diff --git a/drivers/net/ethernet/lantiq/switch-api/Makefile b/drivers/net/ethernet/lantiq/switch-api/Makefile index e70f36cf366a92cdab895fb18437b1fa79afb2a4..475f810f6dc1ac3484cefdc1221213f5e8813834 100644 --- a/drivers/net/ethernet/lantiq/switch-api/Makefile +++ b/drivers/net/ethernet/lantiq/switch-api/Makefile @@ -19,6 +19,7 @@ ifeq ($(CONFIG_SOC_XWAY),y) endif ifeq ($(CONFIG_SOC_GRX500),y) +EXTRA_CFLAGS += -I$(src)/ -I$(src)/mac/ drv_switch_api-objs := gsw_ioctl_wrapper.o drv_switch_api-objs += gsw_init.o #drv_switch_api-objs += gsw_gphy_fw.o @@ -30,6 +31,8 @@ ifeq ($(CONFIG_SOC_GRX500),y) drv_switch_api-objs += gsw_swmcast.o drv_switch_api-objs += gsw_debug.o drv_switch_api-objs += gsw_defconf.o + drv_switch_api-objs += gsw_irq.o + drv_switch_api-objs += gsw_tbl_rw.o endif ifeq ($(CONFIG_X86_INTEL_CE2700),y) diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_debug.c b/drivers/net/ethernet/lantiq/switch-api/gsw_debug.c index 85314ea6ecdb92f36871f7860d0dc6ab2f086931..3f1225f78988cb59be868a602f2a4ce3607a72e2 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_debug.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_debug.c @@ -5,20 +5,263 @@ For licensing information, see the file 'LICENSE' in the root folder of this software module. ******************************************************************************/ -#include "gsw_init.h" -#include "gsw_defconf.h" +#include <gsw_init.h> +#include <gsw_defconf.h> +#include <xgmac_common.h> -GSW_return_t GSW_Debug_GetLpStatistics(void *cdev,GSW_debug_t *parm) + +static GSW_Debug_RMON_Port_cnt_t Rmon_get; +static GSW_CTP_portAssignment_t Assign_get; +static GSW_CTP_portConfig_t CTP_get; +static GSW_BRIDGE_portConfig_t BP_get; +static GSW_BRIDGE_portConfig_t Temp_BP_get; +static GSW_BRIDGE_config_t Brdg_get; +static GSW_QoS_queuePort_t q_map; +static GSW_PMAC_Cnt_t Pmac_Count; + +GSW_return_t GSW_Debug_RMON_Port_Get(void *cdev, GSW_Debug_RMON_Port_cnt_t *parm) { - u32 i=0,j=0,k=0,ret=0; - u32 first_port=0,no_port=0; + u8 RmonCntOffset = 0; + u32 data = 0, data1 = 0; + u32 r_frame = 0, r_unicast = 0, r_multicast = 0, + t_frame = 0, t_unicast = 0, t_multicast = 0; + u32 rgbcl = 0, rbbcl = 0, tgbcl = 0; + u64 rgbch = 0, rbbch = 0, tgbch = 0; + u32 Portmode = 0, PortId = 0; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 count = 0; + bmtbl_prog_t bmtable = {0}; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + Portmode = parm->ePortType; + PortId = parm->nPortId; + /*Clear the structure before using*/ + memset(parm, 0, sizeof(GSW_RMON_Port_cnt_t)); + + switch (Portmode) { + case GSW_RMON_CTP_PORT_RX: + case GSW_RMON_CTP_PORT_TX: + case GSW_RMON_CTP_PORT_PCE_BYPASS: + if (PortId >= gswdev->num_of_ctp) { + pr_err("PortId %d >= gswdev->num_of_ctp %d\n", PortId, gswdev->num_of_ctp); + return GSW_statusErr; + } + + break; + + case GSW_RMON_BRIDGE_PORT_RX: + case GSW_RMON_BRIDGE_PORT_TX: + if (PortId >= gswdev->num_of_bridge_port) { + pr_err("PortId %d >= gswdev->num_of_ctp %d\n", PortId, gswdev->num_of_bridge_port); + return GSW_statusErr; + } + + break; + + default: + pr_err("ePortType Not Supported :ERROR (ePortType=%d)\n", Portmode); + return GSW_statusErr; + } + + /*GSW_ENABLE should be called before calling RMON_GET + In GSW_ENABLE RMON Counter for 0- 15 logical port are enabled*/ + + if (Portmode == GSW_RMON_CTP_PORT_RX || Portmode == GSW_RMON_BRIDGE_PORT_RX) + count = RMON_COUNTER_OFFSET_GSWIP3_1; + else + count = 14; + + //One-time populate. + bmtable.adr.rmon.portOffset = PortId; + bmtable.tableID = (BM_Table_ID)Portmode; + bmtable.b64bitMode = 1; + bmtable.numValues = 4; + + for (RmonCntOffset = 0; RmonCntOffset < count; RmonCntOffset++) { + bmtable.adr.rmon.counterOffset = RmonCntOffset; + gsw_bm_table_read(cdev, &bmtable); + data = (bmtable.value[1] << 16) | (bmtable.value[0] & 0xFFFF); + data1 = (bmtable.value[3] << 16) | (bmtable.value[2] & 0xFFFF); + + /*Only for RX, As per SAS counter offset 0 - 21 is + shared between RX and TX. + Depends upon ePortType selection*/ + if (Portmode == GSW_RMON_CTP_PORT_RX || + Portmode == GSW_RMON_BRIDGE_PORT_RX) { + switch (RmonCntOffset) { + case 0x00: /*RX Size 64 frame count*/ + parm->nRx64BytePkts = data; + parm->nRx127BytePkts = data1; /* Receive Size 65-127 Frame Count */ + break; + + case 0x02: /* Receive Size 128-255 Frame Count */ + parm->nRx255BytePkts = data; + parm->nRx511BytePkts = data1; /* Receive Size 256-511 Frame Count */ + break; + + case 0x04: /* Receive Size 512-1023 Frame Count */ + parm->nRx1023BytePkts = data; + parm->nRxMaxBytePkts = data1; /* Receive Size 1024 - 1518 Frame Count */ + break; + + case 0x06: /* Receive Unicast Frame Count */ + parm->nRxUnicastPkts = r_unicast = data; + parm->nRxMulticastPkts = r_multicast = data1; /* Receive Multicast Frame Count1 */ + break; + + case 0x08: /* Receive Undersize Good Count */ + parm->nRxUnderSizeGoodPkts = data; /* Less than 64 byes. */ + parm->nRxOversizeGoodPkts = data1; /* Receive Oversize (> 1518) Good Count */ + break; + + case 0x0A: /* Receive Good Byte Count (Low) */ + rgbcl = data; + rgbch = data1; /* Receive Good Byte Count (High) */ + break; + + case 0x0C: /* Receive Frme Count */ + parm->nRxBroadcastPkts = r_frame = data; + parm->nRxFilteredPkts = data1; /* Receive Drop (Filter) Frame Count */ + break; + + case 0x0E: /* Receive Extended Vlan Discard Frame Count */ + parm->nRxExtendedVlanDiscardPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxFCSErrorPkts = data1; /* Receive MAC/FCS Error frame Count */ + + break; + + case 0x10: /* Receive Undersize Bad Count */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxUnderSizeErrorPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxOversizeErrorPkts = data1; /* Receive Oversize Bad Count */ + + break; + + case 0x12: /* MTU Exceed Discard Count */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nMtuExceedDiscardPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxDroppedPkts = data1; /* Receive Discard (Tail-Drop) Frame Count */ + + break; + + case 0x14: /* Receive Bad Byte Count (Low) */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + rbbcl = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + rbbch = data1; /* Receive Bad Byte Count (High) */ + + break; + } + } + + /*Only for TX, As per SAS counter offset 0 - 21 is + shared between RX and TX. + Depends upon ePortType selection*/ + if (Portmode == GSW_RMON_CTP_PORT_TX || + Portmode == GSW_RMON_CTP_PORT_PCE_BYPASS || + Portmode == GSW_RMON_BRIDGE_PORT_TX) { + switch (RmonCntOffset) { + case 0x00: /* Transmit Size 64 Frame Count */ + parm->nTx64BytePkts = data; + parm->nTx127BytePkts = data1; /* Transmit Size 65-127 Frame Count */ + break; + + case 0x02: /* Transmit Size 128-255 Frame Count */ + parm->nTx255BytePkts = data; + parm->nTx511BytePkts = data1; /* Transmit Size 256-511 Frame Count */ + break; + + case 0x04: /* Transmit Size 512-1023 Frame Count */ + parm->nTx1023BytePkts = data; + parm->nTxMaxBytePkts = data1; /* Transmit Size 1024 - 1518 Frame Count */ + break; + + case 0x06: /* Transmit Unicast Frame Count */ + parm->nTxUnicastPkts = t_unicast = data; + parm->nTxMulticastPkts = t_multicast = data1; /* Transmit Multicast Frame Count1 */ + break; + + case 0x08: /* Transmit Undersize Good Count */ + parm->nTxUnderSizeGoodPkts = data; /* Less than 64 byes */ + parm->nTxOversizeGoodPkts = data1; /* Transmit Oversize (> 1518) Good Count */ + break; + + case 0x0A: /* Transmit Good Byte Count (Low) */ + tgbcl = data; + tgbch = data1; /* Transmit Good Byte Count (High) */ + break; + + case 0x0C: /* Transmit BroadCast Count */ + parm->nTxBroadcastPkts = t_frame = data; + parm->nTxAcmDroppedPkts = data1; /* Egress Queue Discard,(Active Congestion Management) frame count.*/ + break; + } + } + + RmonCntOffset = RmonCntOffset + 1; + } + + if (Portmode == GSW_RMON_CTP_PORT_RX || + Portmode == GSW_RMON_BRIDGE_PORT_RX) { + /* Receive Good Byte Count */ + parm->nRxGoodBytes = (u64)(((rgbch & 0xFFFFFFFF) << 32) | (rgbcl & 0xFFFFFFFF)); + + if (Portmode == GSW_RMON_CTP_PORT_RX) { + /* Receive Bad Byte Count */ + parm->nRxBadBytes = (u64)(((rbbch & 0xFFFFFFFF) << 32) | (rbbcl & 0xFFFFFFFF)); + } + + parm->nRxGoodPkts = r_frame + r_unicast + r_multicast; + } + + if (Portmode == GSW_RMON_CTP_PORT_TX || + Portmode == GSW_RMON_CTP_PORT_PCE_BYPASS || + Portmode == GSW_RMON_BRIDGE_PORT_TX) { + parm->nTxGoodPkts = t_frame + t_unicast + t_multicast; + /* Transmit Good Byte Count */ + parm->nTxGoodBytes = (u64)(((tgbch & 0xFFFFFFFF) << 32) | (tgbcl & 0xFFFFFFFF)); + } + + parm->ePortType = Portmode; + parm->nPortId = PortId; + + return GSW_statusOk; +} + + +GSW_return_t GSW_Debug_GetLpStatistics(void *cdev, GSW_debug_t *parm) +{ + u32 i = 0, j = 0, k = 0, ret = 0; + u32 first_port = 0, no_port = 0; GSW_CTP_portAssignment_t Assign_get; - GSW_CTP_portConfig_t CTP_get; - GSW_BRIDGE_portConfig_t BP_get; + static GSW_CTP_portConfig_t CTP_get; + static GSW_BRIDGE_portConfig_t BP_get; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } @@ -27,82 +270,82 @@ GSW_return_t GSW_Debug_GetLpStatistics(void *cdev,GSW_debug_t *parm) printk("\t\t\t LOGICAL PORT Statistics\n"); printk("\t\t----------------------------------------\n"); - for(j=0;j < gswdev->tpnum;j++) - { + for (j = 0; j < gswdev->tpnum; j++) { memset(&Assign_get, 0x00, sizeof(Assign_get)); - Assign_get.nLogicalPortId=j; - ret=GSW_CTP_PortAssignmentGet(cdev,&Assign_get); - if(ret==GSW_statusErr) { + Assign_get.nLogicalPortId = j; + ret = GSW_CTP_PortAssignmentGet(cdev, &Assign_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentGet returns ERROR\n"); return GSW_statusErr; } printk("\n"); - printk("\n------ Logical Port %u Configuration ------\n",j); + printk("\n------ Logical Port %u Configuration ------\n", j); printk("\n\t nLogicalPortId = %u", Assign_get.nLogicalPortId); printk("\n\t nFirstCtpPortId = %u", Assign_get.nFirstCtpPortId); printk("\n\t nNumberOfCtpPort = %u", Assign_get.nNumberOfCtpPort); printk("\n\t eMode = %u", Assign_get.eMode); - printk("\n\n\t The Following CTP Ports are associated with Logical port %u :",j); + printk("\n\n\t The Following CTP Ports are associated with Logical port %u :", j); memset(&CTP_get, 0x00, sizeof(CTP_get)); memset(&BP_get, 0x00, sizeof(BP_get)); - first_port=Assign_get.nFirstCtpPortId; - no_port=Assign_get.nNumberOfCtpPort; - - for(i=first_port,k=0;i < (first_port + no_port);i++,k++) - { - CTP_get.nLogicalPortId=j; - CTP_get.nSubIfIdGroup=k; - ret=GSW_CtpPortConfigGet(cdev,&CTP_get); - if(ret==GSW_statusErr) { + first_port = Assign_get.nFirstCtpPortId; + no_port = Assign_get.nNumberOfCtpPort; + + for (i = first_port, k = 0; i < (first_port + no_port); i++, k++) { + CTP_get.nLogicalPortId = j; + CTP_get.nSubIfIdGroup = k; + CTP_get.eMask = 0xffffffff; + + if (!gswdev->ctpportconfig_idx[(first_port + k)].IndexInUse) { + continue; + } + + ret = GSW_CtpPortConfigGet(cdev, &CTP_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CtpPortConfigGet returns ERROR\n"); return GSW_statusErr; } - - BP_get.nBridgePortId=CTP_get.nBridgePortId; - BP_get.eMask=0xffffffff; - ret=GSW_BridgePortConfigGet(cdev,&BP_get); - if(ret==GSW_statusErr) { + + BP_get.nBridgePortId = CTP_get.nBridgePortId; + BP_get.eMask = 0xffffffff; + ret = GSW_BridgePortConfigGet(cdev, &BP_get); + + if (ret == GSW_statusErr) { pr_err("GSW_BridgePortConfigGet returns ERROR\n"); return GSW_statusErr; } - if(i==287) + if (i == 287) printk("\n\t\t %u. CTP Ports %u is Default Port--Dummy port (connected to)--> Bridge port %u (Bridge/Fid = %u)\n", - (k+1),i,CTP_get.nBridgePortId,BP_get.nBridgeId); + (k + 1), i, CTP_get.nBridgePortId, BP_get.nBridgeId); else printk("\n\t\t %u. CTP Ports %u (connected to)--> Bridge port %u (Bridge/Fid = %u)\n", - (k+1),i,CTP_get.nBridgePortId,BP_get.nBridgeId); - + (k + 1), i, CTP_get.nBridgePortId, BP_get.nBridgeId); + } } - + printk("\n\n"); printk("To Get individual CTP port's statistics, Please use following command :\n"); printk("switch_cli GSW_DEBUG_CTP_STATISTICS Index=CTP_PORT_INDEX --> example: 0 to 287\n"); return GSW_statusOk; } -GSW_RMON_Port_cnt_t Rmon_get; -GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) + +GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 i=0,j=0,k=0,match=0,ctpidx=0,lp=0,ret=0; - u32 first_port=0,no_port=0,count=0; - GSW_CTP_portAssignment_t Assign_get; - GSW_CTP_portConfig_t CTP_get; - GSW_BRIDGE_portConfig_t BP_get; - GSW_BRIDGE_portConfig_t Temp_BP_get; - GSW_BRIDGE_config_t Brdg_get; - GSW_QoS_queuePort_t q_map; - GSW_PMAC_Cnt_t Pmac_Count; + u32 i = 0, j = 0, k = 0, f = 0, match = 0, ctpidx = 0, lp = 0, ret = 0; + u32 first_port = 0, no_port = 0, count = 0; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } @@ -115,22 +358,24 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) printk("\n"); - ctpidx=parm->nTableIndex; - lp=gswdev->ctpportconfig_idx[ctpidx].AssociatedLogicalPort; + ctpidx = parm->nTableIndex; + lp = gswdev->ctpportconfig_idx[ctpidx].AssociatedLogicalPort; + + if (!gswdev->ctpportconfig_idx[ctpidx].IndexInUse) { + printk("ERROR :CTP Port %u = NotInUse (CTP port not Allocated) and ", ctpidx); - if(!gswdev->ctpportconfig_idx[ctpidx].IndexInUse) { - printk("ERROR :CTP Port %u = NotInUse (CTP port not Allocated) and ",ctpidx); - if(lp == 0xFF) + if (lp == 0xFF) printk("Associated to Logical port = None\n"); else - printk("Associated to Logical port = %d\n\n",lp); + printk("Associated to Logical port = %d\n\n", lp); + printk("\n"); printk("Please check CTP to Logical port assignment using following command :\n"); printk("switch_cli GSW_DEBUG_LP_STATISTICS\n"); return GSW_statusErr; } else { - if(lp == 0xFF) { - printk("ERROR :CTP Port %d = InUse and ",ctpidx); + if (lp == 0xFF) { + printk("ERROR :CTP Port %d = InUse and ", ctpidx); printk("Associated to Logical port = None\n\n"); printk("\n"); printk("Please check CTP to Logical port assignment using following command :\n"); @@ -138,29 +383,29 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) return GSW_statusErr; } else { memset(&Assign_get, 0x00, sizeof(Assign_get)); - Assign_get.nLogicalPortId=lp; - ret=GSW_CTP_PortAssignmentGet(cdev,&Assign_get); - if(ret==GSW_statusErr) { + Assign_get.nLogicalPortId = lp; + ret = GSW_CTP_PortAssignmentGet(cdev, &Assign_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentGet returns ERROR\n"); return GSW_statusErr; } - first_port=Assign_get.nFirstCtpPortId; - no_port=Assign_get.nNumberOfCtpPort; - CTP_get.nSubIfIdGroup=0; - CTP_get.nLogicalPortId=lp; - CTP_get.eMask=0xFFFFFFFF; + first_port = Assign_get.nFirstCtpPortId; + no_port = Assign_get.nNumberOfCtpPort; + CTP_get.nSubIfIdGroup = 0; + CTP_get.nLogicalPortId = lp; + CTP_get.eMask = 0xFFFFFFFF; - for(i=first_port;((i < (first_port + no_port)) && !match);i++) - { - if((first_port + CTP_get.nSubIfIdGroup) == ctpidx) - match=1; + for (i = first_port; ((i < (first_port + no_port)) && !match); i++) { + if ((first_port + CTP_get.nSubIfIdGroup) == ctpidx) + match = 1; else - CTP_get.nSubIfIdGroup++; + CTP_get.nSubIfIdGroup++; } - if(!match) { - printk("ERROR : CTP index %d is not with in the Logical port %d assigned CTP range\n",ctpidx,lp); + if (!match) { + printk("ERROR : CTP index %d is not with in the Logical port %d assigned CTP range\n", ctpidx, lp); printk("\n\t nLogicalPortId = %u", Assign_get.nLogicalPortId); printk("\n\t nFirstCtpPortId = %u", Assign_get.nFirstCtpPortId); printk("\n\t nNumberOfCtpPort = %u", Assign_get.nNumberOfCtpPort); @@ -170,55 +415,59 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) printk("switch_cli GSW_DEBUG_LP_STATISTICS\n"); return GSW_statusErr; } - - ret=GSW_CtpPortConfigGet(cdev,&CTP_get); - if(ret==GSW_statusErr) { + + ret = GSW_CtpPortConfigGet(cdev, &CTP_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CtpPortConfigGet returns ERROR\n"); return GSW_statusErr; } - BP_get.nBridgePortId=CTP_get.nBridgePortId; - BP_get.eMask=0xffffffff; - - ret=GSW_BridgePortConfigGet(cdev,&BP_get); - if(ret==GSW_statusErr) { + BP_get.nBridgePortId = CTP_get.nBridgePortId; + BP_get.eMask = 0xffffffff; + + ret = GSW_BridgePortConfigGet(cdev, &BP_get); + + if (ret == GSW_statusErr) { pr_err("GSW_BridgePortConfigGet returns ERROR\n"); return GSW_statusErr; } - Brdg_get.nBridgeId=BP_get.nBridgeId; - Brdg_get.eMask=0xffffffff; - ret=GSW_BridgeConfigGet(cdev,&Brdg_get); - if(ret==GSW_statusErr) { + Brdg_get.nBridgeId = BP_get.nBridgeId; + Brdg_get.eMask = 0xffffffff; + + ret = GSW_BridgeConfigGet(cdev, &Brdg_get); + + if (ret == GSW_statusErr) { pr_err("GSW_BridgeConfigGet returns ERROR\n"); return GSW_statusErr; } - + } printk("\n\n"); printk("\t\t----------------------------------------\n"); - printk("\t\t\t CTP PORT %d Statistics\n",ctpidx); + printk("\t\t\t CTP PORT %d Statistics\n", ctpidx); printk("\t\t----------------------------------------\n"); printk("\n\n"); - printk("CTP PORT %u is associated with Logical port %u and Configured with Bridge port %u\n\n",ctpidx,lp,CTP_get.nBridgePortId); - printk("Logical Port %d Configuration :\n",lp); + printk("CTP PORT %u is associated with Logical port %u and Configured with Bridge port %u\n\n", ctpidx, lp, CTP_get.nBridgePortId); + printk("Logical Port %d Configuration :\n", lp); printk("\n\t nLogicalPortId = %u", Assign_get.nLogicalPortId); printk("\n\t nFirstCtpPortId = %u", Assign_get.nFirstCtpPortId); printk("\n\t nNumberOfCtpPort = %u", Assign_get.nNumberOfCtpPort); printk("\n\t eMode = %u", Assign_get.eMode); printk("\n"); - printk("\nCTP PORT %u Configuration (CTP PORT %u Connected to Bridge Port %u) :",ctpidx,ctpidx,CTP_get.nBridgePortId); + printk("\nCTP PORT %u Configuration (CTP PORT %u Connected to Bridge Port %u) :", ctpidx, ctpidx, CTP_get.nBridgePortId); printk("\n\t nLogicalPortId = %u", CTP_get.nLogicalPortId); printk("\n\t nSubIfIdGroup = %u", CTP_get.nSubIfIdGroup); memset(&Rmon_get, 0x00, sizeof(Rmon_get)); - Rmon_get.nPortId=Assign_get.nFirstCtpPortId + CTP_get.nSubIfIdGroup; + Rmon_get.nPortId = Assign_get.nFirstCtpPortId + CTP_get.nSubIfIdGroup; /*bridge port RX rmon*/ - Rmon_get.ePortType=0; - GSW_RMON_Port_Get(cdev, &Rmon_get); - printk("\n\t\t --Ingress CTP Port %u RX RMON Counter :",Rmon_get.nPortId); + Rmon_get.ePortType = 0; + GSW_Debug_RMON_Port_Get(cdev, &Rmon_get); + printk("\n\t\t --Ingress CTP Port %u RX RMON Counter :", Rmon_get.nPortId); printk("\n\t\t\t nRxGoodPkts = %u", Rmon_get.nRxGoodPkts); printk("\n\t\t\t nRxUnicastPkts = %u", Rmon_get.nRxUnicastPkts); printk("\n\t\t\t nRxBroadcastPkts = %u", Rmon_get.nRxBroadcastPkts); @@ -242,27 +491,30 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) printk("\n\t bIngressMeteringEnable = %u", CTP_get.bIngressMeteringEnable); printk("\n\t bEgressMeteringEnable = %u", CTP_get.bEgressMeteringEnable); printk("\n\t bBridgingBypassEnable = %u", CTP_get.bBridgingBypass); - if(CTP_get.bBridgingBypass) { + + if (CTP_get.bBridgingBypass) { printk("\n\tCTP PORT %u Egress Configuration (Bridge ByPass Enabled) :", ctpidx); printk("\n\t nDestLogicalPortId = %u", CTP_get.nDestLogicalPortId); printk("\n\t nDestSubIfIdGroup = %u", CTP_get.nDestSubIfIdGroup); printk("\n\t bPmapperEnable = %u", CTP_get.bPmapperEnable); - if(CTP_get.bPmapperEnable) { + + if (CTP_get.bPmapperEnable) { printk("\n\t ePmapperMappingMode = %u", CTP_get.ePmapperMappingMode); printk("\n\t nPmapperId = %u", BP_get.sPmapper.nPmapperId); } } + printk("\n"); printk("\nBridge PORT %u Configuration (Bridge PORT %u Connected to Bridge/Fid %u) :", - CTP_get.nBridgePortId,CTP_get.nBridgePortId,BP_get.nBridgeId); + CTP_get.nBridgePortId, CTP_get.nBridgePortId, BP_get.nBridgeId); printk("\n\t nBridgePortId = %u", BP_get.nBridgePortId); memset(&Rmon_get, 0x00, sizeof(Rmon_get)); - Rmon_get.nPortId=BP_get.nBridgePortId; + Rmon_get.nPortId = BP_get.nBridgePortId; /*bridge port RX rmon*/ - Rmon_get.ePortType=2; - GSW_RMON_Port_Get(cdev, &Rmon_get); - printk("\n\t\t --Ingress Bridge Port %u RX RMON Counter :",BP_get.nBridgePortId); + Rmon_get.ePortType = 2; + GSW_Debug_RMON_Port_Get(cdev, &Rmon_get); + printk("\n\t\t --Ingress Bridge Port %u RX RMON Counter :", BP_get.nBridgePortId); printk("\n\t\t\t nRxGoodPkts = %u", Rmon_get.nRxGoodPkts); printk("\n\t\t\t nRxUnicastPkts = %u", Rmon_get.nRxUnicastPkts); printk("\n\t\t\t nRxBroadcastPkts = %u", Rmon_get.nRxBroadcastPkts); @@ -288,7 +540,7 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) printk("\n\t bEgressExtendedVlanEnable = %u", BP_get.bEgressExtendedVlanEnable); printk("\n\t bIngressMeteringEnable = %u", BP_get.bIngressMeteringEnable); printk("\n\t bEgressMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[5]); - printk("\n\t bEgressBroadcastSubMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[0] ); + printk("\n\t bEgressBroadcastSubMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[0]); printk("\n\t bEgressMulticastSubMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[1]); printk("\n\t bEgressUnknownMulticastIPSubMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[2]); printk("\n\t bEgressUnknownMulticastNonIPSubMeteringEnable = %u", BP_get.bEgressSubMeteringEnable[3]); @@ -300,90 +552,100 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) printk("\n\t bBypassEgressVlanFilter1Enable = %u", BP_get.bBypassEgressVlanFilter1); printk("\n\t bEgressVlanFilter1Enable = %u", BP_get.bEgressVlanFilter1Enable); printk("\n\t bEgressVlanFilter2Enable = %u", BP_get.bEgressVlanFilter2Enable); - for (j=0;j<8;j++) - printk("\n\t nBridgePortMapIndex[%u] = 0x%x",j,BP_get.nBridgePortMap[j]); + + for (j = 0; j < 8; j++) + printk("\n\t nBridgePortMapIndex[%u] = 0x%x", j, BP_get.nBridgePortMap[j]); + printk("\n"); printk("\nBridge PORT %u's Egress Configuration :", BP_get.nBridgePortId); printk("\n\t nDestLogicalPortId = %u", BP_get.nDestLogicalPortId); printk("\n\t nDestSubIfIdGroup = %u", BP_get.nDestSubIfIdGroup); - if(BP_get.bPmapperEnable) { + + if (BP_get.bPmapperEnable) { printk("\n\t ePmapperMappingMode = %u", BP_get.ePmapperMappingMode); printk("\n\t nPmapperId = %u", BP_get.sPmapper.nPmapperId); } - printk("\n"); - printk("\nBridge PORT %u (Ingress) is Mapped to Following Egress Bridge Ports :",BP_get.nBridgePortId); - count=0; - for(j=0,k=0;j < 8;j++) - { - for(i=0;i < 16;i++,k++) - { - if(BP_get.nBridgePortMap[i] & (1 << i)) { + printk("\n\n"); + printk("\nBridge PORT %u (Ingress) is Mapped to Following Egress Bridge Ports :", BP_get.nBridgePortId); + count = 0; + + for (j = 0, k = 0; j < 8; j++) { + for (i = 0; i < 16; i++, k++) { + if (BP_get.nBridgePortMap[j] & (1 << i)) { memset(&Temp_BP_get, 0x00, sizeof(Temp_BP_get)); - Temp_BP_get.nBridgePortId=k; - Temp_BP_get.eMask=0xffffffff; - ret=GSW_BridgePortConfigGet(cdev,&Temp_BP_get); - if(ret==GSW_statusErr) { + Temp_BP_get.nBridgePortId = k; + Temp_BP_get.eMask = 0xffffffff; + ret = GSW_BridgePortConfigGet(cdev, &Temp_BP_get); + + if (ret == GSW_statusErr) { pr_err("GSW_BridgePortConfigGet(EGBP) returns ERROR\n"); return GSW_statusErr; } + count++; - printk("\n\t Egress BP ---------------------------------------- = %u",k); + printk("\n\t Egress BP ---------------------------------------- = %u", k); memset(&Rmon_get, 0x00, sizeof(Rmon_get)); - Rmon_get.nPortId=k; + Rmon_get.nPortId = k; /*bridge port TX rmon*/ - Rmon_get.ePortType=3; - GSW_RMON_Port_Get(cdev, &Rmon_get); - printk("\n\t\t --Egress Bridge Port %u TX RMON Counter :",k); + Rmon_get.ePortType = 3; + GSW_Debug_RMON_Port_Get(cdev, &Rmon_get); + printk("\n\t\t --Egress Bridge Port %u TX RMON Counter :", k); printk("\n\t\t\t nTxGoodPkts = %u", Rmon_get.nTxGoodPkts); printk("\n\t\t\t nTxUnicastPkt = %u", Rmon_get.nTxUnicastPkts); printk("\n\t\t\t nTxBroadcastPkts = %u", Rmon_get.nTxBroadcastPkts); printk("\n\t\t\t nTxMulticastPkts = %u", Rmon_get.nTxMulticastPkts); printk("\n\t\t\t nTxDroppedPkts = %u", Rmon_get.nTxDroppedPkts); - printk("\n\t\t nDestLogicalPortId = %u", BP_get.nDestLogicalPortId); - printk("\n\t\t nDestSubIfIdGroup = %u", BP_get.nDestSubIfIdGroup); - if(BP_get.bPmapperEnable) { - printk("\n\t\t ePmapperMappingMode = %u", BP_get.ePmapperMappingMode); - printk("\n\t\t nPmapperId = %u", BP_get.sPmapper.nPmapperId); + printk("\n\t\t nDestLogicalPortId = %u", Temp_BP_get.nDestLogicalPortId); + printk("\n\t\t nDestSubIfIdGroup = %u", Temp_BP_get.nDestSubIfIdGroup); + + if (Temp_BP_get.bPmapperEnable) { + printk("\n\t\t ePmapperMappingMode = %u", Temp_BP_get.ePmapperMappingMode); + printk("\n\t\t nPmapperId = %u", Temp_BP_get.sPmapper.nPmapperId); } else { memset(&Assign_get, 0x00, sizeof(Assign_get)); - Assign_get.nLogicalPortId=BP_get.nDestLogicalPortId; - ret=GSW_CTP_PortAssignmentGet(cdev,&Assign_get); - if(ret==GSW_statusErr) { + Assign_get.nLogicalPortId = Temp_BP_get.nDestLogicalPortId; + ret = GSW_CTP_PortAssignmentGet(cdev, &Assign_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentGet (EGBP) returns ERROR\n"); return GSW_statusErr; } - printk("\n\t\t\t --Destination Logical Port %d's Configuration :",BP_get.nDestLogicalPortId); + + printk("\n\t\t\t --Destination Logical Port %d's Configuration :", Temp_BP_get.nDestLogicalPortId); printk("\n\t\t\t\t nLogicalPortId = %u", Assign_get.nLogicalPortId); printk("\n\t\t\t\t nFirstCtpPortId = %u", Assign_get.nFirstCtpPortId); printk("\n\t\t\t\t nNumberOfCtpPort = %u", Assign_get.nNumberOfCtpPort); printk("\n\t\t\t\t eMode = %u", Assign_get.eMode); memset(&Rmon_get, 0x00, sizeof(Rmon_get)); - Rmon_get.nPortId=Assign_get.nFirstCtpPortId + BP_get.nDestSubIfIdGroup; + Rmon_get.nPortId = Assign_get.nFirstCtpPortId + Temp_BP_get.nDestSubIfIdGroup; /*ctp port TX rmon*/ - Rmon_get.ePortType=1; - GSW_RMON_Port_Get(cdev, &Rmon_get); + Rmon_get.ePortType = 1; + GSW_Debug_RMON_Port_Get(cdev, &Rmon_get); printk("\n\n\t\t\t --NOTE : FirstCtp(%u) of (Dst LP %u) + DstSubId(%u) of (EGBP %u)", - Assign_get.nFirstCtpPortId,Assign_get.nLogicalPortId,BP_get.nDestSubIfIdGroup, - k); - printk("\n\t\t\t Egress CTP Port %u TX RMON Counter :",k); + Assign_get.nFirstCtpPortId, Assign_get.nLogicalPortId, Temp_BP_get.nDestSubIfIdGroup, + k); + printk("\n\t\t\t Egress CTP Port %u TX RMON Counter :", k); printk("\n\t\t\t\t nTxGoodPkts = %u", Rmon_get.nTxGoodPkts); printk("\n\t\t\t\t nTxUnicastPkt = %u", Rmon_get.nTxUnicastPkts); printk("\n\t\t\t\t nTxBroadcastPkts = %u", Rmon_get.nTxBroadcastPkts); printk("\n\t\t\t\t nTxMulticastPkts = %u", Rmon_get.nTxMulticastPkts); printk("\n\t\t\t\t nTxDroppedPkts = %u", Rmon_get.nTxDroppedPkts); } + printk("\n"); - printk("\n\t\t nDestLogicalPortId %u's PCE queue mapping Configuration as per Traffic Class :",BP_get.nDestLogicalPortId); + printk("\n\t\t nDestLogicalPortId %u's PCE queue mapping Configuration as per Traffic Class :", Temp_BP_get.nDestLogicalPortId); + /*Traffic Class from 0 to 15*/ - for(i=0;i < 16;i++) { + for (f = 0; f < 16; f++) { memset(&q_map, 0, sizeof(GSW_QoS_queuePort_t)); q_map.nTrafficClassId = i; - q_map.nPortId = BP_get.nDestLogicalPortId; + q_map.nPortId = Temp_BP_get.nDestLogicalPortId; GSW_QoS_QueuePortGet(cdev, &q_map); - printk("\n\t\t\t TC = %u, QId = %u, QMapMode = %u, ExEna = %u, RedirectPortId = %u", - q_map.nTrafficClassId,q_map.nQueueId,q_map.eQMapMode,q_map.bExtrationEnable,q_map.nRedirectPortId); - if(q_map.nRedirectPortId == 0 || q_map.nRedirectPortId == 1) { + printk("\n\t\t\t TC = %u, QId = %u, QMapMode = %u, ExEna = %u, RedirectPortId = %u\n", + q_map.nTrafficClassId, q_map.nQueueId, q_map.eQMapMode, q_map.bExtrationEnable, q_map.nRedirectPortId); + + if (q_map.nRedirectPortId == 0 || q_map.nRedirectPortId == 1) { memset(&Pmac_Count, 0x00, sizeof(Pmac_Count)); Pmac_Count.nPmacId = q_map.nRedirectPortId; Pmac_Count.nTxDmaChanId = lp; @@ -403,7 +665,8 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) } } } - if(!count) + + if (!count) printk("\nIs Mapped to None !!!\n"); } @@ -419,358 +682,387 @@ GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm) return GSW_statusOk; } -GSW_return_t GSW_Debug_CtpTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_CtpTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j,lp=0,bp=0; + u32 j, lp = 0, bp = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_ctp;j++) - { - if(gswdev->ctpportconfig_idx[j].IndexInUse) - { + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_ctp; j++) { + if (gswdev->ctpportconfig_idx[j].IndexInUse) { lp = gswdev->ctpportconfig_idx[j].AssociatedLogicalPort; bp = gswdev->ctpportconfig_idx[j].BrdgPortId; - if(lp == 0xFF) - printk("CTP Port %d = InUse, Associated to Logical port = None and Configured with BrdgPort Id %d.\n",j,bp); + + if (lp == 0xFF) + printk("CTP Port %d = InUse, Associated to Logical port = None and Configured with BrdgPort Id %d.\n", j, bp); else - printk("CTP Port %d = InUse, Associated to Logical port = %d and Configured with BrdgPort Id %d.\n",j,lp,bp); - } + printk("CTP Port %d = InUse, Associated to Logical port = %d and Configured with BrdgPort Id %d.\n", j, lp, bp); + } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->ctpportconfig_idx[parm->nTableIndex].IndexInUse = 1; - printk("\nCTP Port Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("\nCTP Port Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("\nCTP Port Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IndexInUsageCnt); + printk("\nCTP Port Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IndexInUsageCnt); lp = gswdev->ctpportconfig_idx[parm->nTableIndex].AssociatedLogicalPort; - if(lp == 0xFF) + + if (lp == 0xFF) printk("AssociatedLogicalPort = None\n"); else - printk("AssociatedLogicalPort = %d\n",lp); - - printk("BrdgIdPortAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].BrdgIdPortAssigned); - printk("BrdgPortId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].BrdgPortId); - printk("IngressExVlanNonIgmpBlkAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanNonIgmpBlkAssigned); - printk("IngressExVlanIgmpBlkId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanIgmpBlkId); - printk("IngressExVlanIgmpBlkAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanIgmpBlkAssigned); - printk("IngressMeteringAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressMeteringAssigned); - printk("IngressTrafficMeterId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTrafficMeterId); - printk("IngressBridgeBypassPmapperAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressBridgeBypassPmapperAssigned); - printk("IngressBridgeBypassPmappperId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressBridgeBypassPmappperIdx); - printk("EgressExVlanNonIgmpBlkAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanNonIgmpBlkAssigned); - printk("EgressExVlanNonIgmpBlkId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanNonIgmpBlkId); - printk("EgressExVlanIgmpBlkAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanIgmpBlkAssigned); - printk("EgressExVlanIgmpBlkId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanIgmpBlkId); - printk("EgressMeteringAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressMeteringAssigned); - printk("EgressTrafficMeterId = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].EgressTrafficMeterId); - printk("IngressTflowAssigned = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowAssigned); - printk("IngressTflowFirstIdx = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowFirstIdx); - printk("IngressTflowNumberOfEntrys = %d\n",gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowNumberOfEntrys); + printk("AssociatedLogicalPort = %d\n", lp); + + printk("BrdgIdPortAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].BrdgIdPortAssigned); + printk("BrdgPortId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].BrdgPortId); + printk("IngressExVlanNonIgmpBlkAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanNonIgmpBlkAssigned); + printk("IngressExVlanIgmpBlkId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanIgmpBlkId); + printk("IngressExVlanIgmpBlkAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressExVlanIgmpBlkAssigned); + printk("IngressMeteringAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressMeteringAssigned); + printk("IngressTrafficMeterId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTrafficMeterId); + printk("IngressBridgeBypassPmapperAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressBridgeBypassPmapperAssigned); + printk("IngressBridgeBypassPmappperId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressBridgeBypassPmappperIdx); + printk("EgressExVlanNonIgmpBlkAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanNonIgmpBlkAssigned); + printk("EgressExVlanNonIgmpBlkId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanNonIgmpBlkId); + printk("EgressExVlanIgmpBlkAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanIgmpBlkAssigned); + printk("EgressExVlanIgmpBlkId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressExVlanIgmpBlkId); + printk("EgressMeteringAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressMeteringAssigned); + printk("EgressTrafficMeterId = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].EgressTrafficMeterId); + printk("IngressTflowAssigned = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowAssigned); + printk("IngressTflowFirstIdx = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowFirstIdx); + printk("IngressTflowNumberOfEntrys = %d\n", gswdev->ctpportconfig_idx[parm->nTableIndex].IngressTflowNumberOfEntrys); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_BrgPortTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_BrgPortTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j,b=0; + u32 j, b = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_bridge_port;j++){ - if(gswdev->brdgeportconfig_idx[j].IndexInUse) { + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_bridge_port; j++) { + if (gswdev->brdgeportconfig_idx[j].IndexInUse) { b = gswdev->brdgeportconfig_idx[j].BrdgId; - printk("Bridge Port %d = InUse, Configured with Brdg Id/Fid %d.\n",j,b); + printk("Bridge Port %d = InUse, Configured with Brdg Id/Fid %d.\n", j, b); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->brdgeportconfig_idx[parm->nTableIndex].IndexInUse = 1; - printk("\nBridge Port table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("\nBridge Port table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - + printk("\n"); - printk("BridgePort Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IndexInUsageCnt); - printk("BrdgIdAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].BrdgIdAssigned); - printk("BrdgId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].BrdgId); - printk("IngressExVlanBlkAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressExVlanBlkAssigned); - printk("IngressExVlanBlkId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressExVlanBlkId); - printk("EgressExVlanBlkAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressExVlanBlkAssigned); - printk("EgressExVlanBlkId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressExVlanBlkId); - printk("IngressMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressMeteringAssigned); - printk("IngressTrafficMeterId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressTrafficMeterId); - printk("EgressMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressMeteringAssigned); - printk("EgressTrafficMeterId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressTrafficMeterId); - printk("BroadcastMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].BroadcastMeteringAssigned); - printk("BroadcastMeteringId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].BroadcastMeteringId); - printk("MulticastMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].MulticastMeteringAssigned); - printk("MulticastMeteringId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].MulticastMeteringId); - printk("UnknownUniCastMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownUniCastMeteringAssigned); - printk("UnknownUniCastMeteringId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownUniCastMeteringId); - printk("UnknownMultiIpMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringAssigned); - printk("UnknownMultiIpMeteringId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringId); - printk("UnknownMultiNonIpMeteringAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringAssigned); - printk("UnknownMultiNonIpMeteringId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); - printk("PmapperAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].PmapperAssigned); - printk("PmappperIdx = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].PmappperIdx); - printk("IngressVlanFilterAssigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressVlanFilterBlkId); - printk("IngressVlanFilterBlkId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); - printk("EgressVlanFilter1Assigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter1Assigned); - printk("EgressVlanFilter1BlkId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter1BlkId); - printk("EgressVlanFilter2Assigned = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter2Assigned); - printk("EgressVlanFilter2BlkId = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter2BlkId); - printk("StpState = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].StpState); - printk("P8021xState = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].P8021xState); - printk("LearningLimit = %d\n",gswdev->brdgeportconfig_idx[parm->nTableIndex].LearningLimit); + printk("BridgePort Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IndexInUsageCnt); + printk("BrdgIdAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].BrdgIdAssigned); + printk("BrdgId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].BrdgId); + printk("IngressExVlanBlkAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressExVlanBlkAssigned); + printk("IngressExVlanBlkId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressExVlanBlkId); + printk("EgressExVlanBlkAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressExVlanBlkAssigned); + printk("EgressExVlanBlkId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressExVlanBlkId); + printk("IngressMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressMeteringAssigned); + printk("IngressTrafficMeterId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressTrafficMeterId); + printk("EgressMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressMeteringAssigned); + printk("EgressTrafficMeterId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressTrafficMeterId); + printk("BroadcastMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].BroadcastMeteringAssigned); + printk("BroadcastMeteringId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].BroadcastMeteringId); + printk("MulticastMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].MulticastMeteringAssigned); + printk("MulticastMeteringId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].MulticastMeteringId); + printk("UnknownUniCastMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownUniCastMeteringAssigned); + printk("UnknownUniCastMeteringId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownUniCastMeteringId); + printk("UnknownMultiIpMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringAssigned); + printk("UnknownMultiIpMeteringId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringId); + printk("UnknownMultiNonIpMeteringAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringAssigned); + printk("UnknownMultiNonIpMeteringId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); + printk("PmapperAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].PmapperAssigned); + printk("PmappperIdx = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].PmappperIdx); + printk("IngressVlanFilterAssigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].IngressVlanFilterBlkId); + printk("IngressVlanFilterBlkId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); + printk("EgressVlanFilter1Assigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter1Assigned); + printk("EgressVlanFilter1BlkId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter1BlkId); + printk("EgressVlanFilter2Assigned = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter2Assigned); + printk("EgressVlanFilter2BlkId = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].EgressVlanFilter2BlkId); + printk("StpState = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].StpState); + printk("P8021xState = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].P8021xState); + printk("LearningLimit = %d\n", gswdev->brdgeportconfig_idx[parm->nTableIndex].LearningLimit); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_BrgTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_BrgTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 j; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_bridge_port;j++){ - if(gswdev->brdgeconfig_idx[j].IndexInUse) { - printk("Bridge %d = InUse.\n",j); + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_bridge_port; j++) { + if (gswdev->brdgeconfig_idx[j].IndexInUse) { + printk("Bridge %d = InUse.\n", j); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->brdgeconfig_idx[parm->nTableIndex].IndexInUse = 1; - printk("Bridge Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("Bridge Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("Brdg Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].IndexInUsageCnt); - printk("BroadcastMeteringAssigned = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].BroadcastMeteringAssigned); - printk("BroadcastMeteringId = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].BroadcastMeteringId); - printk("MulticastMeteringAssigned = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].MulticastMeteringAssigned); - printk("MulticastMeteringId = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].MulticastMeteringId); - printk("UnknownUniCastMeteringAssigned = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownUniCastMeteringAssigned); - printk("UnknownUniCastMeteringId = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownUniCastMeteringId); - printk("UnknownMultiIpMeteringAssigned = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringAssigned); - printk("UnknownMultiIpMeteringId = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringId); - printk("UnknownMultiNonIpMeteringAssigned = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringAssigned); - printk("UnknownMultiNonIpMeteringId = %d\n",gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); + printk("Brdg Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].IndexInUsageCnt); + printk("BroadcastMeteringAssigned = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].BroadcastMeteringAssigned); + printk("BroadcastMeteringId = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].BroadcastMeteringId); + printk("MulticastMeteringAssigned = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].MulticastMeteringAssigned); + printk("MulticastMeteringId = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].MulticastMeteringId); + printk("UnknownUniCastMeteringAssigned = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownUniCastMeteringAssigned); + printk("UnknownUniCastMeteringId = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownUniCastMeteringId); + printk("UnknownMultiIpMeteringAssigned = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringAssigned); + printk("UnknownMultiIpMeteringId = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiIpMeteringId); + printk("UnknownMultiNonIpMeteringAssigned = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringAssigned); + printk("UnknownMultiNonIpMeteringId = %d\n", gswdev->brdgeconfig_idx[parm->nTableIndex].UnknownMultiNonIpMeteringId); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_ExvlanTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_ExvlanTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j,blockid=0; + u32 j, blockid = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_extendvlan;j++){ - if(gswdev->extendvlan_idx.vlan_idx[j].IndexInUse) { - blockid=gswdev->extendvlan_idx.vlan_idx[j].VlanBlockId; - printk("ExVlan Table Index %d = InUse, Associated to ExVlan Block Id %d.\n",j,blockid); + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_extendvlan; j++) { + if (gswdev->extendvlan_idx.vlan_idx[j].IndexInUse) { + blockid = gswdev->extendvlan_idx.vlan_idx[j].VlanBlockId; + printk("ExVlan Table Index %d = InUse, Associated to ExVlan Block Id %d.\n", j, blockid); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].IndexInUse = 1; gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].VlanBlockId = parm->nblockid; gswdev->extendvlan_idx.nUsedEntry++; - printk("Exvlan Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("Exvlan Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("Exvlan Table Index %d:\n\n",parm->nTableIndex); - printk("BlockId = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].VlanBlockId); - printk("IndexInUse = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].IndexInUsageCnt); - printk("Dscp2PcpPointerAssigned = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].Dscp2PcpPointerAssigned); - printk("Dscp2PcpPointer = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].Dscp2PcpPointer); - printk("MeterAssigned = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].MeterAssigned); - printk("MeterId = %d\n",gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].MeterId); - printk("Number Exvlan table entry used = %d\n",gswdev->extendvlan_idx.nUsedEntry); + printk("Exvlan Table Index %d:\n\n", parm->nTableIndex); + printk("BlockId = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].VlanBlockId); + printk("IndexInUse = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].IndexInUsageCnt); + printk("Dscp2PcpPointerAssigned = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].Dscp2PcpPointerAssigned); + printk("Dscp2PcpPointer = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].Dscp2PcpPointer); + printk("MeterAssigned = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].MeterAssigned); + printk("MeterId = %d\n", gswdev->extendvlan_idx.vlan_idx[parm->nTableIndex].MeterId); + printk("Number Exvlan table entry used = %d\n", gswdev->extendvlan_idx.nUsedEntry); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_VlanFilterTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_VlanFilterTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j,blockid=0; + u32 j, blockid = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_vlanfilter;j++){ - if(gswdev->vlanfilter_idx.filter_idx[j].IndexInUse) { - blockid=gswdev->vlanfilter_idx.filter_idx[j].FilterBlockId; - printk("Vlan Filter Table Index %d = InUse, Associated to Vlan Filetr Block Id %d.\n",j,blockid); + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_vlanfilter; j++) { + if (gswdev->vlanfilter_idx.filter_idx[j].IndexInUse) { + blockid = gswdev->vlanfilter_idx.filter_idx[j].FilterBlockId; + printk("Vlan Filter Table Index %d = InUse, Associated to Vlan Filetr Block Id %d.\n", j, blockid); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].IndexInUse = 1; gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].FilterBlockId = parm->nblockid; gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUntagged = parm->nDiscardUntagged; gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUnMatchedTagged = parm->nDiscardUnMatchedTagged; gswdev->vlanfilter_idx.nUsedEntry++; - printk("Vlan Filter Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("Vlan Filter Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("Vlan Filter Table Index %d:\n\n",parm->nTableIndex); - printk("FilterBlockId = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].FilterBlockId); - printk("IndexInUse = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].IndexInUsageCnt); - printk("DiscardUntagged = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUntagged); - printk("DiscardUnMatchedTagged = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUnMatchedTagged); - printk("FilterMask = %d\n",gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].FilterMask); - printk("Number Vlan Filter table entry used = %d\n",gswdev->vlanfilter_idx.nUsedEntry); + printk("Vlan Filter Table Index %d:\n\n", parm->nTableIndex); + printk("FilterBlockId = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].FilterBlockId); + printk("IndexInUse = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].IndexInUsageCnt); + printk("DiscardUntagged = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUntagged); + printk("DiscardUnMatchedTagged = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].DiscardUnMatchedTagged); + printk("FilterMask = %d\n", gswdev->vlanfilter_idx.filter_idx[parm->nTableIndex].FilterMask); + printk("Number Vlan Filter table entry used = %d\n", gswdev->vlanfilter_idx.nUsedEntry); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_MeterTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_MeterTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 j; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_meters;j++){ - if(gswdev->meter_idx[parm->nTableIndex].IndexInUse) { - printk("Meter Table Index %d = InUse.\n",j); + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_meters; j++) { + if (gswdev->meter_idx[parm->nTableIndex].IndexInUse) { + printk("Meter Table Index %d = InUse.\n", j); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->meter_idx[parm->nTableIndex].IndexInUse = 1; - printk("Meter Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("Meter Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("Meter Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->meter_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->meter_idx[parm->nTableIndex].IndexInUsageCnt); + printk("Meter Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->meter_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->meter_idx[parm->nTableIndex].IndexInUsageCnt); } return GSW_statusOk; } -GSW_return_t GSW_Debug_Dscp2PcpTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_Dscp2PcpTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } printk("\n"); - if(parm->nForceSet) { + + if (parm->nForceSet) { gswdev->dscp2pcp_idx[parm->nTableIndex].IndexInUse = 1; - printk("Dscp2Pcp Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("Dscp2Pcp Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("Dscp2Pcp Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->dscp2pcp_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->dscp2pcp_idx[parm->nTableIndex].IndexInUsageCnt); + printk("Dscp2Pcp Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->dscp2pcp_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->dscp2pcp_idx[parm->nTableIndex].IndexInUsageCnt); } + return GSW_statusOk; } -GSW_return_t GSW_Debug_PmapperTableStatus(void *cdev,GSW_debug_t *parm) +GSW_return_t GSW_Debug_PmapperTableStatus(void *cdev, GSW_debug_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 j; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + printk("\n"); - if(parm->nCheckIndexInUse) - { - for(j=0;j < gswdev->num_of_pmapper;j++){ - if(gswdev->pmapper_idx[j].IndexInUse) { - printk("P-Mapper Table Index %d = InUse.\n",j); + + if (parm->nCheckIndexInUse) { + for (j = 0; j < gswdev->num_of_pmapper; j++) { + if (gswdev->pmapper_idx[j].IndexInUse) { + printk("P-Mapper Table Index %d = InUse.\n", j); } } + return GSW_statusOk; } - if(parm->nForceSet) { + if (parm->nForceSet) { gswdev->pmapper_idx[parm->nTableIndex].IndexInUse = 1; - printk("P-Mapper Table Index %d is Forced to InUSe\n",parm->nTableIndex); + printk("P-Mapper Table Index %d is Forced to InUSe\n", parm->nTableIndex); } else { - printk("P-Mapper Table Index %d:\n\n",parm->nTableIndex); - printk("IndexInUse = %d\n",gswdev->pmapper_idx[parm->nTableIndex].IndexInUse); - printk("IndexInUsageCnt = %d\n",gswdev->pmapper_idx[parm->nTableIndex].IndexInUsageCnt); + printk("P-Mapper Table Index %d:\n\n", parm->nTableIndex); + printk("IndexInUse = %d\n", gswdev->pmapper_idx[parm->nTableIndex].IndexInUse); + printk("IndexInUsageCnt = %d\n", gswdev->pmapper_idx[parm->nTableIndex].IndexInUsageCnt); } + return GSW_statusOk; } GSW_return_t GSW_Debug_PmacBpTable(void *cdev, GSW_debug_t *parm) -{ - pmac_get_bp_cfg(parm->nPmacId); +{ + pmac_get_bp_cfg(cdev, parm->nPmacId); return GSW_statusOk; } GSW_return_t GSW_Debug_PmacEgTable(void *cdev, GSW_debug_t *parm) -{ - pmac_get_eg_cfg(parm->nPmacId, parm->nDestPort); +{ + pmac_get_eg_cfg(cdev, parm->nPmacId, parm->nDestPort); return GSW_statusOk; } GSW_return_t GSW_Debug_PmacIgTable(void *cdev, GSW_debug_t *parm) { - pmac_get_ig_cfg(parm->nPmacId); + pmac_get_ig_cfg(cdev, parm->nPmacId); return GSW_statusOk; } GSW_return_t GSW_Debug_PceBypassTable(void *cdev, GSW_debug_t *parm) { - gsw_get_def_bypass_qmap(); + gsw_get_def_bypass_qmap(cdev); return GSW_statusOk; } GSW_return_t GSW_Debug_PceQTable(void *cdev, GSW_debug_t *parm) { - gsw_get_def_pce_qmap(); + gsw_get_def_pce_qmap(cdev); return GSW_statusOk; } @@ -779,29 +1071,33 @@ GSW_return_t GSW_XgmacCfg(void *cdev, GSW_MAC_cfg_t *mac_cfg) { struct mac_ops *ops = NULL; u8 *argv[10]; - int i=0; + int i = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + pr_err("XGMAC Cfg Supported only in GSWIP3.1 and above\n"); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_1) { - pr_err("XGMAC Cfg Supported only in GSWIP3.1 and above\n"); - return GSW_statusErr; - } ops = gsw_get_mac_ops(0, 0); - if(!ops) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + + if (!ops) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - for(i=0; i<mac_cfg->argc; i++) + for (i = 0; i < mac_cfg->argc; i++) argv[i] = mac_cfg->argv[i]; - + + ops->xgmac_cli(mac_cfg->argc, argv); - + return GSW_statusOk; } @@ -809,29 +1105,32 @@ GSW_return_t GSW_GswssCfg(void *cdev, GSW_MAC_cfg_t *adap_cfg) { struct adap_ops *ops = NULL; u8 *argv[10]; - int i=0; + int i = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + pr_err("GSWSS Cfg Supported only in GSWIP3.1 and above\n"); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_1) { - pr_err("GSWSS Cfg Supported only in GSWIP3.1 and above\n"); - return GSW_statusErr; - } ops = gsw_get_adap_ops(0); - if(!ops) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + + if (!ops) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - - for(i=0; i<adap_cfg->argc; i++) + + for (i = 0; i < adap_cfg->argc; i++) argv[i] = adap_cfg->argv[i]; - + ops->ss_cli(adap_cfg->argc, argv); - + return GSW_statusOk; } @@ -839,30 +1138,68 @@ GSW_return_t GSW_LmacCfg(void *cdev, GSW_MAC_cfg_t *lmac_cfg) { struct mac_ops *ops = NULL; u8 *argv[10]; - int i=0; + int i = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_1) { - pr_err("LMAC Cfg Supported only in GSWIP3.1 and above\n"); - return GSW_statusErr; - } + if (IS_VRSN_NOT_31(gswdev->gipver)) { + pr_err("LMAC Cfg Supported only in GSWIP3.1 and above\n"); + return GSW_statusErr; + } ops = gsw_get_mac_ops(0, 0); - if(!ops) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + + if (!ops) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - - for(i=0; i<lmac_cfg->argc; i++) + + for (i = 0; i < lmac_cfg->argc; i++) argv[i] = lmac_cfg->argv[i]; - + ops->lmac_cli(lmac_cfg->argc, argv); - + return GSW_statusOk; } +GSW_return_t GSW_MacsecCfg(void *cdev, GSW_MAC_cfg_t *macsec_cfg) +{ + + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); +#if 0 + u8 *argv[10]; + int i = 0; + struct macsec_ops *ops = NULL; +#endif + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + pr_err("Macsec Cfg Supported only in GSWIP3.1 and above\n"); + return GSW_statusErr; + } +#if 0 + ops = gsw_get_macsec_ops(0, 0); + + if (!ops) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + for (i = 0; i < macsec_cfg->argc; i++) + argv[i] = macsec_cfg->argv[i]; + + + ops->macsec_cli(macsec_cfg->argc, argv); +#endif + return GSW_statusOk; +} + + diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.c b/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.c index 0292efe5e7a57262b806fca44daabc3fdba8dbdf..7a1467d713a776bd2a50497babb8f286bc80dfef 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.c @@ -7,8 +7,8 @@ * ******************************************************************************/ -#include "gsw_init.h" -#include "gsw_defconf.h" +#include <gsw_init.h> +#include <gsw_defconf.h> #define PMAC0_TX_DMACHID_START 0 #define PMAC0_TX_DMACHID_END 16 @@ -38,7 +38,7 @@ static struct _gsw_pce_path gsw_pce_path[] = { { LOG_10, X, 0, 0, 24, PMAC_0}, { LOG_11, X, 0, 0, 24, PMAC_0}, { LOG_0, X, 0, 0, 24, PMAC_0}, - /* QID 25 */ + /* QID 25 */ { LOG_3, X, 1, 1, 25, PMAC_0}, { LOG_4, X, 1, 1, 25, PMAC_0}, { LOG_5, X, 1, 1, 25, PMAC_0}, @@ -49,7 +49,7 @@ static struct _gsw_pce_path gsw_pce_path[] = { { LOG_10, X, 1, 1, 25, PMAC_0}, { LOG_11, X, 1, 1, 25, PMAC_0}, { LOG_0, X, 1, 1, 25, PMAC_0}, - /* QID 26 */ + /* QID 26 */ { LOG_3, X, 2, 2, 26, PMAC_0}, { LOG_4, X, 2, 2, 26, PMAC_0}, { LOG_5, X, 2, 2, 26, PMAC_0}, @@ -60,7 +60,7 @@ static struct _gsw_pce_path gsw_pce_path[] = { { LOG_10, X, 2, 2, 26, PMAC_0}, { LOG_11, X, 2, 2, 26, PMAC_0}, { LOG_0, X, 2, 2, 26, PMAC_0}, - /* QID 27 */ + /* QID 27 */ { LOG_3, X, 3, 15, 27, PMAC_0}, { LOG_4, X, 3, 15, 27, PMAC_0}, { LOG_5, X, 3, 15, 27, PMAC_0}, @@ -71,21 +71,15 @@ static struct _gsw_pce_path gsw_pce_path[] = { { LOG_10, X, 3, 15, 27, PMAC_0}, { LOG_11, X, 3, 15, 27, PMAC_0}, { LOG_0, X, 3, 15, 27, PMAC_0}, - }; +}; /* Do the GSWIP PCE Q-MAP configuration */ -int gsw_set_def_pce_qmap(void) +int gsw_set_def_pce_qmap(struct core_ops *ops) { int i = 0, j = 0; GSW_QoS_queuePort_t q_map; int num_of_elem = (sizeof(gsw_pce_path) / sizeof(struct _gsw_pce_path)); - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } for (j = 0; j < num_of_elem; j++) { for (i = gsw_pce_path[j].tc_from; @@ -107,13 +101,12 @@ int gsw_set_def_pce_qmap(void) return 0; } -int gsw_get_def_pce_qmap(void) +int gsw_get_def_pce_qmap(struct core_ops *ops) { int i = 0, j = 0; GSW_QoS_queuePort_t q_map; int num_of_elem = (sizeof(gsw_pce_path) / sizeof(struct _gsw_pce_path)); - struct core_ops *ops = gsw_get_swcore_ops(0); if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); @@ -155,18 +148,13 @@ static struct _gsw_bypass_path gsw_bypass_path[] = { }; /* Do the GSWIP Bypass Q-MAP configuration */ -int gsw_set_def_bypass_qmap(GSW_QoS_qMapMode_t q_map_mode) +int gsw_set_def_bypass_qmap(struct core_ops *ops, + GSW_QoS_qMapMode_t q_map_mode) { int j = 0; GSW_QoS_queuePort_t q_map; int num_of_elem = (sizeof(gsw_bypass_path) / sizeof(struct _gsw_bypass_path)); - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } for (j = 0; j < num_of_elem; j++) { memset(&q_map, 0, sizeof(GSW_QoS_queuePort_t)); @@ -187,13 +175,12 @@ int gsw_set_def_bypass_qmap(GSW_QoS_qMapMode_t q_map_mode) return 0; } -int gsw_get_def_bypass_qmap(void) +int gsw_get_def_bypass_qmap(struct core_ops *ops) { int j = 0; GSW_QoS_queuePort_t q_map; int num_of_elem = (sizeof(gsw_bypass_path) / sizeof(struct _gsw_bypass_path)); - struct core_ops *ops = gsw_get_swcore_ops(0); if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); @@ -221,19 +208,12 @@ int gsw_get_def_bypass_qmap(void) } /* Default Qos WRED Config in switch */ -int gsw_qos_def_config(void) +int gsw_qos_def_config(struct core_ops *ops) { GSW_QoS_WRED_PortCfg_t sVar; GSW_QoS_WRED_QueueCfg_t qcfg; int j = 0; - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } - for (j = 0; j < 5; j++) { memset(&sVar, 0x00, sizeof(sVar)); @@ -252,7 +232,7 @@ int gsw_qos_def_config(void) qcfg.nGreen_Max = 256; ops->gsw_qos_ops.QoS_WredQueueCfgSet(ops, &qcfg); - } + } return 0; } @@ -271,19 +251,13 @@ int gsw_qos_def_config(void) * Address: (i from 0 to 15), PCE bypass traffic to MAC3 and MAC4 * Address: (i = 16), Traffic from CPU */ -static int pmac_ig_cfg(u8 pmacid, u8 dpu) +static int pmac_ig_cfg(struct core_ops *ops, u8 pmacid, u8 dpu) { int i = 0; u8 addr_from, addr_to; GSW_PMAC_Ig_Cfg_t ig_cfg; /* Do the GSWIP PMAC IG configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } if (pmacid == 0) { addr_from = PMAC0_TX_DMACHID_START; @@ -349,13 +323,12 @@ static int pmac_ig_cfg(u8 pmacid, u8 dpu) return 0; } -int pmac_get_ig_cfg(u8 pmacid) +int pmac_get_ig_cfg(struct core_ops *ops, u8 pmacid) { int i = 0; GSW_PMAC_Ig_Cfg_t ig_cfg; /* Do the GSWIP PMAC IG configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); @@ -392,19 +365,13 @@ int pmac_get_ig_cfg(u8 pmacid) /* Pmac Egress table has 1024 entries, * i * j * k * 16 channels */ -static int pmac_eg_cfg(u8 pmacid, u8 dpu) +static int pmac_eg_cfg(struct core_ops *ops, u8 pmacid, u8 dpu) { GSW_PMAC_Eg_Cfg_t eg_cfg; int i = 0, j = 0, k = 0, m = 0; u8 dst_start, dst_end; /* Do the GSWIP PMAC configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } if (pmacid == 0) { dst_start = PMAC0_DST_PRT_START; @@ -425,7 +392,7 @@ static int pmac_eg_cfg(u8 pmacid, u8 dpu) for (j = 0; j <= 3; j++) { memset((void *)&eg_cfg, 0x00, sizeof(eg_cfg)); - + /* Select Pmac ID */ eg_cfg.nPmacId = pmacid; /* Egress ch for Pmac0/1 is always 0 */ @@ -489,13 +456,12 @@ static int pmac_eg_cfg(u8 pmacid, u8 dpu) return 0; } -int pmac_get_eg_cfg(u8 pmacid, u8 dst_port) +int pmac_get_eg_cfg(struct core_ops *ops, u8 pmacid, u8 dst_port) { - int i = 0, k = 0, j=0; + int i = 0, k = 0, j = 0; GSW_PMAC_Eg_Cfg_t eg_cfg; /* Do the GSWIP PMAC IG configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); @@ -504,17 +470,18 @@ int pmac_get_eg_cfg(u8 pmacid, u8 dst_port) printk("\nGSWIP PMAC EG CFG\n"); - printk("\n\nDestination portId = %d\n\n",dst_port); + printk("\n\nDestination portId = %d\n\n", dst_port); printk("%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n", "PmacId", "RxDmaChId", "BslTrafCls", "BslSegDis", "PmacEna", "RedirEna", "DestPortId", "TrafCls", "Mpe1", - "Mpe2", "FlowId"); + "Mpe2", "FlowId"); + for (k = 0; k <= 3; k++) { for (i = 0; i <= 3; i++) { for (j = 0; j <= 3; j++) { - memset((void *)&eg_cfg, 0x00, - sizeof(eg_cfg)); + memset((void *)&eg_cfg, 0x00, + sizeof(eg_cfg)); eg_cfg.nPmacId = pmacid; eg_cfg.nDestPortId = dst_port; @@ -523,20 +490,20 @@ int pmac_get_eg_cfg(u8 pmacid, u8 dst_port) eg_cfg.nTrafficClass = i; eg_cfg.bMpe2Flag = ((j & 3) >> 1); eg_cfg.bMpe1Flag = (j & 1); - eg_cfg.nFlowIDMsb = k; - - ops->gsw_pmac_ops.Pmac_Eg_CfgGet(ops, - &eg_cfg); + eg_cfg.nFlowIDMsb = k; + + ops->gsw_pmac_ops.Pmac_Eg_CfgGet(ops, + &eg_cfg); printk("%10d %10d %10d %10d %10d %10d %10d %10d %10d %10d %10d", - eg_cfg.nPmacId, + eg_cfg.nPmacId, eg_cfg.nRxDmaChanId, - eg_cfg.nBslTrafficClass, + eg_cfg.nBslTrafficClass, eg_cfg.bBslSegmentDisable, - eg_cfg.bPmacEna, + eg_cfg.bPmacEna, eg_cfg.bRedirEnable, - eg_cfg.nDestPortId, + eg_cfg.nDestPortId, eg_cfg.nTrafficClass, - eg_cfg.bMpe1Flag, + eg_cfg.bMpe1Flag, eg_cfg.bMpe2Flag, eg_cfg.nFlowIDMsb); printk("\n"); @@ -547,17 +514,11 @@ int pmac_get_eg_cfg(u8 pmacid, u8 dst_port) return 0; } -static int pmac_glbl_cfg(u8 pmacid) { - +static int pmac_glbl_cfg(struct core_ops *ops, u8 pmacid) +{ GSW_PMAC_Glbl_Cfg_t glbl_cfg; /* Do the GSWIP PMAC configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } memset((void *)&glbl_cfg, 0x00, sizeof(glbl_cfg)); @@ -568,12 +529,12 @@ static int pmac_glbl_cfg(u8 pmacid) { glbl_cfg.bRxFCSDis = 1; glbl_cfg.eShortFrmChkType = GSW_PMAC_SHORT_LEN_ENA_UNTAG; glbl_cfg.bLongFrmChkDis = 1; - glbl_cfg.bProcFlagsEgCfgEna=1; + glbl_cfg.bProcFlagsEgCfgEna = 1; glbl_cfg.eProcFlagsEgCfg = GSW_PMAC_PROC_FLAGS_FLAG; ops->gsw_pmac_ops.Pmac_Gbl_CfgSet(ops, &glbl_cfg); - pr_info("PMAC_GLBL_CFG_SET for PMAC %d\n", pmacid); + pr_info("PMAC_GLBL_CFG_SET for PMAC %d\n", pmacid); return 0; } @@ -585,7 +546,7 @@ static int pmac_glbl_cfg(u8 pmacid) { * (Configurable upto 16 ports) */ GSW_PMAC_BM_Cfg_t bm_cfg_nondpu[] = { -/* PmacId TxDmaChId TxQMask RxPortMask */ + /* PmacId TxDmaChId TxQMask RxPortMask */ {0, 0, 1, 0},/* PCE Bypass traf to MAC3+MAC4 */ {0, 1, 0, 0}, {0, 2, 0, 0}, @@ -607,7 +568,7 @@ GSW_PMAC_BM_Cfg_t bm_cfg_nondpu[] = { }; GSW_PMAC_BM_Cfg_t bm_cfg_dpu[] = { -/* PmacId TxDmaChId TxQMask RxPortMask */ + /* PmacId TxDmaChId TxQMask RxPortMask */ {0, 0, 1, 0}, {0, 1, 2, 0}, {0, 2, 4, 0}, @@ -629,19 +590,13 @@ GSW_PMAC_BM_Cfg_t bm_cfg_dpu[] = { {1, 0, 0x10000, 0}, }; -static int pmac_bp_cfg(u8 dpu) +static int pmac_bp_cfg(struct core_ops *ops, u8 dpu) { GSW_PMAC_BM_Cfg_t bm_cfg; int m = 0; int num_of_elem; /* Do the GSWIP PMAC BM table configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); - - if (!ops) { - pr_err("%s: Open SWAPI device FAILED!\n", __func__); - return -EIO; - } if (dpu == NON_DPU) { num_of_elem = @@ -672,19 +627,17 @@ static int pmac_bp_cfg(u8 dpu) return 0; } -int pmac_get_bp_cfg(u8 pmacid) +int pmac_get_bp_cfg(struct core_ops *ops, u8 pmacid) { GSW_PMAC_BM_Cfg_t bm_cfg; int m = 0; - /* Do the GSWIP PMAC BM table configuration */ - struct core_ops *ops = gsw_get_swcore_ops(0); - if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); return -EIO; } + /* Do the GSWIP PMAC BM table configuration */ printk("\nGSWIP PMAC BP CFG\n"); printk("%10s %10s %10s %10s\n", "PmacId", "TxDmaChId", "TxQMask", "RxPortMask"); @@ -705,31 +658,45 @@ int pmac_get_bp_cfg(u8 pmacid) return 0; } -void gsw_pmac_init_nondpu(void) +int gsw_pmac_init_nondpu(void) { - pmac_glbl_cfg(0); - pmac_glbl_cfg(1); - pmac_ig_cfg(0, NON_DPU); - pmac_ig_cfg(1, NON_DPU); - pmac_eg_cfg(0, NON_DPU); - pmac_eg_cfg(1, NON_DPU); - pmac_bp_cfg(NON_DPU); + struct core_ops *ops = gsw_get_swcore_ops(0); + + if (!ops) { + pr_err("%s: Open SWAPI device FAILED!\n", __func__); + return -EIO; + } + + pmac_glbl_cfg(ops, 0); + pmac_glbl_cfg(ops, 1); + pmac_ig_cfg(ops, 0, NON_DPU); + pmac_ig_cfg(ops, 1, NON_DPU); + pmac_eg_cfg(ops, 0, NON_DPU); + pmac_eg_cfg(ops, 1, NON_DPU); + pmac_bp_cfg(ops, NON_DPU); pr_info("\n\t GSW PMAC Init Done!!!\n"); - return; + return 0; } -void gsw_pmac_init_dpu(void) +int gsw_pmac_init_dpu(void) { - pmac_glbl_cfg(0); - pmac_glbl_cfg(1); - pmac_ig_cfg(0, DPU); - pmac_ig_cfg(1, NON_DPU); - pmac_eg_cfg(0, DPU); - pmac_eg_cfg(1, NON_DPU); - pmac_bp_cfg(DPU); + struct core_ops *ops = gsw_get_swcore_ops(0); + + if (!ops) { + pr_err("%s: Open SWAPI device FAILED!\n", __func__); + return -EIO; + } + + pmac_glbl_cfg(ops, 0); + pmac_glbl_cfg(ops, 1); + pmac_ig_cfg(ops, 0, DPU); + pmac_ig_cfg(ops, 1, NON_DPU); + pmac_eg_cfg(ops, 0, DPU); + pmac_eg_cfg(ops, 1, NON_DPU); + pmac_bp_cfg(ops, DPU); pr_info("\n\t GSW PMAC Init Done!!!\n"); - return; + return 0; } diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.h b/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.h index 407a8f55401a2e92ebc9f71b42e5dcbe2b6af7b5..894d6b4da335311841944af4c46edcf48bad960e 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_defconf.h @@ -28,15 +28,15 @@ enum _logical_pid { }; enum _dpu { - DPU=0, - NON_DPU=1, + DPU = 0, + NON_DPU = 1, }; struct _gsw_pce_path { u32 eg_lpid; /* Egress Logical PID after Bridge */ int ext; /* Extraction */ u32 tc_from; /* Traffic Class From */ - u32 tc_to; /* Traffic Class to */ + u32 tc_to; /* Traffic Class to */ u32 qid; /* Egress QID From */ u32 redir_lpid; /* Redirect Logical PID */ }; @@ -49,17 +49,17 @@ struct _gsw_bypass_path { u32 redir_pid; /* Redirect Logical PID */ }; -int gsw_set_def_pce_qmap(void); -int gsw_get_def_pce_qmap(void); -int gsw_set_def_bypass_qmap(GSW_QoS_qMapMode_t q_map_mode); -int gsw_get_def_bypass_qmap(void); -int gsw_qos_def_config(void); +int gsw_set_def_pce_qmap(struct core_ops *ops); +int gsw_get_def_pce_qmap(struct core_ops *ops); +int gsw_set_def_bypass_qmap(struct core_ops *ops, GSW_QoS_qMapMode_t q_map_mode); +int gsw_get_def_bypass_qmap(struct core_ops *ops); +int gsw_qos_def_config(struct core_ops *ops); -void gsw_pmac_init_nondpu(void); -void gsw_pmac_init_dpu(void); -int pmac_get_ig_cfg(u8 pmacid); -int pmac_get_bp_cfg(u8 pmacid); -int pmac_get_eg_cfg(u8 pmacid, u8 dst_port); +int gsw_pmac_init_nondpu(void); +int gsw_pmac_init_dpu(void); +int pmac_get_ig_cfg(struct core_ops *ops, u8 pmacid); +int pmac_get_bp_cfg(struct core_ops *ops, u8 pmacid); +int pmac_get_eg_cfg(struct core_ops *ops, u8 pmacid, u8 dst_port); #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.c b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.c index aa5f895719c52eb7fc2e3d50a94424ba6029d44b..270954aaa4094a733e9a95c12818820f8581a851 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.c @@ -1,15 +1,15 @@ - /****************************************************************************** - Copyright (c) 2016, 2017 Intel Corporation - - ******************************************************************************/ - /***************************************************************************** - Copyright (c) 2012, 2014, 2015 - Lantiq Deutschland GmbH - For licensing information, see the file 'LICENSE' in the root folder of - this software module. - ******************************************************************************/ - -#if defined(KERNEL_MODE) && KERNEL_MODE +/****************************************************************************** + Copyright (c) 2016, 2017 Intel Corporation + +******************************************************************************/ +/***************************************************************************** + Copyright (c) 2012, 2014, 2015 + Lantiq Deutschland GmbH + For licensing information, see the file 'LICENSE' in the root folder of + this software module. +******************************************************************************/ + +#ifdef __KERNEL__ //#include <linux/sched.h> #include <linux/jiffies.h> #include <linux/timer.h> @@ -19,12 +19,15 @@ #endif #endif +#include <gsw_init.h> +#include <gsw_swmcast.h> +#include <gsw_defconf.h> -#include "gsw_init.h" -#include "gsw_swmcast.h" -#include "gsw_defconf.h" #if defined(CONFIG_MAC) && CONFIG_MAC -#include <gswss_cfg.h> +#include <gswss_api.h> +#endif +#if defined(WIN_PC_MODE) && WIN_PC_MODE +#include <eip160_common.h> #endif //#define CONFIG_USE_EMULATOR 1 @@ -72,58 +75,90 @@ static const u32 gsw_pce_tbl_reg_value[] = { PCE_TBL_VAL_24_VAL24_OFFSET, PCE_TBL_VAL_25_VAL25_OFFSET }; static const gsw_pce_tbl_info_t gsw_pce_tbl_info_22[] = { - {0,0,4}, {1,1,1}, {0,0,3}, {1,0,0}, {1,1,0}, {1,1,0}, {4,1,0}, {4,1,0}, - {1,1,0}, {0,0,1}, {0,0,1}, {4,0,2}, {3,1,0}, {2,0,1}, {2,0,5}, {9,0,7}, - {0,0,1}, {0,0,1}, {1,1,1}, {1,1,1}, {4,1,0}, {4,1,0}, {3,1,0}, {3,1,0}, - {0,0,0}, {0,0,4}, {0,0,1}, {0,0,1}, {0,0,2} + {0, 0, 4}, {1, 1, 1}, {0, 0, 3}, {1, 0, 0}, {1, 1, 0}, {1, 1, 0}, {4, 1, 0}, {4, 1, 0}, + {1, 1, 0}, {0, 0, 1}, {0, 0, 1}, {4, 0, 2}, {3, 1, 0}, {2, 0, 1}, {2, 0, 5}, {9, 0, 7}, + {0, 0, 1}, {0, 0, 1}, {1, 1, 1}, {1, 1, 1}, {4, 1, 0}, {4, 1, 0}, {3, 1, 0}, {3, 1, 0}, + {0, 0, 0}, {0, 0, 4}, {0, 0, 1}, {0, 0, 1}, {0, 0, 2} }; static const gsw_pce_tbl_info_t gsw_pce_tbl_info_30[] = { - {0,0,4}, {1,1,0}, {0,0,3}, {1,0,0}, {1,1,0}, {1,1,0}, {4,4,0}, {4,4,0}, - {1,1,0}, {0,0,1}, {0,0,1}, {4,0,2}, {0,0,0}, {3,0,2}, {2,0,5}, {16,0,10}, - {0,0,0}, {0,0,1}, {1,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {3,1,0}, {3,1,0}, - {4,1,0}, {0,0,0}, {0,0,1}, {0,0,1}, {0,0,2}, {1,1,0}, {0,0,2} + {0, 0, 4}, {1, 1, 0}, {0, 0, 3}, {1, 0, 0}, {1, 1, 0}, {1, 1, 0}, {4, 4, 0}, {4, 4, 0}, + {1, 1, 0}, {0, 0, 1}, {0, 0, 1}, {4, 0, 2}, {0, 0, 0}, {3, 0, 2}, {2, 0, 5}, {16, 0, 10}, + {0, 0, 0}, {0, 0, 1}, {1, 1, 1}, {1, 1, 1}, {0, 0, 0}, {0, 0, 0}, {3, 1, 0}, {3, 1, 0}, + {1, 1, 0}, {0, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 0, 2}, {1, 1, 0}, {0, 0, 2} }; static const gsw_pce_tbl_info_t gsw_pce_tbl_info_31[] = { - {0,0,4}, {0,0,0}, {1,0,1}, {1,0,0}, {1,1,0}, {1,1,0}, {4,4,0}, {4,4,0}, - {1,1,0}, {0,0,1}, {0,0,1}, {4,0,10}, {0,0,2}, {19,0,10}, {2,0,5}, {22,0,18}, - {0,0,0}, {0,0,1}, {0,0,9}, {0,0,7}, {0,0,18}, {0,0,14}, {3,1,0}, {3,1,0}, - {1,1,0}, {0,0,10}, {0,0,1}, {0,0,1}, {0,0,1}, {1,1,0}, {4,0,6}, {0,0,1} + {0, 0, 4}, {0, 0, 0}, {1, 0, 1}, {1, 0, 0}, {1, 1, 0}, {1, 1, 0}, {4, 4, 0}, {4, 4, 0}, + {1, 1, 0}, {0, 0, 1}, {0, 0, 1}, {4, 0, 10}, {0, 0, 2}, {19, 0, 10}, {2, 0, 5}, {22, 0, 18}, + {0, 0, 0}, {0, 0, 1}, {0, 0, 9}, {0, 0, 7}, {0, 0, 18}, {0, 0, 14}, {3, 1, 0}, {3, 1, 0}, + {1, 1, 0}, {0, 0, 10}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {1, 1, 0}, {4, 0, 6}, {0, 0, 1} }; /* Local Macros & Definitions */ static pstpstate_t pstpstate[] = { - { GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_AUTHORIZED, - 1, PORT_STATE_FORWARDING, 1 }, - { GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_UNAUTHORIZED, - 1, PORT_STATE_LISTENING, 0 }, /* Govind - set 'lrnlim' to 0. Double check for legacy code. */ - { GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_RX_AUTHORIZED, - 1, PS_RENABLE_TDISABLE, 1 }, - { GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_TX_AUTHORIZED, - 1, PS_RDISABLE_TENABLE, 0 }, /* Govind - set 'lrnlim' to 0. Double check for legacy code. */ - { GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_AUTHORIZED, - 0, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_UNAUTHORIZED, - 0, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_RX_AUTHORIZED, - 0, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_TX_AUTHORIZED, - 0, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_AUTHORIZED, - 1, PORT_STATE_LEARNING, 1 }, - { GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_UNAUTHORIZED, - 1, PORT_STATE_LEARNING, 1 }, - { GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_RX_AUTHORIZED, - 1, PORT_STATE_LEARNING, 1 }, - { GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_TX_AUTHORIZED, - 1, PORT_STATE_LEARNING, 1 }, - { GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_AUTHORIZED, - 1, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_UNAUTHORIZED, - 1, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_RX_AUTHORIZED, - 1, PORT_STATE_LISTENING, 0 }, - { GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_TX_AUTHORIZED, - 1, PORT_STATE_LISTENING, 0 } + { + GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_AUTHORIZED, + 1, PORT_STATE_FORWARDING, 1 + }, + { + GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_UNAUTHORIZED, + 1, PORT_STATE_LISTENING, 0 + }, /* Govind - set 'lrnlim' to 0. Double check for legacy code. */ + { + GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_RX_AUTHORIZED, + 1, PS_RENABLE_TDISABLE, 1 + }, + { + GSW_STP_PORT_STATE_FORWARD, GSW_8021X_PORT_STATE_TX_AUTHORIZED, + 1, PS_RDISABLE_TENABLE, 0 + }, /* Govind - set 'lrnlim' to 0. Double check for legacy code. */ + { + GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_AUTHORIZED, + 0, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_UNAUTHORIZED, + 0, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_RX_AUTHORIZED, + 0, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_DISABLE, GSW_8021X_PORT_STATE_TX_AUTHORIZED, + 0, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_AUTHORIZED, + 1, PORT_STATE_LEARNING, 1 + }, + { + GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_UNAUTHORIZED, + 1, PORT_STATE_LEARNING, 1 + }, + { + GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_RX_AUTHORIZED, + 1, PORT_STATE_LEARNING, 1 + }, + { + GSW_STP_PORT_STATE_LEARNING, GSW_8021X_PORT_STATE_TX_AUTHORIZED, + 1, PORT_STATE_LEARNING, 1 + }, + { + GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_AUTHORIZED, + 1, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_UNAUTHORIZED, + 1, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_RX_AUTHORIZED, + 1, PORT_STATE_LISTENING, 0 + }, + { + GSW_STP_PORT_STATE_BLOCKING, GSW_8021X_PORT_STATE_TX_AUTHORIZED, + 1, PORT_STATE_LISTENING, 0 + } }; static gsw_capdesc_t capdes[] = { @@ -170,41 +205,56 @@ static gsw_capdesc_t capdes[] = { struct mac_ops *get_mac_ops(ethsw_api_dev_t *gswdev, int idx) { +#ifdef __KERNEL__ u32 dev_id = (((struct platform_device *)(gswdev->pdev))->dev.parent->id); - if (idx < 2 || idx > 4) { +#else + u32 dev_id = 0; +#endif + u32 max_mac = gsw_get_mac_subifcnt(dev_id); + + if (idx < 2 || idx > max_mac + 1) { printk("Invalid MAC Idx %d, Only MAC idx 2/3/4 is Allowed\n", idx); return NULL; } /* For mac Idx is from 0, 1, 2 */ idx -= 2; - + return gsw_get_mac_ops(dev_id, idx); } struct adap_ops *get_adap_ops(ethsw_api_dev_t *gswdev) { +#ifdef __KERNEL__ u32 dev_id = (((struct platform_device *)(gswdev->pdev))->dev.parent->id); +#else + u32 dev_id = 0; +#endif return gsw_get_adap_ops(dev_id); } static int calc_credit_value(u32 *rxcnt, u8 *mv, u8 *locv) { - u8 s,c,i, m, loc = 0, crd[MAX_READ] = {0}; - for ( s = 0; s < MAX_READ - 1; s++) { - for ( c = s + 1; c < MAX_READ; c++) { - if ((rxcnt[s] <= rxcnt[c]) && (rxcnt[c] <= (rxcnt[s] + (c-s) * GAP_MAX))) { - crd[s]++; crd[c]++; + u8 s, c, i, m, loc = 0, crd[MAX_READ] = {0}; + + for (s = 0; s < MAX_READ - 1; s++) { + for (c = s + 1; c < MAX_READ; c++) { + if ((rxcnt[s] <= rxcnt[c]) && (rxcnt[c] <= (rxcnt[s] + (c - s) * GAP_MAX))) { + crd[s]++; + crd[c]++; } } } + m = crd[0]; - for ( i = 1; i < MAX_READ; i++) { + + for (i = 1; i < MAX_READ; i++) { if (crd[i] > m) { m = crd[i]; loc = i; } } + *mv = m; *locv = loc; return 0; @@ -212,21 +262,26 @@ static int calc_credit_value(u32 *rxcnt, u8 *mv, u8 *locv) static int calc_credit_byte_value(u32 *rxcnt, u8 *mv, u8 *locv) { - u8 s,c,i, m, loc = 0, crd[MAX_READ] = {0}; - for ( s = 0; s < MAX_READ - 1; s++) { - for ( c = s + 1; c < MAX_READ; c++) { - if ((rxcnt[s] <= rxcnt[c]) && (rxcnt[c] <= (rxcnt[s] + (c-s) * GAP_MAX1))) { - crd[s]++; crd[c]++; + u8 s, c, i, m, loc = 0, crd[MAX_READ] = {0}; + + for (s = 0; s < MAX_READ - 1; s++) { + for (c = s + 1; c < MAX_READ; c++) { + if ((rxcnt[s] <= rxcnt[c]) && (rxcnt[c] <= (rxcnt[s] + (c - s) * GAP_MAX1))) { + crd[s]++; + crd[c]++; } } } + m = crd[0]; - for ( i = 1; i < MAX_READ; i++) { + + for (i = 1; i < MAX_READ; i++) { if (crd[i] > m) { m = crd[i]; loc = i; } } + *mv = m; *locv = loc; return 0; @@ -268,11 +323,13 @@ static void ltq_ethsw_port_cfg_init(void *cdev) ETHSW_CAP_1_PPORTS_SHIFT, ETHSW_CAP_1_PPORTS_SIZE, &value); gswdev->pnum = value; + for (i = 0; i < gswdev->pnum; i++) { memset(&gswdev->pconfig[i], 0, sizeof(port_config_t)); gswdev->pconfig[i].llimit = 0xFF; gswdev->pconfig[i].penable = 1; } + gswdev->stpconfig.sfport = GSW_PORT_FORWARD_DEFAULT; gswdev->stpconfig.fpid8021x = gswdev->cport; gsw_r32(cdev, ETHSW_CAP_1_VPORTS_OFFSET, ETHSW_CAP_1_VPORTS_SHIFT, @@ -285,12 +342,13 @@ static void reset_multicast_sw_table(void *cdev) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 i; - if(gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { gsw_init_hash_table(cdev); } memset(&gswdev->iflag, 0, sizeof(gsw_igmp_t)); gswdev->iflag.itblsize = gswdev->mctblsize; + for (i = 0; i < gswdev->iflag.itblsize; i++) { gswdev->iflag.mctable[i].slsbindex = 0x7F; gswdev->iflag.mctable[i].dlsbindex = 0x7F; @@ -313,202 +371,250 @@ static int gsw2x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) pctbl_prog_t ptdata; pce_dasa_lsb_t ltbl; pce_dasa_msb_t mtbl; + memset(&ptdata, 0, sizeof(pctbl_prog_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (gswdev->iflag.igv3 != 1) { pr_err("%s:%s:%d(bIGMPv3 need to be enable)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + if ((parm->eIPVersion != GSW_IP_SELECT_IPV4) - && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { + && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { pr_err("%s:%s:%d (IPv4/IPV6 need to enable)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { for (i = 0; i < 4; i++) ltbl.ilsb[i] = - ((parm->uIP_Gda.nIPv4 >> (i * 8)) & 0xFF); + ((parm->uIP_Gda.nIPv4 >> (i * 8)) & 0xFF); + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } else { ltbl.mask[0] = 0xFF00; } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gda.nIPv6[i] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; } else { mtbl.mask[0] = 0; } + dmix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, &mtbl); + if (dmix == 0xFF) { dmix = pce_dasa_msb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, &mtbl); + &hpctbl->pce_sub_tbl, &mtbl); dmflag = 1; } + if (dmix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gda.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gda.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i + 4] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } else { ltbl.mask[0] = 0;/* DIP LSB Nibble Mask */ } } + dlix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, <bl); + if (dlix == 0xFF) { dlix = pce_dasa_lsb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, <bl); + &hpctbl->pce_sub_tbl, <bl); dlflag = 1; } + if (dlix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { for (i = 0; i < 4; i++) ltbl.ilsb[i] = - ((parm->uIP_Gsa.nIPv4 >> (i * 8)) & 0xFF); + ((parm->uIP_Gsa.nIPv4 >> (i * 8)) & 0xFF); + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } else { /* DIP LSB Nibble Mask */ ltbl.mask[0] = 0xFF00; } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[3] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[0] == 0)) { - pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[0] == 0)) { + pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; } } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { int src_zero = 0; - /*First, search for DIP in the DA/SA table (DIP MSB)*/ + + /*First, search for DIP in the DA/SA table (DIP MSB)*/ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = - (parm->uIP_Gsa.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = + (parm->uIP_Gsa.nIPv6[i] & 0xFF); mtbl.imsb[j] = - ((parm->uIP_Gsa.nIPv6[i] >> 8) & 0xFF); + ((parm->uIP_Gsa.nIPv6[i] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; } else { mtbl.mask[0] = 0;/* DIP MSB Nibble Mask */ } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((mtbl.imsb[0] == 0) && - (mtbl.imsb[1] == 0) && - (mtbl.imsb[2] == 0) && - (mtbl.imsb[3] == 0) && - (mtbl.imsb[4] == 0) && - (mtbl.imsb[5] == 0) && - (mtbl.imsb[6] == 0) && - (mtbl.imsb[7] == 0)) { - src_zero = 1; + (mtbl.imsb[1] == 0) && + (mtbl.imsb[2] == 0) && + (mtbl.imsb[3] == 0) && + (mtbl.imsb[4] == 0) && + (mtbl.imsb[5] == 0) && + (mtbl.imsb[6] == 0) && + (mtbl.imsb[7] == 0)) { + src_zero = 1; } } + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = - (parm->uIP_Gsa.nIPv6[i+4] & 0xFF); + ltbl.ilsb[j - 1] = + (parm->uIP_Gsa.nIPv6[i + 4] & 0xFF); ltbl.ilsb[j] = - ((parm->uIP_Gsa.nIPv6[i+4] >> 8) & 0xFF); + ((parm->uIP_Gsa.nIPv6[i + 4] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } else { ltbl.mask[0] = 0;/* DIP LSB Nibble Mask */ } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[0] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[3] == 0) && - (ltbl.ilsb[4] == 0) && - (ltbl.ilsb[5] == 0) && - (ltbl.ilsb[6] == 0) && - (ltbl.ilsb[7] == 0)) { + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[3] == 0) && + (ltbl.ilsb[4] == 0) && + (ltbl.ilsb[5] == 0) && + (ltbl.ilsb[6] == 0) && + (ltbl.ilsb[7] == 0)) { if (src_zero) { pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } + smix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, &mtbl); + if (smix == 0xFF) { smix = pce_dasa_msb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, &mtbl); + &hpctbl->pce_sub_tbl, &mtbl); smflag = 1; } + if (smix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + slix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, <bl); + if (slix == 0xFF) { slix = pce_dasa_lsb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, <bl); + &hpctbl->pce_sub_tbl, <bl); slflag = 1; } + if (slix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + /* update the entry for another port number if already exists*/ for (i = 0; i < gswdev->iflag.itblsize; i++) { /* Check if port was already exist */ if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].slsbindex == slix) && - (hitbl->mctable[i].smsbindex == smix) && - (hitbl->mctable[i].valid == 1)) { + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].slsbindex == slix) && + (hitbl->mctable[i].smsbindex == smix) && + (hitbl->mctable[i].valid == 1)) { if (((hitbl->mctable[i].pmap >> parm->nPortId) - & 0x1) == 1) + & 0x1) == 1) return GSW_statusOk; + switch (hitbl->mctable[i].mcmode) { case GSW_IGMP_MEMBER_DONT_CARE: hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; + /* Add the port */ hitbl->mctable[i].pmap |= (1 << parm->nPortId); break; + case GSW_IGMP_MEMBER_EXCLUDE: if (gswdev->gipver == LTQ_GSWIP_3_0) exclude_rule = 0; @@ -520,139 +626,163 @@ static int gsw2x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) hitbl->mctable[i].pmap |= (1 << parm->nPortId); hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; hpctbl->pce_sub_tbl.iplsbtcnt[slix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; hpctbl->pce_sub_tbl.ipmsbtcnt[smix]++; } + break; } /* end switch */ + /* Now, we write into Multicast SW Table */ memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = (hitbl->mctable[i].smsbindex << 8) - | hitbl->mctable[i].slsbindex; + | hitbl->mctable[i].slsbindex; ptdata.key[0] = (hitbl->mctable[i].dmsbindex << 8) - | hitbl->mctable[i].dlsbindex; + | hitbl->mctable[i].dlsbindex; + if (gswdev->gipver == LTQ_GSWIP_3_0) { ptdata.val[0] = hitbl->mctable[i].pmap; ptdata.val[1] = - (parm->nSubIfId & 0xFFFF) << 3; + (parm->nSubIfId & 0xFFFF) << 3; ptdata.key[2] = parm->nFID & 0x3F; + if (parm->eModeMember == - GSW_IGMP_MEMBER_EXCLUDE) { + GSW_IGMP_MEMBER_EXCLUDE) { ptdata.key[2] |= (1 << 15); - /*ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; */ + /*ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; */ } else { ptdata.key[2] &= ~(1 << 15); } } else { if (parm->eModeMember == - GSW_IGMP_MEMBER_EXCLUDE) + GSW_IGMP_MEMBER_EXCLUDE) ptdata.val[0] = (0 << parm->nPortId); else ptdata.val[0] = hitbl->mctable[i].pmap; } + ptdata.valid = hitbl->mctable[i].valid; gsw_pce_table_write(cdev, &ptdata); new_entry = 1; + if (exclude_rule == 0) return GSW_statusOk; } } /* wildcard entry for EXCLUDE rule for port number if already exists*/ -/*if (gswdev->gipver != LTQ_GSWIP_3_0) {*/ + /*if (gswdev->gipver != LTQ_GSWIP_3_0) {*/ if ((exclude_rule == 1) && (new_entry == 1)) { for (i = 0; i < gswdev->iflag.itblsize; i++) { /* Check if port was already exist */ if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].slsbindex == 0x7F) && - (hitbl->mctable[i].smsbindex == 0x7F) && - (hitbl->mctable[i].valid == 1)) { + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].slsbindex == 0x7F) && + (hitbl->mctable[i].smsbindex == 0x7F) && + (hitbl->mctable[i].valid == 1)) { if (((hitbl->mctable[i].pmap >> - parm->nPortId) & 0x1) == 1) { + parm->nPortId) & 0x1) == 1) { return GSW_statusOk; } else { hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == - GSW_IP_SELECT_IPV6) + GSW_IP_SELECT_IPV6) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; + /* Add the port */ hitbl->mctable[i].pmap |= - (1 << parm->nPortId); + (1 << parm->nPortId); } + hitbl->mctable[i].mcmode = - GSW_IGMP_MEMBER_DONT_CARE; + GSW_IGMP_MEMBER_DONT_CARE; memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = - ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + ((hitbl->mctable[i].smsbindex << 8) + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = - ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + ((hitbl->mctable[i].dmsbindex << 8) + | (hitbl->mctable[i].dlsbindex)); ptdata.val[0] = hitbl->mctable[i].pmap; ptdata.valid = hitbl->mctable[i].valid; + if (gswdev->gipver == LTQ_GSWIP_3_0) { ptdata.val[1] = - (parm->nSubIfId & 0xFFFF) << 3; + (parm->nSubIfId & 0xFFFF) << 3; ptdata.key[2] = parm->nFID & 0x3F; ptdata.key[2] |= - (parm->bExclSrcIP & 1) << 15; + (parm->bExclSrcIP & 1) << 15; } + gsw_pce_table_write(cdev, &ptdata); return GSW_statusOk; } } } -/* }*/ -/* Create the new DstIP & SrcIP entry */ + + /* }*/ + /* Create the new DstIP & SrcIP entry */ if (new_entry == 0) { if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { i = 0; + while (i < gswdev->iflag.itblsize) { /* Find a new empty entry to add */ if (hitbl->mctable[i].valid == 0) break; + i++; } } else if (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE) { i = 63; + while (i > 0) { /* Find a new empty entry to add */ if (hitbl->mctable[i].valid == 0) break; + i--; } } + if (i >= 0 && i < gswdev->iflag.itblsize) { hitbl->mctable[i].dlsbindex = dlix; hitbl->mctable[i].dmsbindex = dmix; hitbl->mctable[i].pmap |= (1 << parm->nPortId); + if (dlflag) hpctbl->pce_sub_tbl.iplsbtcnt[dlix] = 1; else hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { if (dmflag) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] = 1; else hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; } + hitbl->mctable[i].valid = 1; hitbl->mctable[i].mcmode = parm->eModeMember; + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { hitbl->mctable[i].slsbindex = slix; hitbl->mctable[i].smsbindex = smix; + if (slflag) hpctbl->pce_sub_tbl.iplsbtcnt[slix] = 1; else hpctbl->pce_sub_tbl.iplsbtcnt[slix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { if (smflag) hpctbl->pce_sub_tbl.ipmsbtcnt[smix] = 1; @@ -660,19 +790,20 @@ static int gsw2x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) hpctbl->pce_sub_tbl.ipmsbtcnt[smix]++; } } else if (parm->eModeMember == - GSW_IGMP_MEMBER_DONT_CARE) { + GSW_IGMP_MEMBER_DONT_CARE) { hitbl->mctable[i].slsbindex = 0x7F; hitbl->mctable[i].smsbindex = 0x7F; } } + memset(&ptdata, 0, sizeof(pctbl_prog_t)); /* Now, we write into Multicast SW Table */ ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | hitbl->mctable[i].slsbindex); + | hitbl->mctable[i].slsbindex); ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | hitbl->mctable[i].dlsbindex); + | hitbl->mctable[i].dlsbindex); if (gswdev->gipver == LTQ_GSWIP_3_0) { ptdata.val[0] = hitbl->mctable[i].pmap; @@ -682,90 +813,105 @@ static int gsw2x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) else ptdata.val[0] = hitbl->mctable[i].pmap; } + ptdata.valid = hitbl->mctable[i].valid; + if (gswdev->gipver == LTQ_GSWIP_3_0) { ptdata.val[1] = (parm->nSubIfId & 0xFFFF) << 3; ptdata.key[2] = parm->nFID & 0x3F; ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; } + gsw_pce_table_write(cdev, &ptdata); if ((parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { for (i = 0; i < gswdev->iflag.itblsize; i++) { /* Check if port was already exist */ if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].slsbindex == 0x7F) && - (hitbl->mctable[i].smsbindex == 0x7F) && - (hitbl->mctable[i].valid == 1)) { + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].slsbindex == 0x7F) && + (hitbl->mctable[i].smsbindex == 0x7F) && + (hitbl->mctable[i].valid == 1)) { if (((hitbl->mctable[i].pmap >> - parm->nPortId) & 0x1) == 1) + parm->nPortId) & 0x1) == 1) return GSW_statusOk; + hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == - GSW_IP_SELECT_IPV6) + GSW_IP_SELECT_IPV6) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; + hitbl->mctable[i].mcmode = - GSW_IGMP_MEMBER_DONT_CARE; + GSW_IGMP_MEMBER_DONT_CARE; /* Add the port */ hitbl->mctable[i].pmap |= - (1 << parm->nPortId); + (1 << parm->nPortId); memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = - ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + ((hitbl->mctable[i].smsbindex << 8) + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = - ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + ((hitbl->mctable[i].dmsbindex << 8) + | (hitbl->mctable[i].dlsbindex)); ptdata.val[0] = hitbl->mctable[i].pmap; ptdata.valid = hitbl->mctable[i].valid; gsw_pce_table_write(cdev, &ptdata); return GSW_statusOk; } } + i = 63; + while (i > 0) { /* Find a new empty entry to add */ if (hitbl->mctable[i].valid == 0) break; + i--; } - if (i >= 0 && i < gswdev->iflag.itblsize) { + + if (i >= 0 && i < gswdev->iflag.itblsize) { /* Now, we write into Multicast SW Table */ - hitbl->mctable[i].dlsbindex = dlix; - hitbl->mctable[i].dmsbindex = dmix; - hitbl->mctable[i].slsbindex = 0x7F; - hitbl->mctable[i].smsbindex = 0x7F; - hitbl->mctable[i].pmap |= (1 << parm->nPortId); - hitbl->mctable[i].mcmode = GSW_IGMP_MEMBER_DONT_CARE; - hitbl->mctable[i].valid = 1; - hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; - if (parm->eIPVersion == GSW_IP_SELECT_IPV6) - hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; - memset(&ptdata, 0, sizeof(pctbl_prog_t)); - ptdata.table = PCE_MULTICAST_SW_INDEX; - ptdata.pcindex = i; - ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | hitbl->mctable[i].slsbindex); - ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | hitbl->mctable[i].dlsbindex); - ptdata.val[0] = hitbl->mctable[i].pmap; - ptdata.valid = hitbl->mctable[i].valid; - if (gswdev->gipver == LTQ_GSWIP_3_0) { - ptdata.val[1] = - (parm->nSubIfId & 0xFFFF) << 3; - ptdata.key[2] = parm->nFID & 0x3F; - ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; - } - gsw_pce_table_write(cdev, &ptdata); + hitbl->mctable[i].dlsbindex = dlix; + hitbl->mctable[i].dmsbindex = dmix; + hitbl->mctable[i].slsbindex = 0x7F; + hitbl->mctable[i].smsbindex = 0x7F; + hitbl->mctable[i].pmap |= (1 << parm->nPortId); + hitbl->mctable[i].mcmode = GSW_IGMP_MEMBER_DONT_CARE; + hitbl->mctable[i].valid = 1; + hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) + hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; + + memset(&ptdata, 0, sizeof(pctbl_prog_t)); + ptdata.table = PCE_MULTICAST_SW_INDEX; + ptdata.pcindex = i; + ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) + | hitbl->mctable[i].slsbindex); + ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) + | hitbl->mctable[i].dlsbindex); + ptdata.val[0] = hitbl->mctable[i].pmap; + ptdata.valid = hitbl->mctable[i].valid; + + if (gswdev->gipver == LTQ_GSWIP_3_0) { + ptdata.val[1] = + (parm->nSubIfId & 0xFFFF) << 3; + ptdata.key[2] = parm->nFID & 0x3F; + ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; + } + + gsw_pce_table_write(cdev, &ptdata); } else { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); } } } + /* Debug */ return GSW_statusOk; } @@ -784,208 +930,260 @@ static int gsw3x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) pctbl_prog_t ptdata; pce_dasa_lsb_t ltbl; pce_dasa_msb_t mtbl; + memset(&ptdata, 0, sizeof(pctbl_prog_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (gswdev->iflag.igv3 != 1) { pr_err("%s:%s:%d(bIGMPv3 need to be enable)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + if ((parm->eIPVersion != GSW_IP_SELECT_IPV4) - && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { + && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { pr_err("%s:%s:%d (IPv4/IPV6 need to enable)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gda.nIPv4 >> (i * 8)) - & 0xFF); - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + & 0xFF); + + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gda.nIPv6[i] >> 8) & 0xFF); } - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; dmix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, - &mtbl); + &mtbl); + if (dmix == 0xFF) { dmix = pce_dasa_msb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, &mtbl); + &hpctbl->pce_sub_tbl, &mtbl); dmflag = 1; } + if (dmix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* First, search for DIP in the DA/SA table (DIP LSB) */ + + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gda.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gda.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i + 4] >> 8) & 0xFF); } - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } + dlix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, - <bl); + <bl); + if (dlix == 0xFF) { dlix = pce_dasa_lsb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, <bl); + &hpctbl->pce_sub_tbl, <bl); dlflag = 1; } + if (dlix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) || - (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gsa.nIPv4 >> (i * 8)) - & 0xFF); - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + & 0xFF); + + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[3] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[0] == 0)) { + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[0] == 0)) { pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + return GSW_statusErr; } } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { int src_zero = 0; - /* First, search for DIP in the DA/SA table (DIP MSB) */ + + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gsa.nIPv6[i] - & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gsa.nIPv6[i] + & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gsa.nIPv6[i] >> 8) - & 0xFF); + & 0xFF); } - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; + if (parm->eModeMember == - GSW_IGMP_MEMBER_EXCLUDE) { + GSW_IGMP_MEMBER_EXCLUDE) { if (mtbl.imsb[0] == 0 && - mtbl.imsb[1] == 0 && - mtbl.imsb[2] == 0 && - mtbl.imsb[3] == 0 && - mtbl.imsb[4] == 0 && - mtbl.imsb[5] == 0 && - mtbl.imsb[6] == 0 && - mtbl.imsb[7] == 0) { + mtbl.imsb[1] == 0 && + mtbl.imsb[2] == 0 && + mtbl.imsb[3] == 0 && + mtbl.imsb[4] == 0 && + mtbl.imsb[5] == 0 && + mtbl.imsb[6] == 0 && + mtbl.imsb[7] == 0) { src_zero = 1; } } - /* First, search for DIP in the DA/SA table (DIP LSB) */ + + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gsa.nIPv6[i+4] - & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i+4] >> 8) - & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gsa.nIPv6[i + 4] + & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i + 4] >> 8) + & 0xFF); } - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; + if (parm->eModeMember == - GSW_IGMP_MEMBER_EXCLUDE) { + GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[0] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[3] == 0) && - (ltbl.ilsb[4] == 0) && - (ltbl.ilsb[5] == 0) && - (ltbl.ilsb[6] == 0) && - (ltbl.ilsb[7] == 0)) { + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[3] == 0) && + (ltbl.ilsb[4] == 0) && + (ltbl.ilsb[5] == 0) && + (ltbl.ilsb[6] == 0) && + (ltbl.ilsb[7] == 0)) { if (src_zero) { pr_err("%s:%s:%d (Exclude rule SIP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } + smix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, - &mtbl); + &mtbl); + if (smix == 0xFF) { smix = pce_dasa_msb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, &mtbl); + &hpctbl->pce_sub_tbl, &mtbl); smflag = 1; } + if (smix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + slix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, - <bl); + <bl); + if (slix == 0xFF) { slix = pce_dasa_lsb_tbl_write(cdev, - &hpctbl->pce_sub_tbl, <bl); + &hpctbl->pce_sub_tbl, <bl); slflag = 1; } + if (slix < 0) { pr_err("%s:%s:%d (IGMP Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + /* update the entry for another port number if already exists*/ for (i = 0; i < gswdev->iflag.itblsize; i++) { /* Check if port was already exist */ if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].slsbindex == slix) && - (hitbl->mctable[i].smsbindex == smix) && - (hitbl->mctable[i].valid == 1) && - (hitbl->mctable[i].fid == parm->nFID)) { + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].slsbindex == slix) && + (hitbl->mctable[i].smsbindex == smix) && + (hitbl->mctable[i].valid == 1) && + (hitbl->mctable[i].fid == parm->nFID)) { if (((hitbl->mctable[i].pmap >> parm->nPortId) - & 0x1) == 1) + & 0x1) == 1) return GSW_statusOk; + exclude_rule = 0; + switch (hitbl->mctable[i].mcmode) { case GSW_IGMP_MEMBER_DONT_CARE: hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; + /* Add the port */ hitbl->mctable[i].pmap |= (1 << parm->nPortId); break; + case GSW_IGMP_MEMBER_EXCLUDE: exclude_rule = 1; -/* hitbl->mctable[i].exclude = 1; */ -/* ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; */ + + /* hitbl->mctable[i].exclude = 1; */ + /* ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; */ case GSW_IGMP_MEMBER_INCLUDE: /* Add the port */ hitbl->mctable[i].pmap |= (1 << parm->nPortId); hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; hpctbl->pce_sub_tbl.iplsbtcnt[slix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; hpctbl->pce_sub_tbl.ipmsbtcnt[smix]++; } + break; } /* end switch */ + /* Now, we write into Multicast SW Table */ memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + | (hitbl->mctable[i].dlsbindex)); ptdata.key[2] = ((hitbl->mctable[i].fid) & 0x3F); ptdata.key[2] |= ((hitbl->mctable[i].exclude) << 15); ptdata.val[0] = hitbl->mctable[i].pmap; @@ -996,51 +1194,62 @@ static int gsw3x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) } } -/* Create the new DstIP & SrcIP entry */ + /* Create the new DstIP & SrcIP entry */ if (new_entry == 0) { if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) || - (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { i = 0; + while (i < gswdev->iflag.itblsize) { /* Find a new empty entry to add */ if (hitbl->mctable[i].valid == 0) break; + i++; } } else if (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE) { i = 63; + while (i > 0) { /* Find a new empty entry to add */ if (hitbl->mctable[i].valid == 0) break; + i--; } } + if (i >= 0 && i < gswdev->iflag.itblsize) { hitbl->mctable[i].dlsbindex = dlix; hitbl->mctable[i].dmsbindex = dmix; hitbl->mctable[i].pmap |= (1 << parm->nPortId); + if (dlflag) hpctbl->pce_sub_tbl.iplsbtcnt[dlix] = 1; else hpctbl->pce_sub_tbl.iplsbtcnt[dlix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { if (dmflag) hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] = 1; else hpctbl->pce_sub_tbl.ipmsbtcnt[dmix]++; } + hitbl->mctable[i].valid = 1; hitbl->mctable[i].mcmode = parm->eModeMember; + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { hitbl->mctable[i].slsbindex = slix; hitbl->mctable[i].smsbindex = smix; + if (slflag) hpctbl->pce_sub_tbl.iplsbtcnt[slix] = 1; else hpctbl->pce_sub_tbl.iplsbtcnt[slix]++; + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { if (smflag) hpctbl->pce_sub_tbl.ipmsbtcnt[smix] = 1; @@ -1048,11 +1257,12 @@ static int gsw3x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) hpctbl->pce_sub_tbl.ipmsbtcnt[smix]++; } } else if (parm->eModeMember == - GSW_IGMP_MEMBER_DONT_CARE) { + GSW_IGMP_MEMBER_DONT_CARE) { hitbl->mctable[i].slsbindex = 0x7F; hitbl->mctable[i].smsbindex = 0x7F; } } + hitbl->mctable[i].fid = (parm->nFID & 0x3F); hitbl->mctable[i].subifid = (parm->nSubIfId & 0xFFFF); memset(&ptdata, 0, sizeof(pctbl_prog_t)); @@ -1060,21 +1270,24 @@ static int gsw3x_msw_table_wr(void *cdev, GSW_multicastTable_t *parm) ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + | (hitbl->mctable[i].dlsbindex)); ptdata.val[0] = hitbl->mctable[i].pmap; ptdata.valid = hitbl->mctable[i].valid; ptdata.val[1] = (parm->nSubIfId & 0xFFFF) << 3; ptdata.key[2] |= parm->nFID & 0x3F; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { /* ptdata.key[2] |= (parm->bExclSrcIP & 1) << 15; */ ptdata.key[2] |= (1 << 15); hitbl->mctable[i].exclude = 1; } + gsw_pce_table_write(cdev, &ptdata); } + return GSW_statusOk; } @@ -1090,229 +1303,288 @@ static int gsw3x_msw_table_rm(void *cdev, GSW_multicastTable_t *parm) pce_dasa_lsb_t ltbl; pce_dasa_msb_t mtbl; int dlix = 0x7F, dmix = 0x7F, slix = 0x7F, smix = 0x7F; + memset(&ptdata, 0, sizeof(pctbl_prog_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); + if ((parm->eIPVersion != GSW_IP_SELECT_IPV4) - && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { + && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { pr_err("%s:%s:%d (IPv4/IPV6 need to enable!!!)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) && - (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) && - (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE)) { + (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) && + (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE)) { pr_err("%s:%s:%d (!!!)\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gda.nIPv4 >> (i * 8)) - & 0xFF); - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + & 0xFF); + + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6 /* IPv6 */) { /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gda.nIPv6[i] >> 8) & 0xFF); } - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; dmix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, - &mtbl); + &mtbl); + if (dmix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gda.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gda.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i + 4] >> 8) & 0xFF); } - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } + dlix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, - <bl); + <bl); + if (dlix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gsa.nIPv4 >> (i * 8)) - & 0xFF); - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + & 0xFF); + + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if (ltbl.ilsb[3] == 0 && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[0] == 0)) { + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[0] == 0)) { pr_err("%s:%s:%d (Exclude SIP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { int src_zero = 0; + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gsa.nIPv6[i] - & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gsa.nIPv6[i] + & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gsa.nIPv6[i] >> 8) - & 0xFF); + & 0xFF); } - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((mtbl.imsb[0] == 0) && - (mtbl.imsb[1] == 0) && - (mtbl.imsb[2] == 0) && - (mtbl.imsb[3] == 0) && - (mtbl.imsb[4] == 0) && - (mtbl.imsb[5] == 0) && - (mtbl.imsb[6] == 0) && - (mtbl.imsb[7] == 0)) + (mtbl.imsb[1] == 0) && + (mtbl.imsb[2] == 0) && + (mtbl.imsb[3] == 0) && + (mtbl.imsb[4] == 0) && + (mtbl.imsb[5] == 0) && + (mtbl.imsb[6] == 0) && + (mtbl.imsb[7] == 0)) src_zero = 1; } + smix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, - &mtbl); + &mtbl); + if (smix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } - /* First, search for DIP in the DA/SA table (DIP LSB) */ + + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gsa.nIPv6[i+4] - & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i+4] >> 8) - & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gsa.nIPv6[i + 4] + & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i + 4] >> 8) + & 0xFF); } - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[0] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[3] == 0) && - (ltbl.ilsb[4] == 0) && - (ltbl.ilsb[5] == 0) && - (ltbl.ilsb[6] == 0) && - (ltbl.ilsb[7] == 0)) { + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[3] == 0) && + (ltbl.ilsb[4] == 0) && + (ltbl.ilsb[5] == 0) && + (ltbl.ilsb[6] == 0) && + (ltbl.ilsb[7] == 0)) { if (src_zero) { pr_err("%s:%s:%d (Exclude SIP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } } + slix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, - <bl); + <bl); + if (slix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + for (i = 0; i < gswdev->iflag.itblsize; i++) { if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].slsbindex == slix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].smsbindex == smix) && - (hitbl->mctable[i].valid == 1) && - (hitbl->mctable[i].fid == parm->nFID)) { + (hitbl->mctable[i].slsbindex == slix) && + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].smsbindex == smix) && + (hitbl->mctable[i].valid == 1) && + (hitbl->mctable[i].fid == parm->nFID)) { switch (hitbl->mctable[i].mcmode) { case GSW_IGMP_MEMBER_DONT_CARE: if (((hitbl->mctable[i].pmap >> parm->nPortId) & 0x1) == 1) { hitbl->mctable[i].pmap &= ~(1 << parm->nPortId); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, dlix); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] == 0) /* Delet the sub table */ ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dlix); + &hpctbl->pce_sub_tbl, dlix); } - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { if (parm->eIPVersion == GSW_IP_SELECT_IPV6) ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dmix); + &hpctbl->pce_sub_tbl, dmix); } } - /* Check the port map status */ - /* Delet the entry from Multicast sw Table */ + + /* Check the port map status */ + /* Delet the entry from Multicast sw Table */ if (hitbl->mctable[i].pmap == 0) hitbl->mctable[i].valid = 0; + MATCH = 1; } + break; + case GSW_IGMP_MEMBER_INCLUDE: case GSW_IGMP_MEMBER_EXCLUDE: if (((hitbl->mctable[i].pmap >> parm->nPortId) & 0x1) == 1) { hitbl->mctable[i].pmap &= ~(1 << parm->nPortId); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, dlix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] == 0) { ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dlix); + &hpctbl->pce_sub_tbl, dlix); } } + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dmix); + &hpctbl->pce_sub_tbl, dmix); } } + if (hpctbl->pce_sub_tbl.iplsbtcnt[slix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, slix); + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.iplsbtcnt[slix] == 0) { ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, slix); + &hpctbl->pce_sub_tbl, slix); } } + if (hpctbl->pce_sub_tbl.ipmsbtcnt[smix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, smix); + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[smix] == 0) { ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, smix); + &hpctbl->pce_sub_tbl, smix); } } + /* Check the port map status */ if (hitbl->mctable[i].pmap == 0) { /* Delet the entry from Multicast sw Table */ hitbl->mctable[i].valid = 0; } + MATCH = 1; } + break; } + if (MATCH == 1) { memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + | (hitbl->mctable[i].dlsbindex)); ptdata.key[2] = (hitbl->mctable[i].fid) & 0x3F; ptdata.key[2] |= (hitbl->mctable[i].exclude) << 15; ptdata.val[0] = hitbl->mctable[i].pmap; @@ -1322,8 +1594,10 @@ static int gsw3x_msw_table_rm(void *cdev, GSW_multicastTable_t *parm) } } } + if (MATCH == 0) pr_err("The GIP/SIP not found\n"); + return GSW_statusOk; } @@ -1339,298 +1613,366 @@ static int gsw2x_msw_table_rm(void *cdev, GSW_multicastTable_t *parm) pce_dasa_lsb_t ltbl; pce_dasa_msb_t mtbl; int dlix = 0x7F, dmix = 0x7F, slix = 0x7F, smix = 0x7F; + memset(&ptdata, 0, sizeof(pctbl_prog_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); + if ((parm->eIPVersion != GSW_IP_SELECT_IPV4) - && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { + && (parm->eIPVersion != GSW_IP_SELECT_IPV6)) { pr_err("%s:%s:%d (IPv4/IPV6 need to enable!!!)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - && (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) - && (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE)) { + && (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) + && (parm->eModeMember == GSW_IGMP_MEMBER_DONT_CARE)) { pr_err("%s:%s:%d (!!!)\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gda.nIPv4 >> (i * 8)) & 0xFF); + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } else { /* DIP LSB Nibble Mask */ ltbl.mask[0] = 0xFF00; } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6 /* IPv6 */) { /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gda.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gda.nIPv6[i] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; } else { mtbl.mask[0] = 0;/* DIP MSB Nibble Mask */ } + dmix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, &mtbl); + if (dmix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gda.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gda.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gda.nIPv6[i + 4] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } else { ltbl.mask[0] = 0;/* DIP LSB Nibble Mask */ } } + dlix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, <bl); + if (dlix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((parm->eModeMember == GSW_IGMP_MEMBER_INCLUDE) - || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { + || (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE)) { if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->uIP_Gsa.nIPv4 >> (i * 8)) & 0xFF); + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0x0; ltbl.mask[1] = 0x0; - ltbl.mask[2] = 0xFFFF; ltbl.mask[3] = 0xFFFF; + ltbl.mask[0] = 0x0; + ltbl.mask[1] = 0x0; + ltbl.mask[2] = 0xFFFF; + ltbl.mask[3] = 0xFFFF; } else { /* DIP LSB Nibble Mask */ ltbl.mask[0] = 0xFF00; } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if (ltbl.ilsb[3] == 0 && ltbl.ilsb[2] == 0 - && ltbl.ilsb[1] == 0 && ltbl.ilsb[0] == 0) { + && ltbl.ilsb[1] == 0 && ltbl.ilsb[0] == 0) { pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } + if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { int src_zero = 0; + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->uIP_Gsa.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->uIP_Gsa.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->uIP_Gsa.nIPv6[i] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - mtbl.mask[0] = 0; mtbl.mask[1] = 0; - mtbl.mask[2] = 0; mtbl.mask[3] = 0; + mtbl.mask[0] = 0; + mtbl.mask[1] = 0; + mtbl.mask[2] = 0; + mtbl.mask[3] = 0; } else { mtbl.mask[0] = 0;/* DIP MSB Nibble Mask */ } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((mtbl.imsb[0] == 0) && - (mtbl.imsb[1] == 0) && - (mtbl.imsb[2] == 0) && - (mtbl.imsb[3] == 0) && - (mtbl.imsb[4] == 0) && - (mtbl.imsb[5] == 0) && - (mtbl.imsb[6] == 0) && - (mtbl.imsb[7] == 0)) + (mtbl.imsb[1] == 0) && + (mtbl.imsb[2] == 0) && + (mtbl.imsb[3] == 0) && + (mtbl.imsb[4] == 0) && + (mtbl.imsb[5] == 0) && + (mtbl.imsb[6] == 0) && + (mtbl.imsb[7] == 0)) src_zero = 1; } + smix = find_msb_tbl_entry(&hpctbl->pce_sub_tbl, - &mtbl); + &mtbl); + if (smix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->uIP_Gsa.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->uIP_Gsa.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->uIP_Gsa.nIPv6[i + 4] >> 8) & 0xFF); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { - ltbl.mask[0] = 0; ltbl.mask[1] = 0; - ltbl.mask[2] = 0; ltbl.mask[3] = 0; + ltbl.mask[0] = 0; + ltbl.mask[1] = 0; + ltbl.mask[2] = 0; + ltbl.mask[3] = 0; } else { ltbl.mask[0] = 0;/* DIP LSB Nibble Mask */ } + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { if ((ltbl.ilsb[0] == 0) && - (ltbl.ilsb[1] == 0) && - (ltbl.ilsb[2] == 0) && - (ltbl.ilsb[3] == 0) && - (ltbl.ilsb[4] == 0) && - (ltbl.ilsb[5] == 0) && - (ltbl.ilsb[6] == 0) && - (ltbl.ilsb[7] == 0)) { + (ltbl.ilsb[1] == 0) && + (ltbl.ilsb[2] == 0) && + (ltbl.ilsb[3] == 0) && + (ltbl.ilsb[4] == 0) && + (ltbl.ilsb[5] == 0) && + (ltbl.ilsb[6] == 0) && + (ltbl.ilsb[7] == 0)) { if (src_zero) { pr_err("%s:%s:%d (Exclude Rule Source IP is Wildcard)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } } } + slix = find_dasa_tbl_entry(&hpctbl->pce_sub_tbl, - <bl); + <bl); + if (slix == 0xFF) { pr_err("%s:%s:%d (IGMP Entry not found)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } + for (i = 0; i < gswdev->iflag.itblsize; i++) { if ((hitbl->mctable[i].dlsbindex == dlix) && - (hitbl->mctable[i].slsbindex == slix) && - (hitbl->mctable[i].dmsbindex == dmix) && - (hitbl->mctable[i].smsbindex == smix) && - (hitbl->mctable[i].valid == 1)) { + (hitbl->mctable[i].slsbindex == slix) && + (hitbl->mctable[i].dmsbindex == dmix) && + (hitbl->mctable[i].smsbindex == smix) && + (hitbl->mctable[i].valid == 1)) { switch (hitbl->mctable[i].mcmode) { case GSW_IGMP_MEMBER_DONT_CARE: if (((hitbl->mctable[i].pmap >> parm->nPortId) & 0x1) == 1) { hitbl->mctable[i].pmap &= ~(1 << parm->nPortId); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, dlix); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] == 0) { /* Delet the sub table */ ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dlix); + &hpctbl->pce_sub_tbl, dlix); } } - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { if (parm->eIPVersion == GSW_IP_SELECT_IPV6) ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dmix); + &hpctbl->pce_sub_tbl, dmix); } } - /* Check the port map status */ - /* Delet the entry from Multicast sw Table */ + + /* Check the port map status */ + /* Delet the entry from Multicast sw Table */ if (hitbl->mctable[i].pmap == 0) hitbl->mctable[i].valid = 0; + MATCH = 1; } + break; + case GSW_IGMP_MEMBER_INCLUDE: case GSW_IGMP_MEMBER_EXCLUDE: if (((hitbl->mctable[i].pmap >> parm->nPortId) & 0x1) == 1) { hitbl->mctable[i].pmap &= ~(1 << parm->nPortId); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, dlix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] == 0) { ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dlix); + &hpctbl->pce_sub_tbl, dlix); } } + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dmix); + &hpctbl->pce_sub_tbl, dmix); } } + if (hpctbl->pce_sub_tbl.iplsbtcnt[slix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, slix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.iplsbtcnt[slix] == 0) { ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, slix); + &hpctbl->pce_sub_tbl, slix); } } + if (hpctbl->pce_sub_tbl.ipmsbtcnt[smix] > 0) { ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, smix); - /* Delet the sub table */ + + /* Delet the sub table */ if (hpctbl->pce_sub_tbl.ipmsbtcnt[smix] == 0) { ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, smix); + &hpctbl->pce_sub_tbl, smix); } } - /* Check the port map status */ - /* Delet the entry from Multicast sw Table */ + + /* Check the port map status */ + /* Delet the entry from Multicast sw Table */ if (hitbl->mctable[i].pmap == 0) hitbl->mctable[i].valid = 0; MATCH = 1; + if (parm->eModeMember == GSW_IGMP_MEMBER_EXCLUDE) { for (j = 0; j < gswdev->iflag.itblsize; j++) { if ((hitbl->mctable[j].dlsbindex == dlix) && - (hitbl->mctable[j].slsbindex == 0x7F) && - (hitbl->mctable[j].dmsbindex == dmix) && - (hitbl->mctable[j].smsbindex == 0x7F) && - (hitbl->mctable[j].valid == 1)) { + (hitbl->mctable[j].slsbindex == 0x7F) && + (hitbl->mctable[j].dmsbindex == dmix) && + (hitbl->mctable[j].smsbindex == 0x7F) && + (hitbl->mctable[j].valid == 1)) { if (((hitbl->mctable[j].pmap >> parm->nPortId) & 0x1) == 1) { hitbl->mctable[j].pmap &= ~(1 << parm->nPortId); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] > 0) { ipdslsb_tblidx_del(&hpctbl->pce_sub_tbl, dlix); + if (hpctbl->pce_sub_tbl.iplsbtcnt[dlix] == 0) { - /* Delet the sub table */ + /* Delet the sub table */ ip_dasa_lsb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dlix); + &hpctbl->pce_sub_tbl, dlix); } } - if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { - ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); - if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { - /* Delet the sub table */ - ip_dasa_msb_tbl_del(cdev, - &hpctbl->pce_sub_tbl, dmix); + + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] > 0) { + ipdsmsb_tblidx_del(&hpctbl->pce_sub_tbl, dmix); + + if (hpctbl->pce_sub_tbl.ipmsbtcnt[dmix] == 0) { + /* Delet the sub table */ + ip_dasa_msb_tbl_del(cdev, + &hpctbl->pce_sub_tbl, dmix); + } } + + /* Check the port map status */ + if (hitbl->mctable[j].pmap == 0) { + /* Delet the entry from Multicast sw Table */ + hitbl->mctable[j].valid = 0; + hitbl->mctable[i].valid = 0; + } + + memset(&ptdata, 0, sizeof(pctbl_prog_t)); + ptdata.table = PCE_MULTICAST_SW_INDEX; + ptdata.pcindex = j; + ptdata.key[1] = ((0x7F << 8) | 0x7F); + ptdata.key[0] = ((hitbl->mctable[j].dmsbindex << 8) + | (hitbl->mctable[i].dlsbindex)); + ptdata.val[0] = hitbl->mctable[j].pmap; + ptdata.valid = hitbl->mctable[j].valid; + gsw_pce_table_write(cdev, &ptdata); } - /* Check the port map status */ - if (hitbl->mctable[j].pmap == 0) { - /* Delet the entry from Multicast sw Table */ - hitbl->mctable[j].valid = 0; - hitbl->mctable[i].valid = 0; - } - memset(&ptdata, 0, sizeof(pctbl_prog_t)); - ptdata.table = PCE_MULTICAST_SW_INDEX; - ptdata.pcindex = j; - ptdata.key[1] = ((0x7F << 8) | 0x7F); - ptdata.key[0] = ((hitbl->mctable[j].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); - ptdata.val[0] = hitbl->mctable[j].pmap; - ptdata.valid = hitbl->mctable[j].valid; - gsw_pce_table_write(cdev, &ptdata); } } } } + + break; } - break; - } + if (MATCH == 1) { memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_SW_INDEX; ptdata.pcindex = i; ptdata.key[1] = ((hitbl->mctable[i].smsbindex << 8) - | (hitbl->mctable[i].slsbindex)); + | (hitbl->mctable[i].slsbindex)); ptdata.key[0] = ((hitbl->mctable[i].dmsbindex << 8) - | (hitbl->mctable[i].dlsbindex)); + | (hitbl->mctable[i].dlsbindex)); ptdata.val[0] = hitbl->mctable[i].pmap; ptdata.valid = hitbl->mctable[i].valid; gsw_pce_table_write(cdev, &ptdata); } } } + if (MATCH == 0) pr_err("The GIP/SIP not found\n"); + return GSW_statusOk; } #endif /*CONFIG_LTQ_MULTICAST */ @@ -1645,91 +1987,94 @@ static void set_port_state(void *cdev, u32 pid, u32 stpstate, u32 st8021) { pctbl_prog_t tbl_prog_brdgeport_ingress; pctbl_prog_t tbl_prog_brdgeport_egress; - u16 State; + u16 State; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 i; - for (i = 0; i < sizeof(pstpstate)/sizeof(pstpstate_t); i++) { - pstpstate_t *pststate = &pstpstate[i]; + for (i = 0; i < sizeof(pstpstate) / sizeof(pstpstate_t); i++) { + pstpstate_t *pststate = &pstpstate[i]; + if ((pststate->psstate == stpstate) && - (pststate->ps8021x == st8021)) { - if(gswdev->gipver != LTQ_GSWIP_3_1) { - gswdev->pconfig[pid].penable = pststate->pen_reg; - gswdev->pconfig[pid].ptstate = pststate->pstate_reg; - /* Learning Limit */ - if (pststate->lrnlim == 0) { - gsw_w32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pid)), - PCE_PCTRL_1_LRNLIM_SHIFT, PCE_PCTRL_1_LRNLIM_SIZE, 0); - } else { - gsw_w32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pid)), - PCE_PCTRL_1_LRNLIM_SHIFT, PCE_PCTRL_1_LRNLIM_SIZE, - gswdev->pconfig[pid].llimit); - } - /* Port State */ - gsw_w32(cdev, (PCE_PCTRL_0_PSTATE_OFFSET + (0xA * pid)), - PCE_PCTRL_0_PSTATE_SHIFT, PCE_PCTRL_0_PSTATE_SIZE, - gswdev->pconfig[pid].ptstate); - /* Port Enable */ - gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (0xA * pid)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, - gswdev->pconfig[pid].penable); - } - - if(gswdev->gipver == LTQ_GSWIP_3_1) { - /*Same bridge port idx for ingress and egress bridge port configuration*/ - memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); - tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); - /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ - tbl_prog_brdgeport_ingress.pcindex |= (pid & 0x7F); - - memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); - tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); - /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ - tbl_prog_brdgeport_egress.pcindex |= (pid & 0x7F); - /*Address-based read for ingress bridge port configuration*/ - gsw_pce_table_read(cdev, &tbl_prog_brdgeport_ingress); - - /*Address-based read for egress bridge port configuration*/ - gsw_pce_table_read(cdev, &tbl_prog_brdgeport_egress); - - /* Learning Limit */ - if (pststate->lrnlim == 0) { - /*Disable learning and set learning limit to zero*/ - tbl_prog_brdgeport_ingress.val[0] |= (1 << 15); - } else { - /*Enable learning and set learning limit to given value*/ - tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 15); - } + (pststate->ps8021x == st8021)) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { + gswdev->pconfig[pid].penable = pststate->pen_reg; + gswdev->pconfig[pid].ptstate = pststate->pstate_reg; + + /* Learning Limit */ + if (pststate->lrnlim == 0) { + gsw_w32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pid)), + PCE_PCTRL_1_LRNLIM_SHIFT, PCE_PCTRL_1_LRNLIM_SIZE, 0); + } else { + gsw_w32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pid)), + PCE_PCTRL_1_LRNLIM_SHIFT, PCE_PCTRL_1_LRNLIM_SIZE, + gswdev->pconfig[pid].llimit); + } - if(pststate->psstate == GSW_STP_PORT_STATE_DISABLE) - State = PORT_STATE_DISABLE; - else - State = pststate->pstate_reg; + /* Port State */ + gsw_w32(cdev, (PCE_PCTRL_0_PSTATE_OFFSET + (0xA * pid)), + PCE_PCTRL_0_PSTATE_SHIFT, PCE_PCTRL_0_PSTATE_SIZE, + gswdev->pconfig[pid].ptstate); + /* Port Enable */ + gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (0xA * pid)), + SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, + gswdev->pconfig[pid].penable); + } + + if (IS_VRSN_31(gswdev->gipver)) { + /*Same bridge port idx for ingress and egress bridge port configuration*/ + memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); + tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - /*VAL 0 Reg 2:0 STP state ingress/egress*/ - tbl_prog_brdgeport_ingress.val[0] &= ~0x7; - tbl_prog_brdgeport_egress.val[0] &= ~0x7; - tbl_prog_brdgeport_ingress.val[0] |= (State & 0x7); - tbl_prog_brdgeport_egress.val[0] |= (State & 0x7); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ + tbl_prog_brdgeport_ingress.pcindex |= (pid & 0x7F); - tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); - /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ - tbl_prog_brdgeport_ingress.pcindex |= (pid & 0x7F); + memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); + tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ + tbl_prog_brdgeport_egress.pcindex |= (pid & 0x7F); + /*Address-based read for ingress bridge port configuration*/ + gsw_pce_table_read(cdev, &tbl_prog_brdgeport_ingress); - tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); - /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ - tbl_prog_brdgeport_egress.pcindex |= (pid & 0x7F); + /*Address-based read for egress bridge port configuration*/ + gsw_pce_table_read(cdev, &tbl_prog_brdgeport_egress); + + /* Learning Limit */ + if (pststate->lrnlim == 0) { + /*Disable learning and set learning limit to zero*/ + tbl_prog_brdgeport_ingress.val[0] |= (1 << 15); + } else { + /*Enable learning and set learning limit to given value*/ + tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 15); + } - /*Address-based write for ingress bridge port configuration*/ - gsw_pce_table_write(cdev, &tbl_prog_brdgeport_ingress); - /*Address-based write for egress bridge port configuration*/ - gsw_pce_table_write(cdev, &tbl_prog_brdgeport_egress); - } + if (pststate->psstate == GSW_STP_PORT_STATE_DISABLE) + State = PORT_STATE_DISABLE; + else + State = pststate->pstate_reg; + + /*VAL 0 Reg 2:0 STP state ingress/egress*/ + tbl_prog_brdgeport_ingress.val[0] &= ~0x7; + tbl_prog_brdgeport_egress.val[0] &= ~0x7; + tbl_prog_brdgeport_ingress.val[0] |= (State & 0x7); + tbl_prog_brdgeport_egress.val[0] |= (State & 0x7); + + tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ + tbl_prog_brdgeport_ingress.pcindex |= (pid & 0x7F); + + tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ + tbl_prog_brdgeport_egress.pcindex |= (pid & 0x7F); + + /*Address-based write for ingress bridge port configuration*/ + gsw_pce_table_write(cdev, &tbl_prog_brdgeport_ingress); + /*Address-based write for egress bridge port configuration*/ + gsw_pce_table_write(cdev, &tbl_prog_brdgeport_egress); + } } } } @@ -1742,15 +2087,18 @@ static void set_port_state(void *cdev, u32 pid, u32 stpstate, u32 st8021) /* The algorithm designed based on software architecture spec.*/ static u32 mratecalc(u32 ibsid, u32 expont, u32 mants) { - static const u16 ibs_table[] = {8*8, 32*8, 64*8, 96*8}; + static const u16 ibs_table[] = {8 * 8, 32 * 8, 64 * 8, 96 * 8}; u16 ibs; u32 mrate = 0; if ((ibsid == 0) && (expont == 0) && (mants == 0)) return 0; + ibs = ibs_table[ibsid]; - if(mants) + + if (mants) mrate = ((ibs * 25000) >> expont) / mants; + return mrate; } @@ -1760,16 +2108,18 @@ static u32 mratecalc(u32 ibsid, u32 expont, u32 mants) /* The algorithm designed based on software architecture spec. */ static int calc_mtoken(u32 mrate, u32 *ibsid, u32 *expont, u32 *mants) { - static const u16 ibs_table[] = {8*8, 32*8, 64*8, 96*8}; + static const u16 ibs_table[] = {8 * 8, 32 * 8, 64 * 8, 96 * 8}; u8 i; for (i = 3; i >= 0; i--) { u32 exp; u16 ibs = ibs_table[i]; + /* target is to get the biggest mantissa value */ - /* that can be used for the 10-Bit register */ + /* that can be used for the 10-Bit register */ for (exp = 0; exp < 16; exp++) { u32 mant = ((ibs * 25000) >> exp) / mrate; + if (mant < (1 << 10)) { *ibsid = i; *expont = exp; @@ -1786,8 +2136,10 @@ static u32 mratecalc_3_1(u32 ibsid, u32 expont, u32 mants) if ((ibsid == 0) && (expont == 0) && (mants == 0)) return 0; - if(mants) - mrate =(ibsid * 200000)/((mants+1)<<expont); + + if (mants) + mrate = (ibsid * 200000) / ((mants + 1) << expont); + return mrate; } @@ -1795,31 +2147,31 @@ static u32 mratecalc_3_1(u32 ibsid, u32 expont, u32 mants) #if defined(WIN_PC_MODE) && WIN_PC_MODE static __inline int fls(int input) { - u32 pos, ifzero = ~0; - __asm__ ( "bsr %1, %0\n\t" - "cmovz %2, %0" - : "=r" (pos) - : "rm" (input) - , "rm" (ifzero)); - return (int)(pos+1); + u32 pos, ifzero = ~0; + __asm__("bsr %1, %0\n\t" + "cmovz %2, %0" + : "=r"(pos) + : "rm"(input) + , "rm"(ifzero)); + return (int)(pos + 1); } #endif static int calc_mtoken_3_1(u32 mrate, u32 *ibsid, u32 *expont, u32 *mants) { - u32 temp, exp_val, exp, mant, ibs; + u32 temp, exp_val, exp, mant, ibs; - temp = 100000000 / mrate; - exp_val = temp>>9; - exp = (u32)fls((int)exp_val); - mant = exp ? 499 : (temp&0x01FF); - ibs = ((mant+1)<<exp)*mrate/200000; + temp = 100000000 / mrate; + exp_val = temp >> 9; + exp = (u32)fls((int)exp_val); + mant = exp ? 499 : (temp & 0x01FF); + ibs = ((mant + 1) << exp) * mrate / 200000; - *ibsid = ibs; - *expont = exp; - *mants = mant; + *ibsid = ibs; + *expont = exp; + *mants = mant; - return 0; + return 0; } #endif /*CONFIG_LTQ_QOS */ @@ -1828,6 +2180,7 @@ static void reset_vlan_sw_table(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u16 i; + for (i = 0; i < gswdev->avlantsz /* VLAN_ACTIVE_TABLE_SIZE */; i++) memset(&gswdev->avtable[i], 0, sizeof(avlan_tbl_t)); } @@ -1838,13 +2191,15 @@ u8 find_active_vlan_index(void *cdev, u16 vid) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 i, index = 0xFF; + for (i = 0; i < gswdev->avlantsz; i++) { if ((vid == gswdev->avtable[i].vid) - && (gswdev->avtable[i].valid == 1)) { + && (gswdev->avtable[i].valid == 1)) { index = i; break; } } + return index; } @@ -1852,20 +2207,23 @@ u8 fempty_avlan_index_table(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 i, index = 0xFF; + for (i = 1; i < gswdev->avlantsz; i += 1) { if (gswdev->avtable[i].valid == 0) { index = i; break; } } + if ((index == 0xFF) && - (gswdev->avtable[0].valid == 0)) + (gswdev->avtable[0].valid == 0)) return 0; + return index; } static void vlan_entry_set(void *cdev, u8 index, - avlan_tbl_t *avlan_entry) + avlan_tbl_t *avlan_entry) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); @@ -1878,7 +2236,7 @@ static void vlan_entry_set(void *cdev, u8 index, } static void get_vlan_sw_table(void *cdev, u8 pcindex, - avlan_tbl_t *avlan_entry) + avlan_tbl_t *avlan_entry) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); @@ -1891,40 +2249,7 @@ static void get_vlan_sw_table(void *cdev, u8 pcindex, } #endif /* CONFIG_LTQ_VLAN */ -GSW_return_t gsw_bm_table_read(void *cdev, bmtbl_prog_t *ptdata) -{ - GSW_return_t err = GSW_statusOk; - int i, noOfValues; - - if(ptdata->b64bitMode) - ptdata->tableID |= 0x40; - noOfValues = ptdata->numValues; - gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, (u32) ptdata->adr.raw); - gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x8000); - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SHIFT, RETURN_FROM_FUNCTION); - for(i=0;(i<noOfValues) /*&& (GSW_statusOk == err)*/;i++) - gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET - i, &(ptdata->value[i])); - return err; -} -GSW_return_t gsw_bm_table_write(void *cdev, bmtbl_prog_t *ptdata) -{ - GSW_return_t err = GSW_statusOk; - int i, noOfValues; - - if(ptdata->b64bitMode) - ptdata->tableID |= 0x40; - noOfValues = ptdata->numValues; - gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, (u32) ptdata->adr.raw); - gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x0020 ); - for(i=0;(i<noOfValues) /*&& (GSW_statusOk == err)*/;i++) - gsw_w32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET - i, ptdata->value[i]); - gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x8020 ); - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SHIFT, RETURN_FROM_FUNCTION); - return err; -} static void get_gsw_hw_cap(void *cdev) { @@ -1932,16 +2257,16 @@ static void get_gsw_hw_cap(void *cdev) u32 reg_val; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return; } - + gsw_r32(cdev, ETHSW_VERSION_REV_ID_OFFSET, ETHSW_VERSION_REV_ID_SHIFT, 16, ®_val); /*GET GSWIP version*/ gswdev->gipver = reg_val; - /* Total number of ports*/ + /* Total number of ports*/ gsw_r32(cdev, ETHSW_CAP_1_PPORTS_OFFSET, ETHSW_CAP_1_PPORTS_SHIFT, ETHSW_CAP_1_PPORTS_SIZE, ®_val); @@ -1949,8 +2274,8 @@ static void get_gsw_hw_cap(void *cdev) /* Total number of ports including vitual ports*/ gsw_r32(cdev, ETHSW_CAP_1_VPORTS_OFFSET, - ETHSW_CAP_1_VPORTS_SHIFT, - ETHSW_CAP_1_VPORTS_SIZE, ®_val); + ETHSW_CAP_1_VPORTS_SHIFT, + ETHSW_CAP_1_VPORTS_SIZE, ®_val); gswdev->tpnum = reg_val + gswdev->pnum; gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, @@ -1978,48 +2303,48 @@ static void get_gsw_hw_cap(void *cdev) ETHSW_CAP_5_IPPLEN_SHIFT, ETHSW_CAP_5_IPPLEN_SIZE, ®_val); gswdev->ip_pkt_lnt_size = reg_val; - - + + gsw_r32(cdev, ETHSW_CAP_5_PROT_OFFSET, ETHSW_CAP_5_PROT_SHIFT, ETHSW_CAP_5_PROT_SIZE, ®_val); gswdev->prot_table_size = reg_val; - + gsw_r32(cdev, ETHSW_CAP_6_MACDASA_OFFSET, ETHSW_CAP_6_MACDASA_SHIFT, ETHSW_CAP_6_MACDASA_SIZE, ®_val); gswdev->mac_dasa_table_size = reg_val; - + gsw_r32(cdev, ETHSW_CAP_6_APPL_OFFSET, ETHSW_CAP_6_APPL_SHIFT, ETHSW_CAP_6_APPL_SIZE, ®_val); gswdev->app_table_size = reg_val; - - + + gsw_r32(cdev, ETHSW_CAP_7_IPDASAM_OFFSET, ETHSW_CAP_7_IPDASAM_SHIFT, ETHSW_CAP_7_IPDASAM_SIZE, ®_val); gswdev->idsmtblsize = reg_val; - - + + gsw_r32(cdev, ETHSW_CAP_7_IPDASAL_OFFSET, ETHSW_CAP_7_IPDASAL_SHIFT, ETHSW_CAP_7_IPDASAL_SIZE, ®_val); gswdev->idsltblsize = reg_val; - + gsw_r32(cdev, ETHSW_CAP_8_MCAST_OFFSET, ETHSW_CAP_8_MCAST_SHIFT, ETHSW_CAP_8_MCAST_SIZE, ®_val); gswdev->mctblsize = reg_val; - - + + gsw_r32(cdev, ETHSW_CAP_9_FLAGG_OFFSET, ETHSW_CAP_9_FLAGG_SHIFT, ETHSW_CAP_9_FLAGG_SIZE, ®_val); - gswdev->tftblsize = reg_val; - - + gswdev->tftblsize = reg_val; + + gsw_r32(cdev, ETHSW_CAP_10_MACBT_OFFSET, ETHSW_CAP_10_MACBT_SHIFT, ETHSW_CAP_10_MACBT_SIZE, ®_val); @@ -2027,12 +2352,12 @@ static void get_gsw_hw_cap(void *cdev) - if(gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, ETHSW_CAP_4_VLAN_OFFSET, - ETHSW_CAP_4_VLAN_SHIFT, - ETHSW_CAP_4_VLAN_SIZE, ®_val); + ETHSW_CAP_4_VLAN_SHIFT, + ETHSW_CAP_4_VLAN_SIZE, ®_val); gswdev->avlantsz = reg_val; - + gsw_r32(cdev, ETHSW_CAP_14_SMAC_OFFSET, ETHSW_CAP_14_SMAC_SHIFT, ETHSW_CAP_14_SMAC_SIZE, ®_val); @@ -2063,8 +2388,8 @@ static void get_gsw_hw_cap(void *cdev) gswdev->num_of_rt_rtp = (1 << reg_val); gswdev->cport = GSW_3X_SOC_CPU_PORT; } - - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { gsw_r32(cdev, ETHSW_CAP_13_PMAC_OFFSET, ETHSW_CAP_13_PMAC_SHIFT, ETHSW_CAP_13_PMAC_SIZE, ®_val); @@ -2083,45 +2408,48 @@ static void get_gsw_hw_cap(void *cdev) gsw_r32(cdev, ETHSW_CAP_13_EVLAN_OFFSET, ETHSW_CAP_13_EVLAN_SHIFT, ETHSW_CAP_13_EVLAN_SIZE, ®_val); + if (gswdev->gipver == LTQ_GSWIP_3_0) gswdev->num_of_egvlan = (1 << reg_val); - if (gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) gswdev->num_of_extendvlan = (1 << reg_val); gswdev->cport = GSW_3X_SOC_CPU_PORT; - + } else { gswdev->cport = GSW_2X_SOC_CPU_PORT; } + /*Applicable only for 3.1*/ if (gswdev->gipver >= LTQ_GSWIP_3_1) { gsw_r32(cdev, ETHSW_CAP_16_VLANMAP_OFFSET, ETHSW_CAP_16_VLANMAP_SHIFT, ETHSW_CAP_16_VLANMAP_SIZE, ®_val); - gswdev->num_of_vlanfilter = 1<<reg_val; + gswdev->num_of_vlanfilter = 1 << reg_val; gsw_r32(cdev, ETHSW_CAP_16_MCASTHW_OFFSET, ETHSW_CAP_16_MCASTHW_SHIFT, ETHSW_CAP_16_MCASTHW_SIZE, ®_val); gswdev->mcsthw_snoop = reg_val; - + gsw_r32(cdev, ETHSW_CAP_17_BRG_OFFSET, ETHSW_CAP_17_BRG_SHIFT, ETHSW_CAP_17_BRG_SIZE, ®_val); - gswdev->num_of_bridge = 1<<reg_val; + gswdev->num_of_bridge = 1 << reg_val; + - gsw_r32(cdev, ETHSW_CAP_17_BRGPT_OFFSET, ETHSW_CAP_17_BRGPT_SHIFT, ETHSW_CAP_17_BRGPT_SIZE, ®_val); - gswdev->num_of_bridge_port = 1<<reg_val; + gswdev->num_of_bridge_port = 1 << reg_val; gsw_r32(cdev, ETHSW_CAP_17_PMAP_OFFSET, ETHSW_CAP_17_PMAP_SHIFT, ETHSW_CAP_17_PMAP_SIZE, ®_val); - gswdev->num_of_pmapper = 1<<reg_val; - + gswdev->num_of_pmapper = 1 << reg_val; + gsw_r32(cdev, ETHSW_CAP_18_CTP_OFFSET, ETHSW_CAP_18_CTP_SHIFT, ETHSW_CAP_18_CTP_SIZE, ®_val); @@ -2132,90 +2460,96 @@ static void get_gsw_hw_cap(void *cdev) gswdev->pce_tbl_reg.key = gsw_pce_tbl_reg_key; gswdev->pce_tbl_reg.mask = gsw_pce_tbl_reg_mask; gswdev->pce_tbl_reg.value = gsw_pce_tbl_reg_value; - if (gswdev->gipver >= LTQ_GSWIP_3_1) { + + if (gswdev->gipver == LTQ_GSWIP_3_1) { gswdev->num_of_pce_tbl = ARRAY_SIZE(gsw_pce_tbl_info_31); gswdev->pce_tbl_info = gsw_pce_tbl_info_31; - } - else if (gswdev->gipver == LTQ_GSWIP_3_0) { + } else if (gswdev->gipver == LTQ_GSWIP_3_0) { gswdev->num_of_pce_tbl = ARRAY_SIZE(gsw_pce_tbl_info_30); gswdev->pce_tbl_info = gsw_pce_tbl_info_30; - } - else { + } else { gswdev->num_of_pce_tbl = ARRAY_SIZE(gsw_pce_tbl_info_22); gswdev->pce_tbl_info = gsw_pce_tbl_info_22; } - - if(1) { + + if (1) { if (gswdev->gipver == LTQ_GSWIP_3_0) printk("\nGSWIP 3.0 HardWare Capability\n"); else if (gswdev->gipver == LTQ_GSWIP_3_1) printk("\nGSWIP 3.1 HardWare Capability\n"); - else + else printk("\nGSWIP 2.2 HardWare Capability\n"); + printk("-----------------------------\n\n"); - printk("Switch Version ID = 0x%x\n",gswdev->gipver); + printk("Switch Version ID = 0x%x\n", gswdev->gipver); printk("\n"); - printk("Number of logical port = %d\n",gswdev->pnum); - printk("Number of CTP Port = %d\n",gswdev->num_of_ctp); - printk("Number of Bridge = %d\n",gswdev->num_of_bridge); - printk("Number of Bridge Port = %d\n",gswdev->num_of_bridge_port); - printk("Number of P-Mapper = %d\n",gswdev->num_of_pmapper); - printk("Number of queues = %d\n",gswdev->num_of_queues); - printk("Number of meter instance = %d\n",gswdev->num_of_meters); - printk("Number of shapers = %d\n",gswdev->num_of_shapers); - printk("Number of PMAC = %d\n",gswdev->num_of_pmac); - printk("Number of CPU PORT = %d\n",gswdev->cport); + printk("Number of logical port = %d\n", gswdev->pnum); + printk("Number of CTP Port = %d\n", gswdev->num_of_ctp); + printk("Number of Bridge = %d\n", gswdev->num_of_bridge); + printk("Number of Bridge Port = %d\n", gswdev->num_of_bridge_port); + printk("Number of P-Mapper = %d\n", gswdev->num_of_pmapper); + printk("Number of queues = %d\n", gswdev->num_of_queues); + printk("Number of meter instance = %d\n", gswdev->num_of_meters); + printk("Number of shapers = %d\n", gswdev->num_of_shapers); + printk("Number of PMAC = %d\n", gswdev->num_of_pmac); + printk("Number of CPU PORT = %d\n", gswdev->cport); printk("\n"); - printk("PPPOE table size = %d\n",gswdev->num_of_pppoe); - printk("IP packet length table size = %d\n",gswdev->ip_pkt_lnt_size); - printk("Protocol table size = %d\n",gswdev->prot_table_size); - printk("MAC DA/SA table size = %d\n",gswdev->mac_dasa_table_size); - printk("Application table size = %d\n",gswdev->app_table_size); - printk("IP DA/SA MSB table size = %d\n",gswdev->idsmtblsize); - printk("IP DA/SA LSB table size = %d\n",gswdev->idsltblsize); - printk("Multicast table size = %d\n",gswdev->mctblsize); - printk("Multicast Hw Snoop = %d\n",gswdev->mcsthw_snoop); - printk("TFLOW table size = %d\n",gswdev->tftblsize); - printk("MAC bridge table size = %d\n",gswdev->mactblsize); - printk("TFLOW RMON counter table Size = %d\n",gswdev->num_of_ifrmon); - printk("Payload Table Size = %d\n",gswdev->pdtblsize); - printk("Extend VLAN Table Size table = %d\n",gswdev->num_of_extendvlan); - printk("Number of VlanFilter table Size = %d\n\n",gswdev->num_of_vlanfilter); + printk("PPPOE table size = %d\n", gswdev->num_of_pppoe); + printk("IP packet length table size = %d\n", gswdev->ip_pkt_lnt_size); + printk("Protocol table size = %d\n", gswdev->prot_table_size); + printk("MAC DA/SA table size = %d\n", gswdev->mac_dasa_table_size); + printk("Application table size = %d\n", gswdev->app_table_size); + printk("IP DA/SA MSB table size = %d\n", gswdev->idsmtblsize); + printk("IP DA/SA LSB table size = %d\n", gswdev->idsltblsize); + printk("Multicast table size = %d\n", gswdev->mctblsize); + printk("Multicast Hw Snoop = %d\n", gswdev->mcsthw_snoop); + printk("TFLOW table size = %d\n", gswdev->tftblsize); + printk("MAC bridge table size = %d\n", gswdev->mactblsize); + printk("TFLOW RMON counter table Size = %d\n", gswdev->num_of_ifrmon); + printk("Payload Table Size = %d\n", gswdev->pdtblsize); + printk("Extend VLAN Table Size table = %d\n", gswdev->num_of_extendvlan); + printk("Number of VlanFilter table Size = %d\n\n", gswdev->num_of_vlanfilter); } } -#if 0 +#if defined(WIN_PC_MODE) && WIN_PC_MODE int gsw_r_init() { return GSW_statusOk; } #endif + #if defined(CONFIG_USE_EMULATOR) && CONFIG_USE_EMULATOR static GSW_return_t emulator_config_coreinit_gswip3_0(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j=0; + u32 j = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) - gsw_r_init(); - /* Set Auto-Polling of connected PHYs - For all ports */ - gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), - GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x0); + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) +#ifdef __KERNEL__ + gsw_r_init(); + +#endif + /* Set Auto-Polling of connected PHYs - For all ports */ + gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), + GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x0); } else { - /* Set Auto-Polling of connected PHYs - For all ports */ - gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET - + GSW_TREG_OFFSET), - MDC_CFG_0_PEN_0_SHIFT, 6, 0x0); + /* Set Auto-Polling of connected PHYs - For all ports */ + gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + + GSW_TREG_OFFSET), + MDC_CFG_0_PEN_0_SHIFT, 6, 0x0); } - for (j = 0; j < gswdev->pnum-1; j++) { + for (j = 0; j < gswdev->pnum - 1; j++) { u32 reg_value; + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), @@ -2237,31 +2571,32 @@ static GSW_return_t emulator_config_coreinit_gswip3_0(void *cdev) (MAC_CTRL_0_GMII_OFFSET + (0xC * j)), MAC_CTRL_0_GMII_SHIFT, MAC_CTRL_0_GMII_SIZE, 2); - + gsw_w32(cdev, - ((GSWT_PHY_ADDR_1_SPEED_OFFSET + (j * 4)) - + GSW30_TOP_OFFSET), - GSWT_PHY_ADDR_1_SPEED_SHIFT, - GSWT_PHY_ADDR_1_SPEED_SIZE, 2); + ((GSWT_PHY_ADDR_1_SPEED_OFFSET + (j * 4)) + + GSW30_TOP_OFFSET), + GSWT_PHY_ADDR_1_SPEED_SHIFT, + GSWT_PHY_ADDR_1_SPEED_SIZE, 2); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_FDUP_OFFSET - + (j * 4)) - + GSW30_TOP_OFFSET), + + (j * 4)) + + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_FDUP_SHIFT, GSWT_PHY_ADDR_1_FDUP_SIZE, 1); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_LNKST_OFFSET - + (j * 4)) - + GSW30_TOP_OFFSET), + + (j * 4)) + + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_LNKST_SHIFT, GSWT_PHY_ADDR_1_LNKST_SIZE, 1); gsw_r32(cdev, ((GSWT_PHY_ADDR_1_LNKST_OFFSET - + (j * 4)) - + GSW30_TOP_OFFSET), + + (j * 4)) + + GSW30_TOP_OFFSET), 0, 16, ®_value); } } + return GSW_statusOk; } #endif @@ -2270,8 +2605,9 @@ static GSW_return_t emulator_config_coreinit_gswip3_0(void *cdev) static GSW_return_t set_srcmac_pauseframe(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } @@ -2291,10 +2627,12 @@ static GSW_return_t set_srcmac_pauseframe(void *cdev) static GSW_return_t mdio_init_gswip3_0(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + /* Configure the MDIO Clock 97.6 Khz 3.0*/ gsw_w32(cdev, (GSWT_MDCCFG_1_FREQ_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_1_FREQ_SHIFT, GSWT_MDCCFG_1_FREQ_SIZE, 0xFF); @@ -2310,36 +2648,37 @@ static GSW_return_t mdio_init_gswip3_0(void *cdev) static GSW_return_t mdio_init_gswip2_2(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } /* Configure the MDIO Clock 97.6 Khz 2.2*/ gsw_w32(cdev, (MDC_CFG_1_FREQ_OFFSET - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MDC_CFG_1_FREQ_SHIFT, MDC_CFG_1_FREQ_SIZE, 0xFF); return GSW_statusOk; } -static GSW_return_t legacy_switch_core_init(void *cdev) +static GSW_return_t legacy_switch_core_init(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 j=0; + u32 j = 0; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } #if defined(CONFIG_LTQ_VLAN) && CONFIG_LTQ_VLAN - /** Reset vlan software tableApplicable only for GSWIP 3.0 */ - reset_vlan_sw_table(cdev); + /** Reset vlan software tableApplicable only for GSWIP 3.0 */ + reset_vlan_sw_table(cdev); #endif /* CONFIG_LTQ_VLAN */ - ltq_ethsw_port_cfg_init(cdev); - /* Set the the source MAC register of pause frame */ - set_srcmac_pauseframe(cdev); + ltq_ethsw_port_cfg_init(cdev); + /* Set the the source MAC register of pause frame */ + set_srcmac_pauseframe(cdev); if (gswdev->gipver == LTQ_GSWIP_3_0) { /**Apllicable only for GSWIP 3.0**/ @@ -2347,19 +2686,24 @@ static GSW_return_t legacy_switch_core_init(void *cdev) emulator_config_coreinit_gswip3_0(cdev); #else mdio_init_gswip3_0(cdev); + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { + +#ifdef __KERNEL__ gsw_r_init(); +#endif gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x1); -/* gsw_w32(cdev, (GSWT_PHY_ADDR_1_LNKST_OFFSET + GSW30_TOP_OFFSET), - GSWT_PHY_ADDR_1_LNKST_SHIFT, GSWT_PHY_ADDR_1_LNKST_SIZE, 1);*/ + /* gsw_w32(cdev, (GSWT_PHY_ADDR_1_LNKST_OFFSET + GSW30_TOP_OFFSET), + GSWT_PHY_ADDR_1_LNKST_SHIFT, GSWT_PHY_ADDR_1_LNKST_SIZE, 1);*/ } else { gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x1e); } + /* SDMA/FDMA and RMON counter Enable*/ - for (j = 0; j < gswdev->pnum-1; j++) { + for (j = 0; j < gswdev->pnum - 1; j++) { if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), @@ -2375,153 +2719,188 @@ static GSW_return_t legacy_switch_core_init(void *cdev) BM_PCFG_CNTEN_SIZE, 1); } } - for (j = 0; j < gswdev->pnum-1; j++) { + + for (j = 0; j < gswdev->pnum - 1; j++) { gsw_w32(cdev, ((GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_OFFSET - + (4 * j)) + GSW30_TOP_OFFSET), + + (4 * j)) + GSW30_TOP_OFFSET), GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SHIFT, GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SIZE, 0x3); } + #endif } else { /* Switch Core 2.2 and lower*/ mdio_init_gswip2_2(cdev); + /* EEE auto negotiation overides: */ /*clock disable (ANEG_EEE_0.CLK_STOP_CAPABLE) */ - for (j = 0; j < gswdev->pnum-1; j++) { + for (j = 0; j < gswdev->pnum - 1; j++) { gsw_w32(cdev, - ((ANEG_EEE_0_CLK_STOP_CAPABLE_OFFSET+j) - + GSW_TREG_OFFSET), - ANEG_EEE_0_CLK_STOP_CAPABLE_SHIFT, - ANEG_EEE_0_CLK_STOP_CAPABLE_SIZE, 0x3); + ((ANEG_EEE_0_CLK_STOP_CAPABLE_OFFSET + j) + + GSW_TREG_OFFSET), + ANEG_EEE_0_CLK_STOP_CAPABLE_SHIFT, + ANEG_EEE_0_CLK_STOP_CAPABLE_SIZE, 0x3); } } - if (gswdev->gipver == LTQ_GSWIP_3_0 ){ + if (gswdev->gipver == LTQ_GSWIP_3_0) { for (j = 0; j < gswdev->tpnum; j++) { - //pr_err("Enable CTP RMON for logical port %d\n",j); + //pr_err("Enable CTP RMON for logical port %d\n",j); gsw_w32(cdev, (BM_PCFG_CNTEN_OFFSET + (j * 2)), BM_PCFG_CNTEN_SHIFT, BM_PCFG_CNTEN_SIZE, 1); - gsw_w32(cdev, (BM_RMON_CTRL_BCAST_CNT_OFFSET + (j * 0x2)), - BM_RMON_CTRL_BCAST_CNT_SHIFT, BM_RMON_CTRL_BCAST_CNT_SIZE, 1); + gsw_w32(cdev, (BM_RMON_CTRL_BCAST_CNT_OFFSET + (j * 0x2)), + BM_RMON_CTRL_BCAST_CNT_SHIFT, BM_RMON_CTRL_BCAST_CNT_SIZE, 1); } + if (gswdev->gipver == LTQ_GSWIP_3_0 && gswdev->sdev == LTQ_FLOW_DEV_INT_R) { gsw_w32(cdev, PCE_TFCR_NUM_NUM_OFFSET, PCE_TFCR_NUM_NUM_SHIFT, PCE_TFCR_NUM_NUM_SIZE, 0x80); } } - + return GSW_statusOk; } -static GSW_return_t switch_core_init(void *cdev) +static GSW_return_t switch_core_init(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - GSW_BRIDGE_portConfig_t brdgport_config; - GSW_CTP_portConfig_t ctp_config; - GSW_CTP_portAssignment_t ctp_assign; - pctbl_prog_t tbl_prog_ctpport_ingress; - pctbl_prog_t tbl_prog_ctpport_egress; - u32 j=0,ret; + static GSW_BRIDGE_portConfig_t brdgport_config; + static GSW_CTP_portConfig_t ctp_config; + static GSW_CTP_portAssignment_t ctp_assign; + static pctbl_prog_t tbl_prog_ctpport_ingress; + static pctbl_prog_t tbl_prog_ctpport_egress; + u32 j = 0, ret; struct adap_ops *ops; - + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { +#ifdef __KERNEL__ + + /*Default Exvlan and Vlan filter Local table Init*/ + gswdev->extendvlan_idx.nUsedEntry = 0; + + for (j = 0; j < gswdev->num_of_extendvlan; j++) { + gswdev->extendvlan_idx.vlan_idx[j].VlanBlockId = EXVLAN_ENTRY_INVALID; + gswdev->extendvlan_idx.vlan_idx[j].IndexInUsageCnt = 0; + } + + gswdev->vlanfilter_idx.nUsedEntry = 0; + + for (j = 0; j < gswdev->num_of_vlanfilter; j++) { + gswdev->vlanfilter_idx.filter_idx[j].FilterBlockId = VLANFILTER_ENTRY_INVALID; + gswdev->vlanfilter_idx.filter_idx[j].IndexInUsageCnt = 0; + } + /**Bridge Settings*/ /*Default configuration :Allocate Bridge/FID 0*/ - gswdev->brdgeconfig_idx[0].IndexInUse=1; - - /**Bridge Port Settings*/ - /*Default configuration :Allocate Bridge port 0 and 1 - and initialize the local BP table for 0 and 1*/ - for(j=0;j < 2;j++) { - gswdev->brdgeportconfig_idx[j].IndexInUse=1; - gswdev->brdgeportconfig_idx[j].BrdgId=0; - gswdev->brdgeportconfig_idx[j].LearningLimit=0xFF; + gswdev->brdgeconfig_idx[0].IndexInUse = 1; + /*Default configuration :Allocate Bridge port 0 and 1*/ + gswdev->brdgeportconfig_idx[0].IndexInUse = 1; + gswdev->brdgeportconfig_idx[1].IndexInUse = 1; + + /*Default configuration :Force Set 0-127 Ingress bridge port mapping + to no Member and with Bridge/Fid 0, + Egress bridge port destination logical port to 0 */ + memset(&brdgport_config, 0, sizeof(GSW_BRIDGE_portConfig_t)); + brdgport_config.eMask = GSW_BRIDGE_PORT_CONFIG_MASK_FORCE | + GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID | + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING | + GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP; + + for (j = 0; j < gswdev->num_of_bridge_port; j++) { + brdgport_config.nBridgePortId = j; + /*initialize the local BP table*/ + gswdev->brdgeportconfig_idx[j].IngressExVlanBlkId = EXVLAN_ENTRY_INVALID; + gswdev->brdgeportconfig_idx[j].EgressExVlanBlkId = EXVLAN_ENTRY_INVALID; + gswdev->brdgeportconfig_idx[j].IngressVlanFilterBlkId = VLANFILTER_ENTRY_INVALID; + gswdev->brdgeportconfig_idx[j].EgressVlanFilter1BlkId = VLANFILTER_ENTRY_INVALID; + gswdev->brdgeportconfig_idx[j].EgressVlanFilter2BlkId = VLANFILTER_ENTRY_INVALID; + gswdev->brdgeportconfig_idx[j].BrdgId = 0; + gswdev->brdgeportconfig_idx[j].LearningLimit = 0xFF; /*Default STP State is GSW_STP_PORT_STATE_FORWARD it can be changed using GSW_Stp_PortCfgSet*/ - gswdev->brdgeportconfig_idx[j].StpState = - GSW_STP_PORT_STATE_FORWARD; + gswdev->brdgeportconfig_idx[j].StpState = + GSW_STP_PORT_STATE_FORWARD; /*By Default 8021X State is GSW_8021X_PORT_STATE_AUTHORIZED it can be changed using GSW_8021X_PortCfgSet*/ - gswdev->brdgeportconfig_idx[j].P8021xState= - GSW_8021X_PORT_STATE_AUTHORIZED; - } + gswdev->brdgeportconfig_idx[j].P8021xState = + GSW_8021X_PORT_STATE_AUTHORIZED; + ret = GSW_BridgePortConfigSet(cdev, &brdgport_config); - /*Default configuration :Force Set 0-127 Ingress bridge port mapping - to no Member and with Bridge/Fid 0, - Egress bridge port destination logical port to 0 */ - memset(&brdgport_config, 0, sizeof(GSW_BRIDGE_portConfig_t)); - brdgport_config.eMask = GSW_BRIDGE_PORT_CONFIG_MASK_FORCE | - GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID | - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING | - GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP; - for(j=0;j < gswdev->num_of_bridge_port;j++) { - brdgport_config.nBridgePortId=j; - ret=GSW_BridgePortConfigSet(cdev,&brdgport_config); - if (ret==GSW_statusErr) { + if (ret == GSW_statusErr) { pr_err("%s:%s:%d (GSW_BridgePortConfigSet returns ERROR)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } /**Logical Port Assignment Settings*/ /*Default Configuration :Allocate and Assign Logical port 0 with CTP 0-PMAC 0*/ - /*and*/ + /*and*/ /*Default Configuration :Allocate and Assign Logical port 1 with CTP 1-PMAC 1*/ - ctp_assign.nNumberOfCtpPort=1; + ctp_assign.nNumberOfCtpPort = 1; ctp_assign.eMode = GSW_LOGICAL_PORT_OTHER; - for(j=0;j < 2;j++) { - gswdev->ctpportconfig_idx[j].IndexInUse=1; - ctp_assign.nFirstCtpPortId=j; - ctp_assign.nLogicalPortId=j; - ret=GSW_CTP_PortAssignmentSet(cdev,&ctp_assign); - if (ret==GSW_statusErr) { + + for (j = 0; j < 2; j++) { + gswdev->ctpportconfig_idx[j].IndexInUse = 1; + ctp_assign.nFirstCtpPortId = j; + ctp_assign.nLogicalPortId = j; + ret = GSW_CTP_PortAssignmentSet(cdev, &ctp_assign); + + if (ret == GSW_statusErr) { pr_err("%s:%s:%d (GSW_CTP_PortAssignmentSet returns ERROR)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } /*Allocate CTP 287 - user is not allowed to use this CTP port*/ /*Default Configuration :Allocate and Assign Logical port 2 to 11 with CTP 287*/ - gswdev->ctpportconfig_idx[287].IndexInUse=1; - ctp_assign.nFirstCtpPortId=287; - ctp_assign.nNumberOfCtpPort=1; + gswdev->ctpportconfig_idx[287].IndexInUse = 1; + ctp_assign.nFirstCtpPortId = 287; + ctp_assign.nNumberOfCtpPort = 1; ctp_assign.eMode = GSW_LOGICAL_PORT_OTHER; - for(j=2;j < gswdev->tpnum;j++) { - ctp_assign.nLogicalPortId=j; - ret=GSW_CTP_PortAssignmentSet(cdev,&ctp_assign); - if (ret==GSW_statusErr) { + + for (j = 2; j < gswdev->tpnum; j++) { + ctp_assign.nLogicalPortId = j; + ret = GSW_CTP_PortAssignmentSet(cdev, &ctp_assign); + + if (ret == GSW_statusErr) { pr_err("%s:%s:%d (GSW_CTP_PortAssignmentSet returns ERROR)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } /**CTP port Settings*/ /*Default configuration :CTP 0 and 1 - Assign Bridge port 0 and 1 respectively + Assign Bridge port 0 and 1 respectively and disable bridge bypass*/ - for(j=0;j < 2;j++) { - gswdev->ctpportconfig_idx[j].BrdgPortId=j; - gswdev->ctpportconfig_idx[j].AssociatedLogicalPort=j; + for (j = 0; j < 2; j++) { + /*initialize the local CTP table*/ + gswdev->ctpportconfig_idx[j].BrdgPortId = j; + gswdev->ctpportconfig_idx[j].AssociatedLogicalPort = j; + gswdev->ctpportconfig_idx[j].IngressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].IngressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].EgressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].EgressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; memset(&ctp_config, 0, sizeof(GSW_CTP_portConfig_t)); - ctp_config.nLogicalPortId=j; - ctp_config.nSubIfIdGroup=0; - ctp_config.nBridgePortId=j; + ctp_config.nLogicalPortId = j; + ctp_config.nSubIfIdGroup = 0; + ctp_config.nBridgePortId = j; ctp_config.eMask = GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID | - GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS; - ret=GSW_CtpPortConfigSet(cdev,&ctp_config); - if (ret==GSW_statusErr) { + GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS; + ret = GSW_CtpPortConfigSet(cdev, &ctp_config); + + if (ret == GSW_statusErr) { pr_err("%s:%s:%d (GSW_CtpPortConfigSet returns ERROR)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return GSW_statusErr; } } @@ -2529,69 +2908,112 @@ static GSW_return_t switch_core_init(void *cdev) /*Allocate Bridge 127- user is not allowed to use this BP CTP 2 to 286 not assigned to any logical port and configured with bridge port 127 bridge port 0,1 ,127 and CTP 287 is Special port/Special usage*/ - gswdev->brdgeportconfig_idx[127].IndexInUse=1; - for(j=2;j < gswdev->num_of_ctp;j++) { - gswdev->ctpportconfig_idx[j].AssociatedLogicalPort=NOT_ASSIGNED; - gswdev->ctpportconfig_idx[j].BrdgPortId=127; + gswdev->brdgeportconfig_idx[127].IndexInUse = 1; - /*Same ctp port idx for ingress and egress ctp port configuration*/ + for (j = 2; j < gswdev->num_of_ctp; j++) { + gswdev->ctpportconfig_idx[j].AssociatedLogicalPort = NOT_ASSIGNED; + gswdev->ctpportconfig_idx[j].BrdgPortId = 127; + gswdev->ctpportconfig_idx[j].IngressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].IngressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].EgressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + gswdev->ctpportconfig_idx[j].EgressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; + + /*Same ctp port idx for ingress and egress ctp port configuration*/ memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_ingress.pcindex |= (j & 0x1FF); - + memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; CLEAR_U16(tbl_prog_ctpport_egress.pcindex); /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_egress.pcindex |= (j & 0x1FF); - + tbl_prog_ctpport_ingress.val[0] &= ~(0xFF); /*bridge port 127*/ tbl_prog_ctpport_ingress.val[0] |= 127; - + /*Address-based write for ingress ctp port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_ctpport_ingress); /*Address-based write for egress ctp port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_ctpport_egress); } - + /*Enable SDMA for logical port 0 (PMAC 0) and 1 (PMAC 1) only Note: Other logical port's SDMA will be enabled only during CTP Alloc*/ - for(j=0;j < 2 ;j++) { - gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 1); + for (j = 0; j < 2 ; j++) { + gsw_w32(cdev, + (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), + SDMA_PCTRL_PEN_SHIFT, + SDMA_PCTRL_PEN_SIZE, 1); } /*Enable FDMA for all logical ports*/ - for(j=0;j < gswdev->tpnum;j++) { + for (j = 0; j < gswdev->tpnum; j++) { gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 1); } - /* Enable CTP RMON for all logical port*/ + /*PMAC default queue assignment and configuration*/ + gsw_set_def_bypass_qmap(cdev, GSW_QOS_QMAP_SINGLE_MODE); + gsw_set_def_pce_qmap(cdev); + gsw_pmac_init_nondpu(); + gsw_qos_def_config(cdev); +#else + + /*Emulation/PC tool*/ + /*Enable FDMA/SDMA for all logical ports*/ + for (j = 0; j < gswdev->tpnum; j++) { + gsw_w32(cdev, + (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), + FDMA_PCTRL_EN_SHIFT, + FDMA_PCTRL_EN_SIZE, 1); + gsw_w32(cdev, + (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), + SDMA_PCTRL_PEN_SHIFT, + SDMA_PCTRL_PEN_SIZE, 1); + } + +#if defined(CONFIG_MAC) && CONFIG_MAC + struct mac_ops *mac_ops; + u32 max_mac = gsw_get_mac_subifcnt(0); + + for (j = 0; j < max_mac; j++) { + mac_ops = get_mac_ops(gswdev, j + 2); + mac_init_fn_ptrs(mac_ops); + mac_ops->init(mac_ops); + } + + ops = gsw_get_adap_ops(0); + gswss_init_fn_ptrs(ops); +#endif + +#endif + + /* Enable CTP RMON for all logical port*/ for (j = 0; j < gswdev->tpnum; j++) { gsw_w32(cdev, (BM_PCFG_CNTEN_OFFSET + (j * 2)), BM_PCFG_CNTEN_SHIFT, BM_PCFG_CNTEN_SIZE, 1); } - /*PMAC default queue assignment and configuration*/ - gsw_set_def_bypass_qmap(GSW_QOS_QMAP_SINGLE_MODE); - gsw_set_def_pce_qmap(); - gsw_pmac_init_nondpu(); - gsw_qos_def_config(); - + /* Switch Core Enable for Windows mode will be done in GSW_ENABLE */ +#if defined(WIN_PC_MODE) && WIN_PC_MODE +#else /*Note: Default Config*/ /*LP0 (fdma/sdma enabled) -> CTP 0 allocated ->Bridge port 0 allocated -> bridge/fid 0 allocated) */ - /*Enable GSWIP 3.1 Switch Core*/ + /*Enable GSWIP 3.1 Switch Core*/ ops = get_adap_ops(gswdev); ops->ss_core_en(ops, 1); - +#endif + /*Initalize GSWIP Irq*/ + GSW_Irq_init(cdev); } + return GSW_statusOk; } @@ -2607,17 +3029,18 @@ void *ethsw_api_core_init(ethsw_core_init_t *ethcinit) struct core_ops *ops; void *cdev; printk("Switch Core INIT...................\n"); - -#if defined(KERNEL_MODE) && KERNEL_MODE + +#ifdef __KERNEL__ /* KERNEL_MODE */ /** Get Platform Driver Data */ ops = platform_get_drvdata(ethcinit->pdev); /** Get Switch Core Private Data */ - PrvData = container_of(ops,ethsw_api_dev_t,ops); + PrvData = container_of(ops, ethsw_api_dev_t, ops); + if (PrvData == NULL) { pr_err("%s:%s:%d (Plateform driver data not allocated)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return PrvData; } @@ -2625,26 +3048,40 @@ void *ethsw_api_core_init(ethsw_core_init_t *ethcinit) memset(PrvData, 0, sizeof(ethsw_api_dev_t)); /** Set Core OPS struct Adress to cdev*/ - cdev=&PrvData->ops; + cdev = &PrvData->ops; /** Store Platform Device struct in Switch Core Private Data */ PrvData->pdev = ethcinit->pdev; - /** Initialize Switch Core Function Pointer */ - gsw_init_fn_ptrs(&PrvData->ops); + spin_lock_init(&PrvData->lock_pce); + spin_lock_init(&PrvData->lock_bm); + spin_lock_init(&PrvData->lock_misc); + spin_lock_init(&PrvData->lock_pmac); + spin_lock_init(&PrvData->lock_pae); + spin_lock_init(&PrvData->lock_irq); + spin_lock_init(&PrvData->lock_alloc); + spin_lock_init(&PrvData->lock_free); + spin_lock_init(&PrvData->lock_mdio); + spin_lock_init(&PrvData->lock_mmd); + /* KERNEL_MODE*/ -#else +#else /* USER SPACE APPLICATION */ PrvData = (ethsw_api_dev_t *)malloc(sizeof(ethsw_api_dev_t)); - cdev=(void *)PrvData; + cdev = (void *)PrvData; + if (!PrvData) { pr_err("%s:%s:%d (memory allocation failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return PrvData; } + memset(PrvData, 0, sizeof(ethsw_api_dev_t)); /* USER SPACE APPLICATION */ -#endif +#endif + + /** Initialize Switch Core Function Pointer */ + gsw_init_fn_ptrs(&PrvData->ops); PrvData->raldev = ethcinit->ecdev; ecoredev[ethcinit->sdev] = PrvData; @@ -2654,7 +3091,7 @@ void *ethsw_api_core_init(ethsw_core_init_t *ethcinit) PrvData->matimer = DEFAULT_AGING_TIMEOUT; /** Switch Core Base Address */ PrvData->gsw_base = ethcinit->gsw_base_addr; - printk("Switch Core Base Address = 0x%08x\n",(unsigned int)PrvData->gsw_base); + printk("Switch Core Base Address = 0x%08x\n", (unsigned int)PrvData->gsw_base); /** Get Switch Hardware capablity */ get_gsw_hw_cap(cdev); @@ -2666,12 +3103,17 @@ void *ethsw_api_core_init(ethsw_core_init_t *ethcinit) /** TFlow Table Init */ pce_table_init(&PrvData->phandler); - + /** Parser Micro Code Init */ +#if defined(CONFIG_USE_EMULATOR) + gsw_w32(cdev, PCE_GCTRL_0_MC_VALID_OFFSET, + PCE_GCTRL_0_MC_VALID_SHIFT, PCE_GCTRL_0_MC_VALID_SIZE, 0x1); +#else gsw_pmicro_code_init(cdev); printk("Switch API: PCE MicroCode loaded !!\n"); +#endif - if (PrvData->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(PrvData->gipver)) switch_core_init(cdev); else legacy_switch_core_init(cdev); @@ -2690,13 +3132,16 @@ void gsw_corecleanup(void) { u8 i; ethsw_api_dev_t *cdev; + for (i = 0; i < LTQ_FLOW_DEV_MAX; i++) { cdev = (ethsw_api_dev_t *)ecoredev[i]; + if (cdev) { -#if defined(KERNEL_MODE) && KERNEL_MODE - kfree(cdev); + GSW_Irq_deinit(cdev); +#ifdef __KERNEL__ + kfree(cdev); #else - free(cdev); + free(cdev); #endif cdev = NULL; } @@ -2705,28 +3150,106 @@ void gsw_corecleanup(void) GSW_return_t GSW_MAC_TableClear(void *cdev) { + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + /* Flush all entries from the MAC table */ gsw_w32(cdev, PCE_GCTRL_0_MTFL_OFFSET, PCE_GCTRL_0_MTFL_SHIFT, PCE_GCTRL_0_MTFL_SIZE, 1); - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} + + +static int conv_id(unsigned short val) +{ + static int templ[16] = { + -1, 0, 1, -2, + 2, -2, -2, -2, + 3, -2, -2, -2, + -2, -2, -2, -2 + }; + + int result, r; + int i; + + result = -1; + + for (i = 0; val != 0 && i < 4; i++, val >>= 4) { + if ((val & 0x0F) == 0) + continue; + + r = templ[val & 0x0F]; + + if (r < 0 || result >= 0) + return -1; + + result = r + i * 4; + } + + return result; +} + +static int conv_id_array(unsigned short *pval, unsigned int size) +{ + int result, r; + unsigned int i; + + result = -1; + + for (i = 0; i < size; i++) { + if (pval[i] == 0) + continue; + + r = conv_id(pval[i]); + + if (r < 0 || result >= 0) + return -1; + + result = r + i * 16; + } + + return result; } GSW_return_t GSW_MAC_TableEntryAdd(void *cdev, - GSW_MAC_tableAdd_t *parm) + GSW_MAC_tableAdd_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((parm->nPortId >= gswdev->tpnum) && - (!(parm->nPortId & 0x80000000))) - return GSW_statusErr; + (!(parm->nPortId & 0x80000000))) + ret = GSW_statusErr; + + goto UNLOCK_AND_RETURN; } - + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_MAC_BRIDGE_INDEX; tbl_prog.key[0] = parm->nMAC[4] << 8 | parm->nMAC[5]; @@ -2736,216 +3259,292 @@ GSW_return_t GSW_MAC_TableEntryAdd(void *cdev, if (gswdev->gipver == LTQ_GSWIP_2_2_ETC) tbl_prog.val[1] = ((parm->nSubIfId & 0xFFF) << 4); + /* tbl_prog.val[1] = ((parm->nSVLAN_Id & 0xFFF) << 4); */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_30_31(gswdev->gipver)) tbl_prog.val[1] = ((parm->nSubIfId & 0x1FFF) << 3); - + /*To configure PCE_TBL_CTRL VLD 12th BIT*/ tbl_prog.valid = 1; tbl_prog.val[1] |= (1 << 1); /* Valid Entry */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { /*Enable source address filter*/ - if(parm->nFilterFlag & 0x1) + if (parm->nFilterFlag & 0x1) tbl_prog.key[3] |= (1 << 8); + /*Enable destination address filter*/ - if(parm->nFilterFlag & 0x2) + if (parm->nFilterFlag & 0x2) tbl_prog.key[3] |= (1 << 9); - //Govind - Is it not mandatory to enable 'static' flag and it's action? } if (parm->bStaticEntry) { /*static entry*/ /*Enable static entry flag */ tbl_prog.val[1] |= 1; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { /*set igmp control flag*/ if (parm->bIgmpControlled) { tbl_prog.val[0] |= (1 << 2); //Govind - Is the DMAC matched will go to below Port-Map or? } + /*Set Bridge Port Map*/ - tbl_prog.val[2] = parm->nPortMap[0]; - tbl_prog.val[3] = parm->nPortMap[1]; - tbl_prog.val[4] = parm->nPortMap[2]; - tbl_prog.val[5] = parm->nPortMap[3]; - tbl_prog.val[6] = parm->nPortMap[4]; - tbl_prog.val[7] = parm->nPortMap[5]; - tbl_prog.val[8] = parm->nPortMap[6]; - tbl_prog.val[9] = parm->nPortMap[7]; - tbl_prog.val[10] = parm->nPortMap[8]; - tbl_prog.val[11] = parm->nPortMap[9]; - tbl_prog.val[12] = parm->nPortMap[10]; - tbl_prog.val[13] = parm->nPortMap[11]; - tbl_prog.val[14] = parm->nPortMap[12]; - tbl_prog.val[15] = parm->nPortMap[13]; - tbl_prog.val[16] = parm->nPortMap[14]; - tbl_prog.val[17] = parm->nPortMap[15]; + if (parm->nPortId & 0x80000000) { + tbl_prog.val[2] = parm->nPortMap[0]; + tbl_prog.val[3] = parm->nPortMap[1]; + tbl_prog.val[4] = parm->nPortMap[2]; + tbl_prog.val[5] = parm->nPortMap[3]; + tbl_prog.val[6] = parm->nPortMap[4]; + tbl_prog.val[7] = parm->nPortMap[5]; + tbl_prog.val[8] = parm->nPortMap[6]; + tbl_prog.val[9] = parm->nPortMap[7]; + tbl_prog.val[10] = parm->nPortMap[8]; + tbl_prog.val[11] = parm->nPortMap[9]; + tbl_prog.val[12] = parm->nPortMap[10]; + tbl_prog.val[13] = parm->nPortMap[11]; + tbl_prog.val[14] = parm->nPortMap[12]; + tbl_prog.val[15] = parm->nPortMap[13]; + tbl_prog.val[16] = parm->nPortMap[14]; + tbl_prog.val[17] = parm->nPortMap[15]; + } else { + u32 i, j; + + i = parm->nPortId / (sizeof(tbl_prog.val[0]) * 8); + j = parm->nPortId & (sizeof(tbl_prog.val[0]) * 8 - 1); + tbl_prog.val[i + 2] = 1 << j; + } } else { if (parm->nPortId & 0x80000000) { /*Port Map 3.0 */ - tbl_prog.val[0] = (parm->nPortId & 0x7FFF); + if (parm->nPortMap[0]) + tbl_prog.val[0] = parm->nPortMap[0]; + else + tbl_prog.val[0] = (parm->nPortId & 0x7FFF); } else { tbl_prog.val[0] = (1 << parm->nPortId); } } + } else { /*Dynamic Entry*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { tbl_prog.val[0] = (parm->nAgeTimer & 0xF); - /*Set Bridge Port Member val 0 to 7 bits*/ + /*Set Bridge Port Member val 0 to 7 bits*/ tbl_prog.val[2] = (parm->nPortId & 0xFF); } else { tbl_prog.val[0] = (((parm->nPortId & 0xF) << 4) - | (parm->nAgeTimer & 0xF)); + | (parm->nAgeTimer & 0xF)); } } + gsw_pce_table_key_write(cdev, &tbl_prog); -#if 0 - /* To ensure MAC is updated in the table */ - memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); - tbl_prog.table = PCE_MAC_BRIDGE_INDEX; - tbl_prog.key[0] = parm->nMAC[4] << 8 | parm->nMAC[5]; - tbl_prog.key[1] = parm->nMAC[2] << 8 | parm->nMAC[3]; - tbl_prog.key[2] = parm->nMAC[0] << 8 | parm->nMAC[1]; - tbl_prog.key[3] = parm->nFId; - gsw_pce_table_key_read(cdev, &tbl_prog); - if (tbl_prog.valid != 1) - pr_err("(MAC Table is full) %s:%s:%d\n", - __FILE__, __func__, __LINE__); + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); #endif - return GSW_statusOk; + return ret; + } GSW_return_t GSW_MAC_TableEntryRead(void *cdev, - GSW_MAC_tableRead_t *parm) + GSW_MAC_tableRead_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t tbl_prog; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); + if (parm->bInitial == 1) { gswdev->mac_rd_index = 0; /*Start from the index 0 */ parm->bInitial = 0; } + if (gswdev->mac_rd_index >= gswdev->mactblsize) { memset(parm, 0, sizeof(GSW_MAC_tableRead_t)); parm->bLast = 1; gswdev->mac_rd_index = 0; - return 0; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } + tbl_prog.table = PCE_MAC_BRIDGE_INDEX; + do { tbl_prog.pcindex = gswdev->mac_rd_index; gsw_pce_table_read(cdev, &tbl_prog); gswdev->mac_rd_index++; + if (tbl_prog.valid != 0) break; } while (gswdev->mac_rd_index < gswdev->mactblsize); + if (tbl_prog.valid == 1) { /*get FID*/ parm->nFId = tbl_prog.key[3] & 0x3F; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { /*source address filter flag*/ if (tbl_prog.key[3] & 0x100) parm->nFilterFlag = parm->nFilterFlag | 0x1; + /*destination address filter flag*/ if (tbl_prog.key[3] & 0x200) - parm->nFilterFlag = parm->nFilterFlag | 0x2; + parm->nFilterFlag = parm->nFilterFlag | 0x2; } + /*static flag*/ parm->bStaticEntry = (tbl_prog.val[1] & 0x1); + if (parm->bStaticEntry == 1) { /*Static Entry*/ parm->nAgeTimer = 0; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { + int id; + /*get igmp control flag*/ - if(tbl_prog.val[0] & 0x4) { - parm->bIgmpControlled=1; + if (tbl_prog.val[0] & 0x4) { + parm->bIgmpControlled = 1; } - /*Get Bridge Port Map*/ - parm->nPortMap[0]=tbl_prog.val[2]; - parm->nPortMap[1]=tbl_prog.val[3]; - parm->nPortMap[2]=tbl_prog.val[4]; - parm->nPortMap[3]=tbl_prog.val[5]; - parm->nPortMap[4]=tbl_prog.val[6]; - parm->nPortMap[5]=tbl_prog.val[7]; - parm->nPortMap[6]=tbl_prog.val[8]; - parm->nPortMap[7]=tbl_prog.val[9]; - parm->nPortMap[8]=tbl_prog.val[10]; - parm->nPortMap[9]=tbl_prog.val[11]; - parm->nPortMap[10]=tbl_prog.val[12]; - parm->nPortMap[11]=tbl_prog.val[13]; - parm->nPortMap[12]=tbl_prog.val[14]; - parm->nPortMap[13]=tbl_prog.val[15]; - parm->nPortMap[14]=tbl_prog.val[16]; - parm->nPortMap[15]=tbl_prog.val[17]; + + /*Get Bridge Port Map*/ + parm->nPortMap[0] = tbl_prog.val[2]; + parm->nPortMap[1] = tbl_prog.val[3]; + parm->nPortMap[2] = tbl_prog.val[4]; + parm->nPortMap[3] = tbl_prog.val[5]; + parm->nPortMap[4] = tbl_prog.val[6]; + parm->nPortMap[5] = tbl_prog.val[7]; + parm->nPortMap[6] = tbl_prog.val[8]; + parm->nPortMap[7] = tbl_prog.val[9]; + parm->nPortMap[8] = tbl_prog.val[10]; + parm->nPortMap[9] = tbl_prog.val[11]; + parm->nPortMap[10] = tbl_prog.val[12]; + parm->nPortMap[11] = tbl_prog.val[13]; + parm->nPortMap[12] = tbl_prog.val[14]; + parm->nPortMap[13] = tbl_prog.val[15]; + parm->nPortMap[14] = tbl_prog.val[16]; + parm->nPortMap[15] = tbl_prog.val[17]; + + + id = conv_id_array(&tbl_prog.val[2], 16); + + if (id < 0) + parm->nPortId = 0x80000000; + else + parm->nPortId = (u32)id; } else { - parm->nPortId = tbl_prog.val[0]; + + int id = conv_id(tbl_prog.val[0]); + + if (id < 0) + parm->nPortId = (u32)tbl_prog.val[0] | 0x80000000; + else + parm->nPortId = (u32)id; } + } else { /*Dynamic Entry*/ u32 mant, timer = 300; /* Aging Counter Mantissa Value */ gsw_r32(cdev, PCE_AGE_1_MANT_OFFSET, PCE_AGE_1_MANT_SHIFT, PCE_AGE_1_MANT_SIZE, &mant); + switch (mant) { case AGETIMER_1_DAY: timer = 86400; break; + case AGETIMER_1_HOUR: timer = 3600; break; + case AGETIMER_300_SEC: timer = 300; break; + case AGETIMER_10_SEC: timer = 10; break; + case AGETIMER_1_SEC: timer = 1; break; } + parm->nAgeTimer = tbl_prog.val[0] & 0xF; - parm->nAgeTimer = (timer * parm->nAgeTimer)/0xF; - if (gswdev->gipver == LTQ_GSWIP_3_1) { - /*Set Bridge Port Member val 0 to 7 bits*/ + parm->nAgeTimer = (timer * parm->nAgeTimer) / 0xF; + + if (IS_VRSN_31(gswdev->gipver)) { + /*Set Bridge Port Member val 0 to 7 bits*/ parm->nPortId = (tbl_prog.val[2] & 0xFF); - } else { + /*Changed + 0: the entry is not changed + 1: the entry is changed and not accessed yet */ + parm->bEntryChanged = ((tbl_prog.val[0] >> 8) & 0x1); + } else { parm->nPortId = (tbl_prog.val[0] >> 4) & 0xF; } } + parm->nMAC[0] = tbl_prog.key[2] >> 8; parm->nMAC[1] = tbl_prog.key[2] & 0xFF; parm->nMAC[2] = tbl_prog.key[1] >> 8; parm->nMAC[3] = tbl_prog.key[1] & 0xFF; parm->nMAC[4] = tbl_prog.key[0] >> 8; parm->nMAC[5] = tbl_prog.key[0] & 0xFF; - + if (gswdev->gipver == LTQ_GSWIP_2_2_ETC) parm->nSubIfId = (tbl_prog.val[1] >> 4 & 0xFFF); + /* parm->nSVLAN_Id = (tbl_prog.val[1] >> 4 & 0xFFF); */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_30_31(gswdev->gipver)) parm->nSubIfId = (tbl_prog.val[1] >> 3 & 0x1FFF); - + parm->bInitial = 0; parm->bLast = 0; } else { memset(parm, 0, sizeof(GSW_MAC_tableRead_t)); parm->bLast = 1; } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_MAC_TableEntryQuery(void *cdev, - GSW_MAC_tableQuery_t *parm) + GSW_MAC_tableQuery_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t tbl_prog; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + parm->bFound = 0; memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_MAC_BRIDGE_INDEX; @@ -2953,50 +3552,68 @@ GSW_return_t GSW_MAC_TableEntryQuery(void *cdev, tbl_prog.key[1] = parm->nMAC[2] << 8 | parm->nMAC[3]; tbl_prog.key[2] = parm->nMAC[0] << 8 | parm->nMAC[1]; tbl_prog.key[3] = parm->nFId; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { /*source address filter key*/ - if(parm->nFilterFlag & 0x1) { + if (parm->nFilterFlag & 0x1) { tbl_prog.key[3] |= (1 << 8); } + /*destination address filter key*/ - if(parm->nFilterFlag & 0x2) { + if (parm->nFilterFlag & 0x2) { tbl_prog.key[3] |= (1 << 9); } } gsw_pce_table_key_read(cdev, &tbl_prog); + if (tbl_prog.valid == 1) { parm->bFound = 1; parm->bStaticEntry = (tbl_prog.val[1] & 0x1); parm->nSubIfId = ((tbl_prog.val[1] >> 3) & 0x1FFF); - if (parm->bStaticEntry == 1) { parm->nAgeTimer = 0; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { + int id; + /*get igmp control flag*/ - if(tbl_prog.val[0] & 0x4) { - parm->bIgmpControlled=1; + if (tbl_prog.val[0] & 0x4) { + parm->bIgmpControlled = 1; } - /*Get Bridge Port Map*/ - parm->nPortMap[0]=tbl_prog.val[2]; - parm->nPortMap[1]=tbl_prog.val[3]; - parm->nPortMap[2]=tbl_prog.val[4]; - parm->nPortMap[3]=tbl_prog.val[5]; - parm->nPortMap[4]=tbl_prog.val[6]; - parm->nPortMap[5]=tbl_prog.val[7]; - parm->nPortMap[6]=tbl_prog.val[8]; - parm->nPortMap[7]=tbl_prog.val[9]; - parm->nPortMap[8]=tbl_prog.val[10]; - parm->nPortMap[9]=tbl_prog.val[11]; - parm->nPortMap[10]=tbl_prog.val[12]; - parm->nPortMap[11]=tbl_prog.val[13]; - parm->nPortMap[12]=tbl_prog.val[14]; - parm->nPortMap[13]=tbl_prog.val[15]; - parm->nPortMap[14]=tbl_prog.val[16]; - parm->nPortMap[15]=tbl_prog.val[17]; + + /*Get Bridge Port Map*/ + parm->nPortMap[0] = tbl_prog.val[2]; + parm->nPortMap[1] = tbl_prog.val[3]; + parm->nPortMap[2] = tbl_prog.val[4]; + parm->nPortMap[3] = tbl_prog.val[5]; + parm->nPortMap[4] = tbl_prog.val[6]; + parm->nPortMap[5] = tbl_prog.val[7]; + parm->nPortMap[6] = tbl_prog.val[8]; + parm->nPortMap[7] = tbl_prog.val[9]; + parm->nPortMap[8] = tbl_prog.val[10]; + parm->nPortMap[9] = tbl_prog.val[11]; + parm->nPortMap[10] = tbl_prog.val[12]; + parm->nPortMap[11] = tbl_prog.val[13]; + parm->nPortMap[12] = tbl_prog.val[14]; + parm->nPortMap[13] = tbl_prog.val[15]; + parm->nPortMap[14] = tbl_prog.val[16]; + parm->nPortMap[15] = tbl_prog.val[17]; + + id = conv_id_array(&tbl_prog.val[2], 16); + + if (id < 0) + parm->nPortId = 0x80000000; + else + parm->nPortId = (u32)id; } else { - parm->nPortId = tbl_prog.val[0]; + int id = conv_id(tbl_prog.val[0]); + + if (id < 0) + parm->nPortId = (u32)tbl_prog.val[0] | 0x80000000; + else + parm->nPortId = (u32)id; } } else { u32 mant, timer = 300; @@ -3004,50 +3621,76 @@ GSW_return_t GSW_MAC_TableEntryQuery(void *cdev, gsw_r32(cdev, PCE_AGE_1_MANT_OFFSET, PCE_AGE_1_MANT_SHIFT, PCE_AGE_1_MANT_SIZE, &mant); + switch (mant) { case AGETIMER_1_DAY: timer = 86400; break; + case AGETIMER_1_HOUR: timer = 3600; break; + case AGETIMER_300_SEC: timer = 300; break; + case AGETIMER_10_SEC: timer = 10; break; + case AGETIMER_1_SEC: timer = 1; break; } + parm->nAgeTimer = tbl_prog.val[0] & 0xF; - parm->nAgeTimer = (timer * parm->nAgeTimer)/0xF; - if (gswdev->gipver == LTQ_GSWIP_3_1) { - /*Set Bridge Port Member val 0 to 7 bits*/ + parm->nAgeTimer = (timer * parm->nAgeTimer) / 0xF; + + if (IS_VRSN_31(gswdev->gipver)) { + /*Set Bridge Port Member val 0 to 7 bits*/ parm->nPortId = (tbl_prog.val[2] & 0xFF); - } else { + + /*Changed + 0: the entry is not changed + 1: the entry is changed and not accessed yet */ + parm->bEntryChanged = ((tbl_prog.val[0] >> 8) & 0x1); + } else { parm->nPortId = (tbl_prog.val[0] >> 4) & 0xF; } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_MAC_TableEntryRemove(void *cdev, - GSW_MAC_tableRemove_t *parm) + GSW_MAC_tableRemove_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t tbl_prog; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /* MAC table flushing control bit */ gsw_r32(cdev, PCE_GCTRL_0_MTFL_OFFSET, PCE_GCTRL_0_MTFL_SHIFT, PCE_GCTRL_0_MTFL_SIZE, &value); + /* If value is 1, flush all entries from the MAC table in process */ if (!value) { memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); @@ -3056,7 +3699,21 @@ GSW_return_t GSW_MAC_TableEntryRemove(void *cdev, tbl_prog.key[1] = parm->nMAC[2] << 8 | parm->nMAC[3]; tbl_prog.key[2] = parm->nMAC[0] << 8 | parm->nMAC[1]; tbl_prog.key[3] = parm->nFId; + + if (IS_VRSN_31(gswdev->gipver)) { + /*source address filter key*/ + if (parm->nFilterFlag & 0x1) { + tbl_prog.key[3] |= (1 << 8); + } + + /*destination address filter key*/ + if (parm->nFilterFlag & 0x2) { + tbl_prog.key[3] |= (1 << 9); + } + } + gsw_pce_table_key_read(cdev, &tbl_prog); + if (tbl_prog.valid == 1) { pctbl_prog_t tbl_cl_prog; memset(&tbl_cl_prog, 0, sizeof(pctbl_prog_t)); @@ -3065,7 +3722,13 @@ GSW_return_t GSW_MAC_TableEntryRemove(void *cdev, gsw_pce_table_write(cdev, &tbl_cl_prog); } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) @@ -3073,22 +3736,32 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; u32 value, monrx = 0, montx = 0, PEN, EN; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } + /* See if PORT enable or not */ gsw_r32(cdev, (SDMA_PCTRL_PEN_OFFSET + (0x6 * pidx)), SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, &PEN); gsw_r32(cdev, (FDMA_PCTRL_EN_OFFSET + (0x6 * pidx)), FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, &EN); + /* Port Enable feature only support 6 port */ - if (pidx >= gswdev->pnum) { + if (pidx >= gswdev->pnum) { parm->eEnable = 1; } else { if ((PEN == 1) && (EN == 1)) @@ -3100,6 +3773,7 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) else parm->eEnable = GSW_PORT_DISABLE; } + /* Learning Limit */ gsw_r32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pidx)), PCE_PCTRL_1_LRNLIM_SHIFT, @@ -3118,8 +3792,8 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) parm->bAging = value; if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { /** MAC address table learning on the port specified. */ gsw_r32(cdev, (PCE_PCTRL_3_LNDIS_OFFSET + (0xA * pidx)), PCE_PCTRL_3_LNDIS_SHIFT, @@ -3129,19 +3803,23 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_0_SPFDIS_SHIFT, PCE_PCTRL_0_SPFDIS_SIZE, &parm->bMAC_SpoofingDetection); } + /* UnicastUnknownDrop */ gsw_r32(cdev, PCE_PMAP_3_UUCMAP_OFFSET, PCE_PMAP_3_UUCMAP_SHIFT, PCE_PMAP_3_UUCMAP_SIZE, &value); + /* UnicastUnknownDrop feature support */ if ((value & (1 << pidx)) == 0) parm->bUnicastUnknownDrop = 1; else parm->bUnicastUnknownDrop = 0; + /* MulticastUnknownDrop */ gsw_r32(cdev, PCE_PMAP_2_DMCPMAP_OFFSET, PCE_PMAP_2_DMCPMAP_SHIFT, PCE_PMAP_2_DMCPMAP_SIZE, &value); + /* MulticastUnknownDrop feature support */ if ((value & (1 << pidx)) == 0) { parm->bMulticastUnknownDrop = 1; @@ -3150,6 +3828,7 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) parm->bMulticastUnknownDrop = 0; parm->bBroadcastDrop = 0; } + /* Require to check later - 3M */ parm->bReservedPacketDrop = 0; /* Port Monitor */ @@ -3159,6 +3838,7 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) gsw_r32(cdev, (PCE_PCTRL_3_TXMIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_TXMIR_SHIFT, PCE_PCTRL_3_TXMIR_SIZE, &montx); + if ((monrx == 1) && (montx == 1)) parm->ePortMonitor = GSW_PORT_MONITOR_RXTX; else if ((monrx == 1) && (montx == 0)) @@ -3171,50 +3851,59 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) gsw_r32(cdev, (PCE_PCTRL_3_VIO_2_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_2_SHIFT, PCE_PCTRL_3_VIO_2_SIZE, &monrx); + if (monrx == 1) parm->ePortMonitor |= GSW_PORT_MONITOR_VLAN_UNKNOWN; gsw_r32(cdev, (PCE_PCTRL_3_VIO_4_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_4_SHIFT, PCE_PCTRL_3_VIO_4_SIZE, &monrx); + if (monrx == 1) parm->ePortMonitor |= GSW_PORT_MONITOR_VLAN_MEMBERSHIP; gsw_r32(cdev, (PCE_PCTRL_3_VIO_5_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_5_SHIFT, PCE_PCTRL_3_VIO_5_SIZE, &monrx); + if (monrx == 1) parm->ePortMonitor |= GSW_PORT_MONITOR_PORT_STATE; gsw_r32(cdev, (PCE_PCTRL_3_VIO_6_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_6_SHIFT, PCE_PCTRL_3_VIO_6_SIZE, &monrx); + if (monrx == 1) parm->ePortMonitor |= GSW_PORT_MONITOR_LEARNING_LIMIT; - gsw_r32(cdev, (PCE_PCTRL_3_VIO_7_OFFSET + (0xA * pidx)), + gsw_r32(cdev, (PCE_PCTRL_3_VIO_7_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_7_SHIFT, PCE_PCTRL_3_VIO_7_SIZE, &monrx); + if (monrx == 1) parm->ePortMonitor |= GSW_PORT_MONITOR_PORT_LOCK; + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (BM_RMON_CTRL_IFRMONFST_OFFSET + (0x2 * pidx)), BM_RMON_CTRL_IFRMONFST_SHIFT, BM_RMON_CTRL_IFRMONFST_SIZE, &parm->nIfCountStartIdx); + if (parm->nIfCountStartIdx) parm->bIfCounters = 1; + gsw_r32(cdev, (BM_RMON_CTRL_IFRMONMD_OFFSET + (0x2 * pidx)), BM_RMON_CTRL_IFRMONMD_SHIFT, BM_RMON_CTRL_IFRMONMD_SIZE, &parm->eIfRMONmode); + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if (parm->nPortId == 15) { -/* pr_err("%s:%s:%d",__FILE__, __func__, __LINE__);*/ + /* pr_err("%s:%s:%d",__FILE__, __func__, __LINE__);*/ gsw_r32(cdev, MAC_PSTAT_TXPAUEN_OFFSET, MAC_PSTAT_TXPAUEN_SHIFT, 2, &value); } } else { - if ((parm->nPortId |= 0 ) && (parm->nPortId < (gswdev->pnum - 1))) { - gsw_r32(cdev, (MAC_PSTAT_TXPAUEN_OFFSET + (0xC * (parm->nPortId - 1 ))), + if ((parm->nPortId |= 0) && (parm->nPortId < (gswdev->pnum - 1))) { + gsw_r32(cdev, (MAC_PSTAT_TXPAUEN_OFFSET + (0xC * (parm->nPortId - 1))), MAC_PSTAT_TXPAUEN_SHIFT, 2, &value); } } @@ -3223,42 +3912,57 @@ GSW_return_t GSW_PortCfgGet(void *cdev, GSW_portCfg_t *parm) MAC_PSTAT_TXPAUEN_SHIFT, 2, &value); } - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC /* MAC API's to get flow control */ - if(parm->ePortType == GSW_PHYSICAL_PORT || - parm->ePortType == GSW_LOGICAL_PORT) { + if (parm->ePortType == GSW_PHYSICAL_PORT || + parm->ePortType == GSW_LOGICAL_PORT) { struct mac_ops *ops = get_mac_ops(gswdev, parm->nPortId); - if(!ops) - { - pr_err("MAC %d is not initialized\n",parm->nPortId); - return GSW_statusErr; + + if (!ops) { + pr_err("MAC %d is not initialized\n", parm->nPortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + parm->eFlowCtrl = ops->get_flow_ctl(ops); - } - else - pr_err("MAC configuration is not valid for CTP or Bridge Port %d \n",parm->nPortId); - - } - else { + } else + pr_err("MAC configuration is not valid for CTP or Bridge Port %d \n", parm->nPortId); + +#endif + } else { switch (value) { case 0: - parm->eFlowCtrl = GSW_FLOW_OFF; + parm->eFlowCtrl = GSW_FLOW_OFF; break; + case 1: - parm->eFlowCtrl = GSW_FLOW_TX; + parm->eFlowCtrl = GSW_FLOW_TX; break; + case 3: - parm->eFlowCtrl = GSW_FLOW_RXTX; + parm->eFlowCtrl = GSW_FLOW_RXTX; break; + case 2: - parm->eFlowCtrl = GSW_FLOW_RX; + parm->eFlowCtrl = GSW_FLOW_RX; break; + default: parm->eFlowCtrl = GSW_FLOW_AUTO; } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) @@ -3267,33 +3971,44 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) u8 pidx = parm->nPortId; u32 paddr; u32 value, EN, PEN, PACT; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /* Port locking flag */ gsw_w32(cdev, (PCE_PCTRL_0_PLOCK_OFFSET + (0xA * pidx)), PCE_PCTRL_0_PLOCK_SHIFT, PCE_PCTRL_0_PLOCK_SIZE, parm->bLearningMAC_PortLock); } + /* Learning Limit Action */ - if (parm->nLearningLimit == 0xFFFF) + if (parm->nLearningLimit == 0xFFFF) value = 0xFF; else value = parm->nLearningLimit; + gswdev->pconfig[parm->nPortId].llimit = value; /* Learning Limit */ gsw_w32(cdev, (PCE_PCTRL_1_LRNLIM_OFFSET + (0xA * pidx)), PCE_PCTRL_1_LRNLIM_SHIFT, PCE_PCTRL_1_LRNLIM_SIZE, value); + if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { /** MAC address table learning on the port specified */ gsw_w32(cdev, (PCE_PCTRL_3_LNDIS_OFFSET + (0xA * pidx)), PCE_PCTRL_3_LNDIS_SHIFT, @@ -3303,20 +4018,23 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_0_SPFDIS_SHIFT, PCE_PCTRL_0_SPFDIS_SIZE, parm->bMAC_SpoofingDetection); } + /* Aging */ //Govind- aging dis/en is not in 3.1? gsw_w32(cdev, PCE_PCTRL_0_AGEDIS_OFFSET + (0xA * pidx), PCE_PCTRL_0_AGEDIS_SHIFT, PCE_PCTRL_0_AGEDIS_SIZE, parm->bAging); - if(gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { /* UnicastUnknownDrop Read first */ gsw_r32(cdev, PCE_PMAP_3_UUCMAP_OFFSET, PCE_PMAP_3_UUCMAP_SHIFT, PCE_PMAP_3_UUCMAP_SIZE, &value); + if (parm->bUnicastUnknownDrop == 1) value &= ~(1 << pidx); else value |= 1 << pidx; + /* UnicastUnknownDrop write back */ gsw_w32(cdev, PCE_PMAP_3_UUCMAP_OFFSET, PCE_PMAP_3_UUCMAP_SHIFT, @@ -3326,17 +4044,19 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) gsw_r32(cdev, PCE_PMAP_2_DMCPMAP_OFFSET, PCE_PMAP_2_DMCPMAP_SHIFT, PCE_PMAP_2_DMCPMAP_SIZE, &value); + if (parm->bMulticastUnknownDrop == 1) value &= ~(1 << pidx); else value |= 1 << pidx; + /* MulticastUnknownDrop */ gsw_w32(cdev, PCE_PMAP_2_DMCPMAP_OFFSET, PCE_PMAP_2_DMCPMAP_SHIFT, PCE_PMAP_2_DMCPMAP_SIZE, value); } - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { /* Flow Control */ if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((pidx == 0 /*GSW_3X_SOC_CPU_PORT*/)) { @@ -3350,31 +4070,31 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) gsw_r32(cdev, (GSWT_MDIO_STAT_1_PACT_OFFSET + GSW30_TOP_OFFSET), GSWT_MDIO_STAT_1_PACT_SHIFT, GSWT_MDIO_STAT_1_PACT_SIZE, &PACT); gsw_r32(cdev, (GSWT_PHY_ADDR_1_ADDR_OFFSET + GSW30_TOP_OFFSET), - GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &paddr); + GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &paddr); } else { PEN = 0; PACT = 0; } } else { - if (pidx < gswdev->pnum ) { + if (pidx < gswdev->pnum) { gsw_r32(cdev, (GSWT_MDCCFG_0_PEN_0_OFFSET + GSW30_TOP_OFFSET), (GSWT_MDCCFG_0_PEN_0_SHIFT + pidx), GSWT_MDCCFG_0_PEN_0_SIZE, &PEN); gsw_r32(cdev, ((GSWT_MDIO_STAT_1_PACT_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_MDIO_STAT_1_PACT_SHIFT, GSWT_MDIO_STAT_1_PACT_SIZE, &PACT); gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((parm->nPortId - 1) * 4)) + GSW30_TOP_OFFSET), - GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &paddr); - } else { - PEN = 0; - PACT = 0; - } + GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &paddr); + } else { + PEN = 0; + PACT = 0; } } + } } else { - if (pidx < gswdev->pnum ) { + if (pidx < gswdev->pnum) { gsw_r32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), - (MDC_CFG_0_PEN_0_SHIFT + pidx), MDC_CFG_0_PEN_0_SIZE, &PEN); + (MDC_CFG_0_PEN_0_SHIFT + pidx), MDC_CFG_0_PEN_0_SIZE, &PEN); gsw_r32(cdev, (MDIO_STAT_0_PACT_OFFSET + GSW_TREG_OFFSET + pidx), - MDIO_STAT_0_PACT_SHIFT, MDIO_STAT_0_PACT_SIZE, &PACT); + MDIO_STAT_0_PACT_SHIFT, MDIO_STAT_0_PACT_SIZE, &PACT); gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, PHY_ADDR_0_ADDR_SIZE, &paddr); } else { @@ -3382,15 +4102,15 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PACT = 0; } } - } - else { + } else { PEN = 0; - PACT = 0; + PACT = 0; } + /* PHY polling statemachine (of the MAC) is activated and */ /* an external PHY reacts on the MDIO accesses. */ /* Therefore update the MDIO register of the attached PHY.*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if ((PEN == 1) && (PACT == 1)) { GSW_MDIO_data_t mddata; /* Write directly to MDIO register */ @@ -3398,20 +4118,25 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) mddata.nAddressReg = 0x4; GSW_MDIO_DataRead(cdev, &mddata); mddata.nData &= ~(0xC00); + switch (parm->eFlowCtrl) { case GSW_FLOW_OFF: break; + case GSW_FLOW_TX: mddata.nData |= 0x800; break; + case GSW_FLOW_RXTX: mddata.nData |= 0x400; break; + case GSW_FLOW_RX: case GSW_FLOW_AUTO: mddata.nData |= 0xC00; break; } + GSW_MDIO_DataWrite(cdev, &mddata); /* Restart Auto negotiation */ mddata.nAddressReg = 0x0; @@ -3420,21 +4145,31 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) GSW_MDIO_DataWrite(cdev, &mddata); } else { u32 RX = 0, TX = 0; + switch (parm->eFlowCtrl) { case GSW_FLOW_OFF: - RX = 3; TX = 3; + RX = 3; + TX = 3; break; + case GSW_FLOW_TX: - RX = 3; TX = 2; + RX = 3; + TX = 2; break; + case GSW_FLOW_RXTX: - RX = 2; TX = 2; + RX = 2; + TX = 2; break; + case GSW_FLOW_RX: - RX = 2; TX = 3; + RX = 2; + TX = 3; break; + case GSW_FLOW_AUTO: - RX = 0; TX = 0; + RX = 0; + TX = 0; break; } @@ -3444,14 +4179,14 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) if (pidx == 15) { gsw_w32(cdev, MAC_CTRL_0_FCON_OFFSET, MAC_CTRL_0_FCON_SHIFT, MAC_CTRL_0_FCON_SIZE, parm->eFlowCtrl); - gsw_w32(cdev, (GSWT_PHY_ADDR_1_FCONTX_OFFSET+ GSW30_TOP_OFFSET), + gsw_w32(cdev, (GSWT_PHY_ADDR_1_FCONTX_OFFSET + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_FCONTX_SHIFT, GSWT_PHY_ADDR_1_FCONTX_SIZE, TX); gsw_w32(cdev, (GSWT_PHY_ADDR_1_FCONRX_OFFSET + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_FCONRX_SHIFT, GSWT_PHY_ADDR_1_FCONRX_SIZE, RX); } } else { - if (pidx < gswdev->pnum ) { - gsw_w32(cdev, (MAC_CTRL_0_FCON_OFFSET + (0xC * (pidx-1))), + if (pidx < gswdev->pnum) { + gsw_w32(cdev, (MAC_CTRL_0_FCON_OFFSET + (0xC * (pidx - 1))), MAC_CTRL_0_FCON_SHIFT, MAC_CTRL_0_FCON_SIZE, parm->eFlowCtrl); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_FCONTX_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_FCONTX_SHIFT, GSWT_PHY_ADDR_1_FCONTX_SIZE, TX); @@ -3461,11 +4196,11 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) } } } else { - if (pidx < gswdev->pnum ) { + if (pidx < gswdev->pnum) { gsw_w32(cdev, (MAC_CTRL_0_FCON_OFFSET + (0xC * pidx)), MAC_CTRL_0_FCON_SHIFT, MAC_CTRL_0_FCON_SIZE, parm->eFlowCtrl); gsw_w32(cdev, (PHY_ADDR_0_FCONTX_OFFSET - (0x1 * pidx)), - PHY_ADDR_0_FCONTX_SHIFT, PHY_ADDR_0_FCONTX_SIZE , TX); + PHY_ADDR_0_FCONTX_SHIFT, PHY_ADDR_0_FCONTX_SIZE, TX); gsw_w32(cdev, (PHY_ADDR_0_FCONRX_OFFSET - (0x1 * pidx)), PHY_ADDR_0_FCONRX_SHIFT, PHY_ADDR_0_FCONRX_SIZE, RX); } @@ -3473,25 +4208,28 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) } } - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC /* MAC API's to set flow control */ - if(parm->ePortType == GSW_PHYSICAL_PORT || - parm->ePortType == GSW_LOGICAL_PORT) { + if (parm->ePortType == GSW_PHYSICAL_PORT || + parm->ePortType == GSW_LOGICAL_PORT) { struct mac_ops *ops = get_mac_ops(gswdev, parm->nPortId); - if(!ops) - { - pr_err("MAC %d is not initialized\n",parm->nPortId); - return GSW_statusErr; - } + + if (!ops) { + pr_err("MAC %d is not initialized\n", parm->nPortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + ops->set_flow_ctl(ops, parm->eFlowCtrl); - } - else - pr_err("MAC configuration is not valid for CTP or Bridge Port %d\n",parm->nPortId); - + } else + pr_err("MAC configuration is not valid for CTP or Bridge Port %d\n", parm->nPortId); + +#endif } - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { switch (parm->ePortMonitor) { case GSW_PORT_MONITOR_NONE: gsw_w32(cdev, @@ -3523,6 +4261,7 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_3_VIO_7_SHIFT, PCE_PCTRL_3_VIO_7_SIZE, 0); break; + case GSW_PORT_MONITOR_RX: gsw_w32(cdev, (PCE_PCTRL_3_RXVMIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_RXVMIR_SHIFT, @@ -3531,6 +4270,7 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_3_TXMIR_SHIFT, PCE_PCTRL_3_TXMIR_SIZE, 0); break; + case GSW_PORT_MONITOR_TX: gsw_w32(cdev, (PCE_PCTRL_3_RXVMIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_RXVMIR_SHIFT, @@ -3539,6 +4279,7 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_3_TXMIR_SHIFT, PCE_PCTRL_3_TXMIR_SIZE, 1); break; + case GSW_PORT_MONITOR_RXTX: gsw_w32(cdev, (PCE_PCTRL_3_RXVMIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_RXVMIR_SHIFT, @@ -3547,36 +4288,41 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PCE_PCTRL_3_TXMIR_SHIFT, PCE_PCTRL_3_TXMIR_SIZE, 1); break; + case GSW_PORT_MONITOR_VLAN_UNKNOWN: gsw_w32(cdev, (PCE_PCTRL_3_VIO_2_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_2_SHIFT, PCE_PCTRL_3_VIO_2_SIZE, 1); break; + case GSW_PORT_MONITOR_VLAN_MEMBERSHIP: gsw_w32(cdev, (PCE_PCTRL_3_VIO_4_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_4_SHIFT, PCE_PCTRL_3_VIO_4_SIZE, 1); break; + case GSW_PORT_MONITOR_PORT_STATE: gsw_w32(cdev, (PCE_PCTRL_3_VIO_5_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_5_SHIFT, PCE_PCTRL_3_VIO_5_SIZE, 1); break; + case GSW_PORT_MONITOR_LEARNING_LIMIT: gsw_w32(cdev, (PCE_PCTRL_3_VIO_6_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_6_SHIFT, PCE_PCTRL_3_VIO_6_SIZE, 1); break; + case GSW_PORT_MONITOR_PORT_LOCK: gsw_w32(cdev, (PCE_PCTRL_3_VIO_7_OFFSET + (0xA * pidx)), PCE_PCTRL_3_VIO_7_SHIFT, PCE_PCTRL_3_VIO_7_SIZE, 1); break; } - } - else { + } else { // TODO: Port Mirroring uses CTP port configuration } + if (parm->eEnable == GSW_PORT_ENABLE_RXTX) { PEN = 1; EN = 1; @@ -3590,50 +4336,81 @@ GSW_return_t GSW_PortCfgSet(void *cdev, GSW_portCfg_t *parm) PEN = 0; EN = 0; } + /* Set SDMA_PCTRL_PEN PORT enable */ gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (6 * pidx)), SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, PEN); /* Set FDMA_PCTRL_EN PORT enable */ gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (0x6 * pidx)), FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, EN); + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (parm->bIfCounters == 1) { gsw_w32(cdev, (BM_RMON_CTRL_IFRMONFST_OFFSET + (0x2 * pidx)), BM_RMON_CTRL_IFRMONFST_SHIFT, BM_RMON_CTRL_IFRMONFST_SIZE, parm->nIfCountStartIdx); } + gsw_w32(cdev, (BM_RMON_CTRL_IFRMONMD_OFFSET + (0x2 * pidx)), BM_RMON_CTRL_IFRMONMD_SHIFT, BM_RMON_CTRL_IFRMONMD_SIZE, parm->eIfRMONmode); } - return GSW_statusOk; + ret = GSW_statusOk; + + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } + + #if defined(CONFIG_LTQ_STP) && CONFIG_LTQ_STP GSW_return_t GSW_STP_BPDU_RuleGet(void *cdev, - GSW_STP_BPDU_Rule_t *parm) + GSW_STP_BPDU_Rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); stp8021x_t *scfg; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + scfg = &gswdev->stpconfig; parm->eForwardPort = scfg->spstate; parm->nForwardPortId = scfg->stppid; - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_STP_BPDU_RuleSet(void *cdev, - GSW_STP_BPDU_Rule_t *parm) + GSW_STP_BPDU_Rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); stp8021x_t *scfg = &gswdev->stpconfig; - GSW_PCE_rule_t pcrule; + static GSW_PCE_rule_t pcrule; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + scfg->spstate = parm->eForwardPort; scfg->stppid = parm->nForwardPortId; memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); @@ -3648,93 +4425,157 @@ GSW_return_t GSW_STP_BPDU_RuleSet(void *cdev, pcrule.pattern.nMAC_Dst[4] = 0x00; pcrule.pattern.nMAC_Dst[5] = 0x00; pcrule.action.eCrossStateAction = GSW_PCE_ACTION_CROSS_STATE_CROSS; + if ((scfg->spstate < 4) && (scfg->spstate > 0)) pcrule.action.ePortMapAction = scfg->spstate + 1; else { - pr_err("(Incorrect forward port action) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("(Incorrect forward port action) %s:%s:%d\n", + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - pcrule.action.nForwardPortMap[0] = (1 << scfg->stppid); //Govind - Can occur out of array bounds problem. + + pcrule.action.nForwardPortMap[0] = (1 << scfg->stppid); //Govind - Can occur out of array bounds problem. + /* We prepare everything and write into PCE Table */ - if (0 != pce_rule_write(cdev, &gswdev->phandler, &pcrule)) - return GSW_statusErr; - return GSW_statusOk; + if (0 != pce_rule_write(cdev, &gswdev->phandler, &pcrule)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_STP_PortCfgGet(void *cdev, GSW_STP_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - parm->ePortState = gswdev->pconfig[parm->nPortId].pcstate; - } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif - if(gswdev->gipver == LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->num_of_bridge_port) - return GSW_statusErr; - /*If Bridge Port ID is valid,Check whether it is InUSE - if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) - return GSW_statusErr; - - parm->ePortState=gswdev->brdgeportconfig_idx[parm->nPortId].StpState; - } - - return GSW_statusOk; + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + parm->ePortState = gswdev->pconfig[parm->nPortId].pcstate; + } + + if (IS_VRSN_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->num_of_bridge_port) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If Bridge Port ID is valid,Check whether it is InUSE + if not InUse,return ERROR*/ + if (!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + parm->ePortState = gswdev->brdgeportconfig_idx[parm->nPortId].StpState; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_STP_PortCfgSet(void *cdev, GSW_STP_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 StpState,P8021xState; + u8 StpState, P8021xState; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - gswdev->pconfig[parm->nPortId].pcstate = parm->ePortState; - /* Config the Table */ - set_port_state(cdev, parm->nPortId, - gswdev->pconfig[parm->nPortId].pcstate, - gswdev->pconfig[parm->nPortId].p8021xs); - } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif - if(gswdev->gipver == LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->num_of_bridge_port) - return GSW_statusErr; - /*If Bridge Port ID is valid,Check whether it is InUSE - if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) - return GSW_statusErr; - - StpState = parm->ePortState; - P8021xState = gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState; - gswdev->brdgeportconfig_idx[parm->nPortId].StpState=StpState; - - /* Config the Table */ - set_port_state(cdev, parm->nPortId, StpState, P8021xState); - } - return GSW_statusOk; + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + gswdev->pconfig[parm->nPortId].pcstate = parm->ePortState; + /* Config the Table */ + set_port_state(cdev, parm->nPortId, + gswdev->pconfig[parm->nPortId].pcstate, + gswdev->pconfig[parm->nPortId].p8021xs); + } + + if (IS_VRSN_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->num_of_bridge_port) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If Bridge Port ID is valid,Check whether it is InUSE + if not InUse,return ERROR*/ + if (!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + StpState = parm->ePortState; + P8021xState = gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState; + gswdev->brdgeportconfig_idx[parm->nPortId].StpState = StpState; + + /* Config the Table */ + set_port_state(cdev, parm->nPortId, StpState, P8021xState); + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_TrunkingCfgGet(void *cdev, GSW_trunkingCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { @@ -3754,22 +4595,38 @@ GSW_return_t GSW_TrunkingCfgGet(void *cdev, GSW_trunkingCfg_t *parm) gsw_r32(cdev, PCE_TRUNK_CONF_SA_OFFSET, PCE_TRUNK_CONF_SA_SHIFT, PCE_TRUNK_CONF_SA_SIZE, &parm->bMAC_Src); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_TrunkingCfgSet(void *cdev, - GSW_trunkingCfg_t *parm) + GSW_trunkingCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver != LTQ_GSWIP_2_0) { /* Destination IP Mask */ if (parm->bIP_Dst == 1) { @@ -3781,6 +4638,7 @@ GSW_return_t GSW_TrunkingCfgSet(void *cdev, PCE_TRUNK_CONF_DIP_SHIFT, PCE_TRUNK_CONF_DIP_SIZE, 0); } + /* 'Source IP Mask */ if (parm->bIP_Src == 1) { gsw_w32(cdev, PCE_TRUNK_CONF_SIP_OFFSET, @@ -3791,6 +4649,7 @@ GSW_return_t GSW_TrunkingCfgSet(void *cdev, PCE_TRUNK_CONF_SIP_SHIFT, PCE_TRUNK_CONF_SIP_SIZE, 0); } + /* Destination MAC Mask */ if (parm->bMAC_Dst == 1) { gsw_w32(cdev, PCE_TRUNK_CONF_DA_OFFSET, @@ -3801,6 +4660,7 @@ GSW_return_t GSW_TrunkingCfgSet(void *cdev, PCE_TRUNK_CONF_DA_SHIFT, PCE_TRUNK_CONF_DA_SIZE, 0); } + /* 'Source MAC Mask */ if (parm->bMAC_Src == 1) { gsw_w32(cdev, PCE_TRUNK_CONF_SA_OFFSET, @@ -3811,23 +4671,42 @@ GSW_return_t GSW_TrunkingCfgSet(void *cdev, PCE_TRUNK_CONF_SA_SHIFT, PCE_TRUNK_CONF_SA_SIZE, 0); } - return GSW_statusOk; + + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_TrunkingPortCfgGet(void *cdev, - GSW_trunkingPortCfg_t *parm) + GSW_trunkingPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; u32 value; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= (gswdev->tpnum)) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= (gswdev->tpnum)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns with */ /* an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { @@ -3839,26 +4718,44 @@ GSW_return_t GSW_TrunkingPortCfgGet(void *cdev, gsw_r32(cdev, (PCE_PTRUNK_PARTER_OFFSET + (parm->nPortId * 0x2)), PCE_PTRUNK_PARTER_SHIFT, PCE_PTRUNK_PARTER_SIZE, &value); parm->nAggrPortId = value; - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_TrunkingPortCfgSet(void *cdev, GSW_trunkingPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= (gswdev->tpnum)) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= (gswdev->tpnum)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { - /** Ports are aggregated. the 'nPortId' and the */ - /* 'nAggrPortId' ports form an aggregated link.*/ + /** Ports are aggregated. the 'nPortId' and the */ + /* 'nAggrPortId' ports form an aggregated link.*/ if (parm->bAggregateEnable == 1) { gsw_w32(cdev, (PCE_PTRUNK_EN_OFFSET + (parm->nPortId * 0x2)), PCE_PTRUNK_EN_SHIFT, PCE_PTRUNK_EN_SIZE, 1); @@ -3868,20 +4765,36 @@ GSW_return_t GSW_TrunkingPortCfgSet(void *cdev, GSW_trunkingPortCfg_t *parm) gsw_w32(cdev, (PCE_PTRUNK_EN_OFFSET + (parm->nPortId * 0x2)), PCE_PTRUNK_EN_SHIFT, PCE_PTRUNK_EN_SIZE, 0); } - return GSW_statusOk; + + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_TimestampTimerSet(void *cdev, GSW_TIMESTAMP_Timer_t *parm) { u32 value; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Supported for GSWIP 2.2 and newer and returns with */ /* an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { @@ -3902,9 +4815,9 @@ GSW_return_t GSW_TimestampTimerSet(void *cdev, GSW_TIMESTAMP_Timer_t *parm) TIMER_NS_MSB_NSMSB_SHIFT, TIMER_NS_MSB_NSMSB_SIZE, ((parm->nNanoSec >> 16) & 0xFFFF)); -/** Fractional Nano Second. Absolute fractional nano */ -/* second timer count. This counter specifis a */ -/* 2^32 fractional 'nNanoSec'. */ + /** Fractional Nano Second. Absolute fractional nano */ + /* second timer count. This counter specifis a */ + /* 2^32 fractional 'nNanoSec'. */ gsw_w32(cdev, (TIMER_FS_LSB_FSLSB_OFFSET), TIMER_FS_LSB_FSLSB_SHIFT, TIMER_FS_LSB_FSLSB_SIZE, @@ -3917,27 +4830,42 @@ GSW_return_t GSW_TimestampTimerSet(void *cdev, GSW_TIMESTAMP_Timer_t *parm) gsw_w32(cdev, (TIMER_CTRL_WR_OFFSET), TIMER_CTRL_WR_SHIFT, TIMER_CTRL_WR_SIZE, value); - - CHECK_BUSY(TIMER_CTRL_WR_OFFSET, - TIMER_CTRL_WR_SHIFT,TIMER_CTRL_WR_SIZE, RETURN_FROM_FUNCTION); - - - return GSW_statusOk; + + CHECK_BUSY(TIMER_CTRL_WR_OFFSET, + TIMER_CTRL_WR_SHIFT, TIMER_CTRL_WR_SIZE, RETURN_FROM_FUNCTION); + + + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_TimestampTimerGet(void *cdev, - GSW_TIMESTAMP_Timer_t *parm) + GSW_TIMESTAMP_Timer_t *parm) { u32 value; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; value = 1; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { @@ -3945,9 +4873,9 @@ GSW_return_t GSW_TimestampTimerGet(void *cdev, TIMER_CTRL_RD_SHIFT, TIMER_CTRL_RD_SIZE, value); - CHECK_BUSY(TIMER_CTRL_RD_OFFSET, - TIMER_CTRL_RD_SHIFT, TIMER_CTRL_RD_SIZE, RETURN_FROM_FUNCTION); - + CHECK_BUSY(TIMER_CTRL_RD_OFFSET, + TIMER_CTRL_RD_SHIFT, TIMER_CTRL_RD_SIZE, RETURN_FROM_FUNCTION); + /** Second. Absolute second timer count. */ gsw_r32(cdev, (TIMER_SEC_LSB_SECLSB_OFFSET), TIMER_SEC_LSB_SECLSB_SHIFT, @@ -3966,9 +4894,9 @@ GSW_return_t GSW_TimestampTimerGet(void *cdev, TIMER_NS_MSB_NSMSB_SHIFT, TIMER_NS_MSB_NSMSB_SIZE, &value); parm->nNanoSec |= (value & 0xFFFF << 16); - /** Fractional Nano Second. Absolute fractional */ - /* nano second timer count. */ -/* This counter specifis a 2^32 fractional 'nNanoSec'. */ + /** Fractional Nano Second. Absolute fractional */ + /* nano second timer count. */ + /* This counter specifis a 2^32 fractional 'nNanoSec'. */ gsw_r32(cdev, (TIMER_FS_LSB_FSLSB_OFFSET), TIMER_FS_LSB_FSLSB_SHIFT, TIMER_FS_LSB_FSLSB_SIZE, &value); @@ -3977,69 +4905,104 @@ GSW_return_t GSW_TimestampTimerGet(void *cdev, TIMER_FS_MSB_FSMSB_SHIFT, TIMER_FS_MSB_FSMSB_SIZE, &value); parm->nFractionalNanoSec |= (value & 0xFFFF << 16); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_TimestampPortRead(void *cdev, - GSW_TIMESTAMP_PortRead_t *parm) + GSW_TIMESTAMP_PortRead_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 tstamp0, tstamp1; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= ((gswdev->tpnum - 1))) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= ((gswdev->tpnum - 1))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ if (gswdev->gipver != LTQ_GSWIP_2_0) { /** Second. Absolute second timer count. */ gsw_r32(cdev, (FDMA_TSTAMP0_TSTL_OFFSET + - (parm->nPortId * 0x6)), + (parm->nPortId * 0x6)), FDMA_TSTAMP0_TSTL_SHIFT, FDMA_TSTAMP0_TSTL_SIZE, &tstamp0); gsw_r32(cdev, (FDMA_TSTAMP1_TSTH_OFFSET + - (parm->nPortId * 0x6)), + (parm->nPortId * 0x6)), FDMA_TSTAMP1_TSTH_SHIFT, FDMA_TSTAMP1_TSTH_SIZE, &tstamp1); parm->nEgressSec = ((tstamp0 | (tstamp1 << 16))) >> 30; parm->nEgressNanoSec = (((tstamp0 | (tstamp1 << 16))) - & 0x7FFFFFFF); + & 0x7FFFFFFF); /** Nano Second. Absolute nano second timer count. */ gsw_r32(cdev, (SDMA_TSTAMP0_TSTL_OFFSET + - (parm->nPortId * 0x6)), + (parm->nPortId * 0x6)), SDMA_TSTAMP0_TSTL_SHIFT, SDMA_TSTAMP0_TSTL_SIZE, &tstamp0); gsw_r32(cdev, (SDMA_TSTAMP1_TSTH_OFFSET + - (parm->nPortId * 0x6)), + (parm->nPortId * 0x6)), SDMA_TSTAMP1_TSTH_SHIFT, SDMA_TSTAMP1_TSTH_SIZE, &tstamp1); parm->nIngressSec = ((tstamp0 | (tstamp1 << 16))) >> 30; parm->nIngressNanoSec = (((tstamp0 | (tstamp1 << 16))) - & 0x7FFFFFFF); - return GSW_statusOk; + & 0x7FFFFFFF); + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } #endif /* CONFIG_LTQ_STP */ #if defined(CONFIG_LTQ_VLAN) && CONFIG_LTQ_VLAN GSW_return_t GSW_VLAN_Member_Init(void *cdev, - GSW_VLAN_memberInit_t *parm) + GSW_VLAN_memberInit_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { pctbl_prog_t pcetable; u16 pcindex; + for (pcindex = 0; pcindex < 4096; pcindex++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = pcindex; @@ -4051,23 +5014,40 @@ GSW_return_t GSW_VLAN_Member_Init(void *cdev, pcetable.val[2] = (parm->nEgressTagMap & 0xFFFF); gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_VLAN_IdCreate(void *cdev, - GSW_VLAN_IdCreate_t *parm) + GSW_VLAN_IdCreate_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = parm->nVId; pcetable.table = PCE_VLANMAP_INDEX; @@ -4076,22 +5056,32 @@ GSW_return_t GSW_VLAN_IdCreate(void *cdev, } else { u8 pcindex; avlan_tbl_t avlantbl; + if (find_active_vlan_index(cdev, parm->nVId) != 0xFF) { pr_err("This vid exists\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + pcindex = fempty_avlan_index_table(cdev); + if (pcindex == 0xFF) { pr_err("There is no table entry avariable\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + memset(&avlantbl, 0, sizeof(avlan_tbl_t)); memset(&pcetable, 0, sizeof(pctbl_prog_t)); avlantbl.valid = 1; avlantbl.vid = parm->nVId; avlantbl.fid = parm->nFId; - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + vlan_entry_set(cdev, pcindex, &avlantbl); memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = pcindex; @@ -4106,21 +5096,36 @@ GSW_return_t GSW_VLAN_IdCreate(void *cdev, pcetable.val[2] = 0; gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_VLAN_IdDelete(void *cdev, - GSW_VLAN_IdDelete_t *parm) + GSW_VLAN_IdDelete_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = parm->nVId; pcetable.table = PCE_VLANMAP_INDEX; @@ -4131,19 +5136,27 @@ GSW_return_t GSW_VLAN_IdDelete(void *cdev, ltq_pce_table_t *pcvtbl = &gswdev->phandler; memset(&avlantbl, 0, sizeof(avlan_tbl_t)); pcindex = find_active_vlan_index(cdev, parm->nVId); + if (pcindex == 0xFF) { pr_err("(VID not exists) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (gavlan_tbl_index(&pcvtbl->pce_sub_tbl, - pcindex) != GSW_statusOk) { + pcindex) != GSW_statusOk) { pr_err("(VID: 0x%0x used by flow table) %s:%s:%d\n", - parm->nVId, __FILE__, __func__, __LINE__); - return GSW_statusErr; + parm->nVId, __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + vlan_entry_set(cdev, pcindex, &avlantbl); memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = pcindex; @@ -4153,19 +5166,34 @@ GSW_return_t GSW_VLAN_IdDelete(void *cdev, pcetable.table = PCE_VLANMAP_INDEX; gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_IdGet(void *cdev, GSW_VLAN_IdGet_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = parm->nVId; pcetable.table = PCE_VLANMAP_INDEX; @@ -4175,69 +5203,102 @@ GSW_return_t GSW_VLAN_IdGet(void *cdev, GSW_VLAN_IdGet_t *parm) u8 pcindex; avlan_tbl_t avlantbl; pcindex = find_active_vlan_index(cdev, parm->nVId); + if (pcindex == 0xFF) { pr_err("(VID not exists) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + get_vlan_sw_table(cdev, pcindex, &avlantbl); parm->nFId = avlantbl.fid; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_VLAN_PortCfgGet(void *cdev, - GSW_VLAN_portCfg_t *parm) + GSW_VLAN_portCfg_t *parm) { u32 value; int pcindex; ltq_bool_t uvr, vimr, vemr; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); avlan_tbl_t avlantbl; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_r32(cdev, (PCE_DEFPVID_PVID_OFFSET + (10 * parm->nPortId)), PCE_DEFPVID_PVID_SHIFT, PCE_DEFPVID_PVID_SIZE, &value); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { parm->nPortVId = value; } else { pcindex = value; - if (pcindex >= 64) - return GSW_statusValueRange; - get_vlan_sw_table(cdev, pcindex, &avlantbl); + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + + get_vlan_sw_table(cdev, pcindex, &avlantbl); parm->nPortVId = avlantbl.vid; } + gsw_r32(cdev, (PCE_VCTRL_UVR_OFFSET + (10 * parm->nPortId)), PCE_VCTRL_UVR_SHIFT, PCE_VCTRL_UVR_SIZE, &value); uvr = value; + if (uvr == 1) parm->bVLAN_UnknownDrop = 1; else parm->bVLAN_UnknownDrop = 0; + gsw_r32(cdev, (PCE_VCTRL_VSR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VSR_SHIFT, PCE_VCTRL_VSR_SIZE, &value); parm->bVLAN_ReAssign = value; gsw_r32(cdev, (PCE_VCTRL_VIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VIMR_SHIFT, PCE_VCTRL_VIMR_SIZE, &value); vimr = value; gsw_r32(cdev, (PCE_VCTRL_VEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VEMR_SHIFT, PCE_VCTRL_VEMR_SIZE, &value); vemr = value; + if (vimr == 0 && vemr == 0) parm->eVLAN_MemberViolation = GSW_VLAN_MEMBER_VIOLATION_NO; else if (vimr == 1 && vemr == 0) @@ -4248,166 +5309,225 @@ GSW_return_t GSW_VLAN_PortCfgGet(void *cdev, parm->eVLAN_MemberViolation = GSW_VLAN_MEMBER_VIOLATION_BOTH; gsw_r32(cdev, (PCE_VCTRL_VINR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VINR_SHIFT, PCE_VCTRL_VINR_SIZE, &value); + switch (value) { case 0: parm->eAdmitMode = GSW_VLAN_ADMIT_ALL; break; + case 1: parm->eAdmitMode = GSW_VLAN_ADMIT_TAGGED; break; + case 2: parm->eAdmitMode = GSW_VLAN_ADMIT_UNTAGGED; break; + default: - break; + break; } + gsw_r32(cdev, (PCE_PCTRL_0_TVM_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_TVM_SHIFT, PCE_PCTRL_0_TVM_SIZE, &value); parm->bTVM = value; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_PortCfgSet(void *cdev, - GSW_VLAN_portCfg_t *parm) + GSW_VLAN_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; u8 pcindex; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { value = parm->nPortVId; } else { pcindex = find_active_vlan_index(cdev, parm->nPortVId); + if (pcindex == 0xFF) { pr_err("(VID not exists) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + value = pcindex; } + gsw_w32(cdev, (PCE_DEFPVID_PVID_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_DEFPVID_PVID_SHIFT, PCE_DEFPVID_PVID_SIZE, value); value = 0; + if (parm->bVLAN_UnknownDrop == 1) value = 1; gsw_w32(cdev, (PCE_VCTRL_UVR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_UVR_SHIFT, PCE_VCTRL_UVR_SIZE, value); value = parm->bVLAN_ReAssign; gsw_w32(cdev, (PCE_VCTRL_VSR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VSR_SHIFT, PCE_VCTRL_VSR_SIZE, value); + switch (parm->eVLAN_MemberViolation) { case GSW_VLAN_MEMBER_VIOLATION_NO: gsw_w32(cdev, (PCE_VCTRL_VIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VIMR_SHIFT, PCE_VCTRL_VIMR_SIZE, 0); gsw_w32(cdev, (PCE_VCTRL_VEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VEMR_SHIFT, PCE_VCTRL_VEMR_SIZE, 0); break; + case GSW_VLAN_MEMBER_VIOLATION_INGRESS: gsw_w32(cdev, (PCE_VCTRL_VIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VIMR_SHIFT, PCE_VCTRL_VIMR_SIZE, 1); gsw_w32(cdev, (PCE_VCTRL_VEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VEMR_SHIFT, PCE_VCTRL_VEMR_SIZE, 0); break; + case GSW_VLAN_MEMBER_VIOLATION_EGRESS: gsw_w32(cdev, (PCE_VCTRL_VIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VIMR_SHIFT, PCE_VCTRL_VIMR_SIZE, 0); gsw_w32(cdev, (PCE_VCTRL_VEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VEMR_SHIFT, PCE_VCTRL_VEMR_SIZE, 1); break; + case GSW_VLAN_MEMBER_VIOLATION_BOTH: gsw_w32(cdev, (PCE_VCTRL_VIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VIMR_SHIFT, PCE_VCTRL_VIMR_SIZE, 1); gsw_w32(cdev, (PCE_VCTRL_VEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VEMR_SHIFT, PCE_VCTRL_VEMR_SIZE, 1); break; + default: pr_err("WARNING:(eVLAN_MemberViolation) %s:%s:%d\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); } + switch (parm->eAdmitMode) { case GSW_VLAN_ADMIT_ALL: value = 0; break; + case GSW_VLAN_ADMIT_TAGGED: value = 1; break; + case GSW_VLAN_ADMIT_UNTAGGED: value = 2; break; + default: value = 0; pr_err("%s:%s:%d (eAdmitMode)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); } + gsw_w32(cdev, (PCE_VCTRL_VINR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_VINR_SHIFT, PCE_VCTRL_VINR_SIZE, value); value = 0; + if (parm->bTVM == 1) value = 1; gsw_w32(cdev, (PCE_PCTRL_0_TVM_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_TVM_SHIFT, PCE_PCTRL_0_TVM_SIZE, value); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, - GSW_VLAN_portMemberAdd_t *parm) + GSW_VLAN_portMemberAdd_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((parm->nPortId >= gswdev->tpnum) && - (!(parm->nPortId & 0x80000000))) - return GSW_statusErr; + (!(parm->nPortId & 0x80000000))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + + } + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { u16 portmap, tagmap, val0; + if (parm->nVId > 4096) { pr_err("ERROR: %s:%s:%d, (VID:%d)\n", - __FILE__, __func__, __LINE__, parm->nVId); - return GSW_statusErr; + __FILE__, __func__, __LINE__, parm->nVId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = parm->nVId; @@ -4415,22 +5535,26 @@ GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, portmap = (pcetable.val[1]); tagmap = (pcetable.val[2]); val0 = (pcetable.val[0]); - /* Support portmap information. */ - /* To differentiate between port index and portmap, */ - /* the MSB (highest data bit) should be 1.*/ + + /* Support portmap information. */ + /* To differentiate between port index and portmap, */ + /* the MSB (highest data bit) should be 1.*/ if (parm->nPortId & 0x80000000) { /*Port Map */ portmap |= ((parm->nPortId) & 0xFFFF); + if (parm->bVLAN_TagEgress) tagmap |= ((parm->nPortId) & 0xFFFF); else tagmap &= ~((parm->nPortId) & 0xFFFF); } else { portmap |= 1 << parm->nPortId; + if (parm->bVLAN_TagEgress) tagmap |= 1 << parm->nPortId; else tagmap &= ~(1 << parm->nPortId); } + pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = parm->nVId; pcetable.val[0] = val0; @@ -4441,35 +5565,48 @@ GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, u8 pcindex; avlan_tbl_t avlantbl; pcindex = find_active_vlan_index(cdev, - parm->nVId); + parm->nVId); + if (pcindex == 0xFF) { pr_err("(VID not exists) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (pcindex >= 64) return GSW_statusValueRange; + get_vlan_sw_table(cdev, pcindex, &avlantbl); + if (avlantbl.reserved == 1) { pr_err("(VID was already reserved) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (parm->nPortId & 0x80000000) { /*Port Map */ avlantbl.pm |= ((parm->nPortId) & 0x7FFF); + if (parm->bVLAN_TagEgress) avlantbl.tm |= ((parm->nPortId) & 0x7FFF); else avlantbl.tm &= ~((parm->nPortId) & 0x7FFF); } else { avlantbl.pm |= 1 << parm->nPortId; + if (parm->bVLAN_TagEgress) avlantbl.tm |= 1 << parm->nPortId; else avlantbl.tm &= ~(1 << parm->nPortId); } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + vlan_entry_set(cdev, pcindex, &avlantbl); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = pcindex; @@ -4480,19 +5617,33 @@ GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, pcetable.val[2] = avlantbl.tm; gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_PortMemberRead(void *cdev, - GSW_VLAN_portMemberRead_t *parm) + GSW_VLAN_portMemberRead_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (parm->bInitial == 1) { /*Start from the index 0 */ gswdev->vlan_rd_index = 0; @@ -4506,9 +5657,10 @@ GSW_return_t GSW_VLAN_PortMemberRead(void *cdev, parm->bInitial = 0; parm->bLast = 0; } + if (parm->bLast != 1) { if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { if (gswdev->vlan_rd_index < 4096) { gswdev->vlan_rd_index++; pcetable.table = PCE_VLANMAP_INDEX; @@ -4538,30 +5690,49 @@ GSW_return_t GSW_VLAN_PortMemberRead(void *cdev, } } } - return GSW_statusOk; + + ret = GSW_statusOk; + + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, - GSW_VLAN_portMemberRemove_t *parm) + GSW_VLAN_portMemberRemove_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((parm->nPortId >= gswdev->tpnum) && - (!(parm->nPortId & 0x80000000))) - return GSW_statusErr; + (!(parm->nPortId & 0x80000000))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { - u16 portmap, tagmap , val0; + (gswdev->gipver == LTQ_GSWIP_3_0)) { + u16 portmap, tagmap, val0; + if (parm->nVId > 4096) { pr_err("ERROR: %s:%s:%d, (VID:%d)\n", - __FILE__, __func__, __LINE__, parm->nVId); - return GSW_statusErr; + __FILE__, __func__, __LINE__, parm->nVId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = parm->nVId; @@ -4569,6 +5740,7 @@ GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, portmap = (pcetable.val[1]); tagmap = (pcetable.val[2]); val0 = (pcetable.val[0]); + if (parm->nPortId & 0x80000000) portmap &= ~((parm->nPortId) & 0x7FFF); else @@ -4585,26 +5757,37 @@ GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, avlan_tbl_t avlantbl; u8 pcindex; pcindex = find_active_vlan_index(cdev, - parm->nVId); + parm->nVId); + if (pcindex == 0xFF) { pr_err("This vid doesn't exists\n"); - return GSW_statusErr; + ret = GSW_statusErr; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + get_vlan_sw_table(cdev, pcindex, &avlantbl); + if (parm->nPortId & 0x80000000) avlantbl.pm &= ~((parm->nPortId) & 0x7FFF); else avlantbl.pm &= ~(1 << parm->nPortId); avlantbl.tm &= ~(1 << parm->nPortId); - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + vlan_entry_set(cdev, pcindex, &avlantbl); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = pcindex; gsw_pce_table_read(cdev, &pcetable); + if (parm->nPortId & 0x80000000) { pcetable.val[1] &= ~((parm->nPortId) & 0x7FFF); pcetable.val[2] &= ~((parm->nPortId) & 0x7FFF); @@ -4612,28 +5795,44 @@ GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, pcetable.val[1] &= ~(1 << parm->nPortId); pcetable.val[2] &= ~(1 << parm->nPortId); } + gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_VLAN_ReservedAdd(void *cdev, - GSW_VLAN_reserved_t *parm) + GSW_VLAN_reserved_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { if (parm->nVId > 4096) { pr_err("ERROR: %s:%s:%d,(VID:%d)\n", - __FILE__, __func__, __LINE__, parm->nVId); - return GSW_statusErr; + __FILE__, __func__, __LINE__, parm->nVId); + ret = GSW_statusErr; } + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = parm->nVId; @@ -4644,28 +5843,43 @@ GSW_return_t GSW_VLAN_ReservedAdd(void *cdev, u8 pcindex; avlan_tbl_t avlantbl; pcindex = find_active_vlan_index(cdev, - parm->nVId); + parm->nVId); + if (pcindex == 0xFF) { pr_err("(VID not exist, create VID) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + get_vlan_sw_table(cdev, pcindex, &avlantbl); + if (avlantbl.pm != 0) { pr_err("(Added to member & can't be reserve %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (avlantbl.tm != 0) { pr_err("(Added to member & can't be reserve %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + avlantbl.reserved = 1; - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + vlan_entry_set(cdev, pcindex, &avlantbl); memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = pcindex; @@ -4673,25 +5887,42 @@ GSW_return_t GSW_VLAN_ReservedAdd(void *cdev, pcetable.val[0] |= (1 << 8); gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_VLAN_ReservedRemove(void *cdev, - GSW_VLAN_reserved_t *parm) + GSW_VLAN_reserved_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { if (parm->nVId > 4096) { pr_err("ERROR: %s:%s:%d,(VID:%d)\n", - __FILE__, __func__, __LINE__, parm->nVId); - return GSW_statusErr; + __FILE__, __func__, __LINE__, parm->nVId); + ret = GSW_statusErr; } + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_VLANMAP_INDEX; pcetable.pcindex = parm->nVId; @@ -4702,32 +5933,48 @@ GSW_return_t GSW_VLAN_ReservedRemove(void *cdev, u8 pcindex; avlan_tbl_t avlantbl; pcindex = find_active_vlan_index(cdev, parm->nVId); + if (pcindex == 0xFF) { pr_err("This vid doesn't exists, create VID first\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + get_vlan_sw_table(cdev, pcindex, &avlantbl); + if (avlantbl.pm != 0) { pr_err("(Added to member & can't be remove the reserve %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (avlantbl.tm != 0) { pr_err("(Added to member & can't be remove the reserve %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (pcindex >= 64) - return GSW_statusValueRange; + + if (pcindex >= 64) { + ret = GSW_statusValueRange; + goto UNLOCK_AND_RETURN; + } + if (avlantbl.reserved == 0) { pr_err("This VID was not reserve, reserve it first\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } else { avlantbl.reserved = 0; vlan_entry_set(cdev, pcindex, &avlantbl); } + vlan_entry_set(cdev, pcindex, &avlantbl); memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = pcindex; @@ -4735,81 +5982,130 @@ GSW_return_t GSW_VLAN_ReservedRemove(void *cdev, pcetable.val[0] &= ~(1 << 8); gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_PCE_EG_VLAN_CfgSet(void *cdev, - GSW_PCE_EgVLAN_Cfg_t *parm) + GSW_PCE_EgVLAN_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (parm->eEgVLANmode == - GSW_PCE_EG_VLAN_SUBIFID_BASED) { + GSW_PCE_EG_VLAN_SUBIFID_BASED) { gsw_w32(cdev, (PCE_EVLANCFG_EGVMD_OFFSET - + (0x10 * parm->nPortId)), + + (0x10 * parm->nPortId)), PCE_EVLANCFG_EGVMD_SHIFT, PCE_EVLANCFG_EGVMD_SIZE, 1); } else { gsw_w32(cdev, (PCE_EVLANCFG_EGVMD_OFFSET - + (0x10 * parm->nPortId)), + + (0x10 * parm->nPortId)), PCE_EVLANCFG_EGVMD_SHIFT, PCE_EVLANCFG_EGVMD_SIZE, 0); } + gsw_w32(cdev, (PCE_EVLANCFG_EGVFST_OFFSET - + (0x10 * parm->nPortId)), + + (0x10 * parm->nPortId)), PCE_EVLANCFG_EGVFST_SHIFT, PCE_EVLANCFG_EGVFST_SIZE, parm->nEgStartVLANIdx); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_PCE_EG_VLAN_CfgGet(void *cdev, - GSW_PCE_EgVLAN_Cfg_t *parm) + GSW_PCE_EgVLAN_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } -/* if (parm->nPortId >= gswdev->tpnum) */ -/* return GSW_statusErr; */ + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + /* if (parm->nPortId >= gswdev->tpnum) */ + /* ret = GSW_statusErr; */ if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (PCE_EVLANCFG_EGVMD_OFFSET - + (0x10 * parm->nPortId)), + + (0x10 * parm->nPortId)), PCE_EVLANCFG_EGVMD_SHIFT, PCE_EVLANCFG_EGVMD_SIZE, &parm->eEgVLANmode); gsw_r32(cdev, (PCE_EVLANCFG_EGVFST_OFFSET - + (0x10 * parm->nPortId)), + + (0x10 * parm->nPortId)), PCE_EVLANCFG_EGVFST_SHIFT, PCE_EVLANCFG_EGVFST_SIZE, &value); parm->nEgStartVLANIdx = value; } - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_PCE_EG_VLAN_EntryWrite(void *cdev, - GSW_PCE_EgVLAN_Entry_t *parm) + GSW_PCE_EgVLAN_Entry_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* if (parm->nPortId >= gswdev->tpnum) */ -/* return GSW_statusErr;*/ + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + /* if (parm->nPortId >= gswdev->tpnum) */ + /* ret = GSW_statusErr;*/ if (gswdev->gipver == LTQ_GSWIP_3_0) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = (parm->nIndex & 0xFF); + if (parm->bEgVLAN_Action == 1) pcetable.val[0] |= (1 << 0); @@ -4820,6 +6116,7 @@ GSW_return_t GSW_PCE_EG_VLAN_EntryWrite(void *cdev, pcetable.val[0] |= (1 << 3); pcetable.val[0] |= ((parm->nEgSVid & 0xFFF) << 4); + if (parm->bEgCVidRem_Action == 1) pcetable.val[1] |= (1 << 2); @@ -4830,20 +6127,34 @@ GSW_return_t GSW_PCE_EG_VLAN_EntryWrite(void *cdev, pcetable.table = PCE_EG_VLAN_INDEX; gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_PCE_EG_VLAN_EntryRead(void *cdev, - GSW_PCE_EgVLAN_Entry_t *parm) + GSW_PCE_EgVLAN_Entry_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /*if (parm->nPortId >= gswdev->tpnum) */ - /* return GSW_statusErr; */ + /* ret = GSW_statusErr; */ if (gswdev->gipver == LTQ_GSWIP_3_0) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = (parm->nIndex & 0xFF); @@ -4857,272 +6168,373 @@ GSW_return_t GSW_PCE_EG_VLAN_EntryRead(void *cdev, parm->bEgCVidIns_Action = (pcetable.val[1] >> 3) & 0x1; parm->nEgCVid = (pcetable.val[1] >> 4) & 0xFFF; } + gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_SVLAN_CfgGet(void *cdev, - GSW_SVLAN_cfg_t *parm) + GSW_SVLAN_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 reg_val; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) - || (gswdev->gipver == LTQ_GSWIP_3_0)) { + || (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_r32(cdev, (FDMA_SVTETYPE_OFFSET), FDMA_SVTETYPE_ETYPE_SHIFT, FDMA_SVTETYPE_ETYPE_SIZE, ®_val); parm->nEthertype = reg_val; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_SVLAN_CfgSet(void *cdev, - GSW_SVLAN_cfg_t *parm) + GSW_SVLAN_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 reg_val; + u32 ret; reg_val = parm->nEthertype & 0xFFFF; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_w32(cdev, (FDMA_SVTETYPE_OFFSET), FDMA_SVTETYPE_ETYPE_SHIFT, FDMA_SVTETYPE_ETYPE_SIZE, reg_val); gsw_w32(cdev, (MAC_VLAN_ETYPE_1_INNER_OFFSET), MAC_VLAN_ETYPE_1_INNER_SHIFT, MAC_VLAN_ETYPE_1_INNER_SIZE, reg_val); - /* ToDo: Update the Micro code based on SVAN*/ + /* ToDo: Update the Micro code based on SVAN*/ } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_SVLAN_PortCfgGet(void *cdev, - GSW_SVLAN_portCfg_t *parm) + GSW_SVLAN_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; ltq_bool_t svimr, svemr; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; -/** nPortVId: retrieve the corresponding VLAN ID */ -/* from the Active VLAN Table*/ +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /** nPortVId: retrieve the corresponding VLAN ID */ + /* from the Active VLAN Table*/ if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_r32(cdev, (PCE_DEFPSVID_PVID_OFFSET + - (2 * parm->nPortId)), + (2 * parm->nPortId)), PCE_DEFPSVID_PVID_SHIFT, PCE_DEFPSVID_PVID_SIZE, &value); parm->nPortVId = value; - /* bSVLAN_TagSupport */ + /* bSVLAN_TagSupport */ gsw_r32(cdev, (PCE_VCTRL_STEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_STEN_SHIFT, PCE_VCTRL_STEN_SIZE, &value); parm->bSVLAN_TagSupport = value; /** bVLAN_ReAssign */ gsw_r32(cdev, (PCE_VCTRL_SVSR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVSR_SHIFT, PCE_VCTRL_SVSR_SIZE, &value); parm->bVLAN_ReAssign = value; - /** bVlanMemberViolationIngress */ + /** bVlanMemberViolationIngress */ gsw_r32(cdev, (PCE_VCTRL_SVIMR_OFFSET - + (10 * parm->nPortId)), + + (10 * parm->nPortId)), PCE_VCTRL_SVIMR_SHIFT, PCE_VCTRL_SVIMR_SIZE, &value); svimr = value; /** bVlanMemberViolationEgress */ gsw_r32(cdev, (PCE_VCTRL_SVEMR_OFFSET - + (10 * parm->nPortId)), + + (10 * parm->nPortId)), PCE_VCTRL_SVEMR_SHIFT, PCE_VCTRL_SVEMR_SIZE, &value); svemr = value; + if (svimr == 0 && svemr == 0) parm->eVLAN_MemberViolation = - GSW_VLAN_MEMBER_VIOLATION_NO; + GSW_VLAN_MEMBER_VIOLATION_NO; + if (svimr == 1 && svemr == 0) parm->eVLAN_MemberViolation = - GSW_VLAN_MEMBER_VIOLATION_INGRESS; + GSW_VLAN_MEMBER_VIOLATION_INGRESS; + if (svimr == 0 && svemr == 1) parm->eVLAN_MemberViolation = - GSW_VLAN_MEMBER_VIOLATION_EGRESS; + GSW_VLAN_MEMBER_VIOLATION_EGRESS; + if (svimr == 1 && svemr == 1) parm->eVLAN_MemberViolation = - GSW_VLAN_MEMBER_VIOLATION_BOTH; + GSW_VLAN_MEMBER_VIOLATION_BOTH; + /* eAdmitMode: */ gsw_r32(cdev, (PCE_VCTRL_SVINR_OFFSET - + (10 * parm->nPortId)), + + (10 * parm->nPortId)), PCE_VCTRL_SVINR_SHIFT, PCE_VCTRL_SVINR_SIZE, &value); + switch (value) { case 0: parm->eAdmitMode = GSW_VLAN_ADMIT_ALL; break; + case 1: parm->eAdmitMode = GSW_VLAN_ADMIT_TAGGED; break; + case 2: parm->eAdmitMode = GSW_VLAN_ADMIT_UNTAGGED; break; + default: - break; + break; } /* ----- end switch ----- */ + /** bSVLAN_MACbasedTag */ gsw_r32(cdev, (PCE_VCTRL_MACEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_MACEN_SHIFT, PCE_VCTRL_MACEN_SIZE, &value); parm->bSVLAN_MACbasedTag = value; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_SVLAN_PortCfgSet(void *cdev, - GSW_SVLAN_portCfg_t *parm) + GSW_SVLAN_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { value = parm->nPortVId; gsw_w32(cdev, (PCE_DEFPSVID_PVID_OFFSET + - (2 * parm->nPortId)), + (2 * parm->nPortId)), PCE_DEFPSVID_PVID_SHIFT, PCE_DEFPSVID_PVID_SIZE, value); /* bSVLAN_TagSupport */ value = parm->bSVLAN_TagSupport; gsw_w32(cdev, (PCE_VCTRL_STEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_STEN_SHIFT, PCE_VCTRL_STEN_SIZE, value); + if (parm->bSVLAN_TagSupport == 1) { - gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + - (6 * parm->nPortId)), - FDMA_PCTRL_SVLANMOD_SHIFT, - FDMA_PCTRL_SVLANMOD_SIZE, 3); - } else { - gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + - (6 * parm->nPortId)), - FDMA_PCTRL_SVLANMOD_SHIFT, - FDMA_PCTRL_SVLANMOD_SIZE, 0); - } + gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + + (6 * parm->nPortId)), + FDMA_PCTRL_SVLANMOD_SHIFT, + FDMA_PCTRL_SVLANMOD_SIZE, 3); + } else { + gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + + (6 * parm->nPortId)), + FDMA_PCTRL_SVLANMOD_SHIFT, + FDMA_PCTRL_SVLANMOD_SIZE, 0); + } + /** bVLAN_ReAssign */ value = parm->bVLAN_ReAssign; gsw_w32(cdev, (PCE_VCTRL_SVSR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVSR_SHIFT, PCE_VCTRL_SVSR_SIZE, value); + /** eVLAN_MemberViolation */ switch (parm->eVLAN_MemberViolation) { case GSW_VLAN_MEMBER_VIOLATION_NO: gsw_w32(cdev, (PCE_VCTRL_SVIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVIMR_SHIFT, PCE_VCTRL_SVIMR_SIZE, 0); gsw_w32(cdev, (PCE_VCTRL_SVEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVEMR_SHIFT, PCE_VCTRL_SVEMR_SIZE, 0); break; + case GSW_VLAN_MEMBER_VIOLATION_INGRESS: gsw_w32(cdev, (PCE_VCTRL_SVIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVIMR_SHIFT, PCE_VCTRL_SVIMR_SIZE, 1); gsw_w32(cdev, (PCE_VCTRL_SVEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVEMR_SHIFT, PCE_VCTRL_SVEMR_SIZE, 0); break; + case GSW_VLAN_MEMBER_VIOLATION_EGRESS: gsw_w32(cdev, (PCE_VCTRL_SVIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVIMR_SHIFT, PCE_VCTRL_SVIMR_SIZE, 0); gsw_w32(cdev, (PCE_VCTRL_SVEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVEMR_SHIFT, PCE_VCTRL_SVEMR_SIZE, 1); break; + case GSW_VLAN_MEMBER_VIOLATION_BOTH: gsw_w32(cdev, (PCE_VCTRL_SVIMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVIMR_SHIFT, PCE_VCTRL_SVIMR_SIZE, 1); gsw_w32(cdev, (PCE_VCTRL_SVEMR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVEMR_SHIFT, PCE_VCTRL_SVEMR_SIZE, 1); break; } /* ----- end switch ----- */ + /** eAdmitMode */ switch (parm->eAdmitMode) { case GSW_VLAN_ADMIT_ALL: value = 0; break; + case GSW_VLAN_ADMIT_TAGGED: value = 1; break; + case GSW_VLAN_ADMIT_UNTAGGED: value = 2; break; + default: value = 0; } /* ----- end switch ----- */ + gsw_w32(cdev, (PCE_VCTRL_SVINR_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_SVINR_SHIFT, PCE_VCTRL_SVINR_SIZE, value); /** bSVLAN_MACbasedTag */ value = parm->bSVLAN_MACbasedTag; gsw_w32(cdev, (PCE_VCTRL_MACEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_VCTRL_MACEN_SHIFT, PCE_VCTRL_MACEN_SIZE, value); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortGet(void *cdev, - GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm) + GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value, dei; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { for (value = 0; value < 16; value++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = (((parm->nPortId & 0xF) << 4) - | (value)); + | (value)); pcetable.table = PCE_EGREMARK_INDEX; gsw_pce_table_read(cdev, &pcetable); parm->nDSCP[value] = (pcetable.val[0] & 0x3F); @@ -5132,30 +6544,47 @@ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortGet(void *cdev, parm->nSPCP[value] |= (dei << 7); } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortSet(void *cdev, - GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm) + GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; u8 cpcp, dscp, spcp, dei; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_3_0)) { for (value = 0; value < 16; value++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = (((parm->nPortId & 0xF) << 4) - | (value)); + | (value)); dscp = parm->nDSCP[value] & 0x3F; spcp = parm->nSPCP[value] & 0x7; cpcp = parm->nCPCP[value] & 0x7; @@ -5166,61 +6595,93 @@ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortSet(void *cdev, gsw_pce_table_write(cdev, &pcetable); } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_SVLAN_PCP_ClassGet(void *cdev, - GSW_QoS_SVLAN_PCP_ClassCfg_t *parm) + GSW_QoS_SVLAN_PCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t ptbl; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { memset(&ptbl, 0, sizeof(pctbl_prog_t)); + for (value = 0; value < 16; value++) { ptbl.table = PCE_SPCP_INDEX; ptbl.pcindex = value; gsw_pce_table_read(cdev, &ptbl); parm->nTrafficClass[value] = ptbl.val[0] & 0xF; - + /*Following are not applicable for GSWIP 3.1*/ - if(gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { parm->nTrafficColor[value] = ((ptbl.val[0] >> 6) & 0x3); parm->nPCP_Remark_Enable[value] = ((ptbl.val[0] >> 4) & 0x1); parm->nDEI_Remark_Enable[value] = ((ptbl.val[0] >> 5) & 0x1); } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_SVLAN_PCP_ClassSet(void *cdev, - GSW_QoS_SVLAN_PCP_ClassCfg_t *parm) + GSW_QoS_SVLAN_PCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { pctbl_prog_t pcetable; u32 value; + for (value = 0; value < 16; value++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_SPCP_INDEX; pcetable.pcindex = value; pcetable.val[0] = parm->nTrafficClass[value] & 0xF; - + /*Following are not applicable for GSWIP 3.1*/ - if(gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { pcetable.val[0] |= (parm->nTrafficColor[value] & 0x3) << 6; pcetable.val[0] |= @@ -5228,26 +6689,46 @@ GSW_return_t GSW_QoS_SVLAN_PCP_ClassSet(void *cdev, pcetable.val[0] |= (parm->nDEI_Remark_Enable[value] & 0x1) << 5; } - gsw_pce_table_write(cdev, &pcetable); - } + + gsw_pce_table_write(cdev, &pcetable); + } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } + #endif /*CONFIG_LTQ_VLAN */ + + #if defined(CONFIG_LTQ_QOS) && CONFIG_LTQ_QOS + GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, - GSW_QoS_meterCfg_t *parm) + GSW_QoS_meterCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 mid = parm->nMeterId, value, exp, mant, ibs; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { - if (mid > gswdev->num_of_meters) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { + if (mid > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_w32(cdev, GSW_INST_SEL_INST_OFFSET, GSW_INST_SEL_INST_SHIFT, GSW_INST_SEL_INST_SIZE, mid); @@ -5274,22 +6755,23 @@ GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, gsw_r32(cdev, GSW_PCE_TCM_CIR_MANT_MANT_OFFSET, GSW_PCE_TCM_CIR_MANT_MANT_SHIFT, GSW_PCE_TCM_CIR_MANT_MANT_SIZE, &mant); - /* Rate Counter iBS */ - if(gswdev->gipver == LTQ_GSWIP_3_1) + + /* Rate Counter iBS */ + if (IS_VRSN_31(gswdev->gipver)) gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE_GSWIP_3_1, &ibs); else - gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, + gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE, &ibs); /* calc the Rate */ - if(gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) parm->nRate = mratecalc_3_1(ibs, exp, mant); else parm->nRate = mratecalc(ibs, exp, mant); - + /* Rate Counter Exponent */ gsw_r32(cdev, GSW_PCE_TCM_PIR_EXP_EXP_OFFSET, GSW_PCE_TCM_PIR_EXP_EXP_SHIFT, @@ -5298,34 +6780,38 @@ GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, gsw_r32(cdev, GSW_PCE_TCM_PIR_MANT_MANT_OFFSET, GSW_PCE_TCM_PIR_MANT_MANT_SHIFT, GSW_PCE_TCM_PIR_MANT_MANT_SIZE, &mant); - /* Rate Counter iBS */ - if(gswdev->gipver == LTQ_GSWIP_3_1) + + /* Rate Counter iBS */ + if (IS_VRSN_31(gswdev->gipver)) gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE_GSWIP_3_1, &ibs); else - gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, + gsw_r32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE, &ibs); /* calc the Rate */ - if(gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) parm->nPiRate = mratecalc_3_1(ibs, exp, mant); else parm->nPiRate = mratecalc(ibs, exp, mant); - - /* parm->nPbs=??? how to calculate it*/ + + /* parm->nPbs=??? how to calculate it*/ gsw_r32(cdev, GSW_PCE_TCM_CTRL_TMOD_OFFSET, GSW_PCE_TCM_CTRL_TMOD_SHIFT, GSW_PCE_TCM_CTRL_TMOD_SIZE, &parm->eMtrType); - - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) gsw_r32(cdev, GSW_PCE_TCM_CTRL_BLIND_OFFSET, GSW_PCE_TCM_CTRL_BLIND_SHIFT, GSW_PCE_TCM_CTRL_BLIND_SIZE, &parm->nColourBlindMode); } else { - if (mid > 7) - return GSW_statusErr; + if (mid > 7) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Enable/Disable the meter shaper */ gsw_r32(cdev, (PCE_TCM_CTRL_TCMEN_OFFSET + (mid * 7)), PCE_TCM_CTRL_TCMEN_SHIFT, @@ -5349,57 +6835,82 @@ GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, gsw_r32(cdev, (PCE_TCM_CIR_MANT_MANT_OFFSET + (mid * 7)), PCE_TCM_CIR_MANT_MANT_SHIFT, PCE_TCM_CIR_MANT_MANT_SIZE, &mant); - /* Rate Counter iBS */ + /* Rate Counter iBS */ gsw_r32(cdev, (PCE_TCM_IBS_IBS_OFFSET + (mid * 7)), PCE_TCM_IBS_IBS_SHIFT, PCE_TCM_IBS_IBS_SIZE, &ibs); /* calc the Rate */ parm->nRate = mratecalc(ibs, exp, mant); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, - GSW_QoS_meterCfg_t *parm) + GSW_QoS_meterCfg_t *parm) { u32 mid, cbs, ebs, exp = 0, mant = 0, rate, ibs = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + mid = parm->nMeterId; - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { - if (mid > gswdev->num_of_meters) - return GSW_statusErr; + + if (IS_VRSN_30_31(gswdev->gipver)) { + if (mid > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_w32(cdev, GSW_INST_SEL_INST_OFFSET, GSW_INST_SEL_INST_SHIFT, GSW_INST_SEL_INST_SIZE, mid); + /* Committed Burst Size */ if (parm->nCbs > 0xFFC0) cbs = 0x3FF; else cbs = ((parm->nCbs + 63) / 64); + gsw_w32(cdev, GSW_PCE_TCM_CBS_CBS_OFFSET, GSW_PCE_TCM_CBS_CBS_SHIFT, GSW_PCE_TCM_CBS_CBS_SIZE, cbs); + /* Excess Burst Size (EBS [bytes]) */ if (parm->nEbs > 0xFFC0) ebs = 0x3FF; else ebs = ((parm->nEbs + 63) / 64); + gsw_w32(cdev, GSW_PCE_TCM_EBS_EBS_OFFSET, GSW_PCE_TCM_EBS_EBS_SHIFT, GSW_PCE_TCM_EBS_EBS_SIZE, ebs); /* Calc the Rate and convert to MANT and EXP*/ rate = parm->nRate; + if (rate) { - if(gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) calc_mtoken_3_1(rate, &ibs, &exp, &mant); else calc_mtoken(rate, &ibs, &exp, &mant); } + /* Rate Counter Exponent */ gsw_w32(cdev, GSW_PCE_TCM_CIR_EXP_EXP_OFFSET, GSW_PCE_TCM_CIR_EXP_EXP_SHIFT, @@ -5408,8 +6919,9 @@ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, gsw_w32(cdev, GSW_PCE_TCM_CIR_MANT_MANT_OFFSET, GSW_PCE_TCM_CIR_MANT_MANT_SHIFT, GSW_PCE_TCM_CIR_MANT_MANT_SIZE, mant); + /* Rate Counter iBS */ - if(gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) gsw_w32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE_GSWIP_3_1, ibs); @@ -5417,15 +6929,17 @@ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, gsw_w32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, GSW_PCE_TCM_IBS_IBS_SHIFT, GSW_PCE_TCM_IBS_IBS_SIZE_GSWIP_3_1, ibs); - + /* Calc the Rate and convert to MANT and EXP*/ rate = parm->nPiRate; + if (rate) { - if(gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) calc_mtoken_3_1(rate, &ibs, &exp, &mant); else calc_mtoken(rate, &ibs, &exp, &mant); } + /* Rate Counter Exponent */ gsw_w32(cdev, GSW_PCE_TCM_PIR_EXP_EXP_OFFSET, GSW_PCE_TCM_PIR_EXP_EXP_SHIFT, @@ -5435,9 +6949,9 @@ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, GSW_PCE_TCM_PIR_MANT_MANT_SHIFT, GSW_PCE_TCM_PIR_MANT_MANT_SIZE, mant); /* Rate Counter iBS */ -/* gsw_w32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, */ -/* GSW_PCE_TCM_IBS_IBS_SHIFT,*/ -/* GSW_PCE_TCM_IBS_IBS_SIZE, ibs);*/ + /* gsw_w32(cdev, GSW_PCE_TCM_IBS_IBS_OFFSET, */ + /* GSW_PCE_TCM_IBS_IBS_SHIFT,*/ + /* GSW_PCE_TCM_IBS_IBS_SIZE, ibs);*/ gsw_w32(cdev, GSW_PCE_TCM_CTRL_TMOD_OFFSET, GSW_PCE_TCM_CTRL_TMOD_SHIFT, GSW_PCE_TCM_CTRL_TMOD_SIZE, parm->eMtrType); @@ -5445,146 +6959,192 @@ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, gsw_w32(cdev, GSW_PCE_TCM_CTRL_TCMEN_OFFSET, GSW_PCE_TCM_CTRL_TCMEN_SHIFT, GSW_PCE_TCM_CTRL_TCMEN_SIZE, parm->bEnable); - - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) gsw_w32(cdev, GSW_PCE_TCM_CTRL_BLIND_OFFSET, GSW_PCE_TCM_CTRL_BLIND_SHIFT, GSW_PCE_TCM_CTRL_BLIND_SIZE, parm->nColourBlindMode); } else { - if (mid > 7) - return GSW_statusErr; + if (mid > 7) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Committed Burst Size */ if (parm->nCbs > 0xFFC0) cbs = 0x3FF; else cbs = ((parm->nCbs + 63) / 64); + gsw_w32(cdev, (PCE_TCM_CBS_CBS_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_CBS_CBS_SHIFT, PCE_TCM_CBS_CBS_SIZE, cbs); + /* Excess Burst Size (EBS [bytes]) */ if (parm->nEbs > 0xFFC0) ebs = 0x3FF; else ebs = ((parm->nEbs + 63) / 64); + gsw_w32(cdev, (PCE_TCM_EBS_EBS_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_EBS_EBS_SHIFT, PCE_TCM_EBS_EBS_SIZE, ebs); /* Calc the Rate and convert to MANT and EXP*/ rate = parm->nRate; + if (rate) calc_mtoken(rate, &ibs, &exp, &mant); + /* Rate Counter Exponent */ gsw_w32(cdev, (PCE_TCM_CIR_EXP_EXP_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_CIR_EXP_EXP_SHIFT, PCE_TCM_CIR_EXP_EXP_SIZE, exp); /* Rate Counter Mantissa */ gsw_w32(cdev, (PCE_TCM_CIR_MANT_MANT_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_CIR_MANT_MANT_SHIFT, PCE_TCM_CIR_MANT_MANT_SIZE, mant); /* Rate Counter iBS */ gsw_w32(cdev, (PCE_TCM_IBS_IBS_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_IBS_IBS_SHIFT, PCE_TCM_IBS_IBS_SIZE, ibs); /* Enable/Disable the meter shaper */ gsw_w32(cdev, (PCE_TCM_CTRL_TCMEN_OFFSET + - (mid * 7)), + (mid * 7)), PCE_TCM_CTRL_TCMEN_SHIFT, PCE_TCM_CTRL_TCMEN_SIZE, parm->bEnable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_MeterPortAssign(void *cdev, - GSW_QoS_meterPort_t *parm) + GSW_QoS_meterPort_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; + u32 ret; u32 eport, iport, value1, value2; ltq_bool_t eftbl = 0, nempftbl = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver == LTQ_GSWIP_3_1) - { /* GSW_QoS_MeterPortAssign should not be called for GSWIP3.1 + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (IS_VRSN_31(gswdev->gipver)) { + /* GSW_QoS_MeterPortAssign should not be called for GSWIP3.1 Meter should be assigned during CTP/Bridge Port Config*/ - return GSW_statusNoSupport; + ret = GSW_statusNoSupport; + goto UNLOCK_AND_RETURN; } + memset(&pcetable, 0, sizeof(pctbl_prog_t)); value1 = 0; + while (value1 < 8) { pcetable.table = PCE_METER_INS_0_INDEX; pcetable.pcindex = value1; gsw_pce_table_read(cdev, &pcetable); + if (pcetable.valid == 1) { iport = pcetable.key[0] & 0xF; eport = (pcetable.key[0] >> 8) & 0xF; + if ((eport == parm->nPortEgressId) && - (iport == parm->nPortIngressId)) { + (iport == parm->nPortIngressId)) { eftbl = 1; value2 = 0; + while (value2 < 8) { pcetable.table = PCE_METER_INS_1_INDEX; pcetable.pcindex = value2; gsw_pce_table_read(cdev, &pcetable); + if (pcetable.valid == 1) { iport = pcetable.key[0] & 0xF; eport = ((pcetable.key[0] >> 8) & 0xF); + if ((eport == parm->nPortEgressId) && - (iport == parm->nPortIngressId)) - return GSW_statusErr; + (iport == parm->nPortIngressId)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } + value2++; } } } + value1++; } + /* Not in the original table, write a new one */ if (eftbl == 0) { value1 = 0; memset(&pcetable, 0, sizeof(pctbl_prog_t)); + /* Search for whole Table 1*/ while (value1 < 8) { pcetable.table = PCE_METER_INS_0_INDEX; pcetable.pcindex = value1; gsw_pce_table_read(cdev, &pcetable); + /* We found the empty one */ if (pcetable.valid == 0) { switch (parm->eDir) { case GSW_DIRECTION_BOTH: pcetable.key[0] = - (((parm->nPortEgressId & 0xF) << 8) - | (parm->nPortIngressId & 0xF)); + (((parm->nPortEgressId & 0xF) << 8) + | (parm->nPortIngressId & 0xF)); pcetable.mask[0] = 0; break; + case GSW_DIRECTION_EGRESS: pcetable.key[0] = - (((parm->nPortEgressId & 0xF) << 8) - | 0xF); + (((parm->nPortEgressId & 0xF) << 8) + | 0xF); pcetable.mask[0] = 1; break; + case GSW_DIRECTION_INGRESS: pcetable.key[0] = (0xF00 | - (parm->nPortIngressId & 0xF)); + (parm->nPortIngressId & 0xF)); pcetable.mask[0] = 4; break; + default: pcetable.key[0] = 0; pcetable.mask[0] = 5; } + pcetable.val[0] = parm->nMeterId & 0x3F; pcetable.valid = 1; gsw_pce_table_write(cdev, &pcetable); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } + value1++; } + if (value1 >= 8) nempftbl = 1; } @@ -5593,80 +7153,108 @@ GSW_return_t GSW_QoS_MeterPortAssign(void *cdev, if ((nempftbl == 1) || (eftbl == 1)) { value2 = 0; memset(&pcetable, 0, sizeof(pctbl_prog_t)); + while (value2 < 8) { pcetable.table = PCE_METER_INS_1_INDEX; pcetable.pcindex = value2; gsw_pce_table_read(cdev, &pcetable); + /* We found the empty one */ if (pcetable.valid == 0) { switch (parm->eDir) { case GSW_DIRECTION_BOTH: pcetable.key[0] = - (((parm->nPortEgressId & 0xF) << 8) | - (parm->nPortIngressId & 0xF)); + (((parm->nPortEgressId & 0xF) << 8) | + (parm->nPortIngressId & 0xF)); pcetable.mask[0] = 0; break; + case GSW_DIRECTION_EGRESS: pcetable.key[0] = - (((parm->nPortEgressId & 0xF) << 8) - | 0xF); + (((parm->nPortEgressId & 0xF) << 8) + | 0xF); pcetable.mask[0] = 1; break; + case GSW_DIRECTION_INGRESS: pcetable.key[0] = (0xF00 | - (parm->nPortIngressId & 0xF)); + (parm->nPortIngressId & 0xF)); pcetable.mask[0] = 4; break; + default: pcetable.key[0] = 0; pcetable.mask[0] = 5; } + pcetable.val[0] = parm->nMeterId & 0x3F; pcetable.valid = 1; gsw_pce_table_write(cdev, &pcetable); nempftbl = 0; - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } + value2++; } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_MeterPortDeassign(void *cdev, - GSW_QoS_meterPort_t *parm) + GSW_QoS_meterPort_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 eport, iport, mid, i, j; ltq_bool_t eftbl = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + for (i = 0; i < 2; i++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); + if (i == 0) pcetable.table = PCE_METER_INS_0_INDEX; else pcetable.table = PCE_METER_INS_1_INDEX; + for (j = 0; j < 8; j++) { pcetable.pcindex = j; gsw_pce_table_read(cdev, &pcetable); + if (pcetable.valid == 1) { iport = pcetable.key[0] & 0xF; eport = (pcetable.key[0] >> 8) & 0xF; mid = pcetable.val[0] & 0x1F; + if ((eport == parm->nPortEgressId) && - (iport == parm->nPortIngressId) && - (mid == parm->nMeterId)) { + (iport == parm->nPortIngressId) && + (mid == parm->nMeterId)) { if (i == 0) pcetable.table = - PCE_METER_INS_0_INDEX; + PCE_METER_INS_0_INDEX; else pcetable.table = - PCE_METER_INS_1_INDEX; + PCE_METER_INS_1_INDEX; + pcetable.key[0] = 0; pcetable.val[0] = 0; pcetable.valid = 0; @@ -5678,24 +7266,39 @@ GSW_return_t GSW_QoS_MeterPortDeassign(void *cdev, } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_MeterPortGet(void *cdev, - GSW_QoS_meterPortGet_t *parm) + GSW_QoS_meterPortGet_t *parm) { pctbl_prog_t pcetable; u32 value = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&pcetable, 0, sizeof(pctbl_prog_t)); -/* gsw_r32(cdev, ETHSW_CAP_3_METERS_OFFSET,*/ -/* ETHSW_CAP_3_METERS_SHIFT,*/ -/* ETHSW_CAP_3_METERS_SIZE, &value); */ + /* gsw_r32(cdev, ETHSW_CAP_3_METERS_OFFSET,*/ + /* ETHSW_CAP_3_METERS_SHIFT,*/ + /* ETHSW_CAP_3_METERS_SIZE, &value); */ value = gswdev->num_of_meters; + if (parm->bInitial == 1) { gswdev->meter_cnt = 0; parm->bInitial = 0; @@ -5711,12 +7314,14 @@ GSW_return_t GSW_QoS_MeterPortGet(void *cdev, pcetable.pcindex = gswdev->meter_cnt; gsw_pce_table_read(cdev, &pcetable); + if (pcetable.valid) { parm->nMeterId = (pcetable.val[0] & 0x3F); parm->nPortEgressId = ((pcetable.key[0] >> 8) & 0xF); parm->nPortIngressId = (pcetable.key[0] & 0xF); + if ((pcetable.mask[0] & 0x5) == 0) - parm->eDir = GSW_DIRECTION_BOTH; + parm->eDir = GSW_DIRECTION_BOTH; else if ((pcetable.mask[0] & 0x5) == 1) parm->eDir = GSW_DIRECTION_EGRESS; else if ((pcetable.mask[0] & 0x5) == 4) @@ -5724,49 +7329,68 @@ GSW_return_t GSW_QoS_MeterPortGet(void *cdev, else parm->eDir = GSW_DIRECTION_NONE; } + gswdev->meter_cnt++; - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_DSCP_ClassGet(void *cdev, - GSW_QoS_DSCP_ClassCfg_t *parm) + GSW_QoS_DSCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + for (value = 0; value <= 63; value++) { pcetable.table = PCE_DSCP_INDEX; pcetable.pcindex = value; gsw_pce_table_read(cdev, &pcetable); parm->nTrafficClass[value] = (pcetable.val[0] & 0xF); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_DSCP_ClassSet(void *cdev, - GSW_QoS_DSCP_ClassCfg_t *parm) + GSW_QoS_DSCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -#if 0 - memset(&pcetable, 0, sizeof(pctbl_prog_t)); - pcetable.table = PCE_DSCP_INDEX; - /* index of the DSCP configuration */ - pcetable.pcindex = parm->nDSCP; - gsw_pce_table_read(cdev, &pcetable); - pcetable.val[0] &= ~(0xFF); - pcetable.val[0] |= (parm->nTrafficClass[parm->nDSCP] & 0xFF); - gsw_pce_table_write(cdev, &pcetable); -#else + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + for (value = 0; value <= 63; value++) { pcetable.table = PCE_DSCP_INDEX; pcetable.pcindex = value; @@ -5775,22 +7399,35 @@ GSW_return_t GSW_QoS_DSCP_ClassSet(void *cdev, pcetable.val[0] |= (parm->nTrafficClass[value] & 0xF); gsw_pce_table_write(cdev, &pcetable); } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); #endif - return GSW_statusOk; + return ret; + } GSW_return_t GSW_QoS_ClassDSCP_Get(void *cdev, - GSW_QoS_ClassDSCP_Cfg_t *parm) + GSW_QoS_ClassDSCP_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_0 || - gswdev->gipver != LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (gswdev->gipver != LTQ_GSWIP_3_0 || + IS_VRSN_NOT_31(gswdev->gipver)) { for (value = 0; value < 16; value++) { pcetable.table = PCE_REMARKING_INDEX; pcetable.pcindex = value; @@ -5798,23 +7435,40 @@ GSW_return_t GSW_QoS_ClassDSCP_Get(void *cdev, parm->nDSCP[value] = pcetable.val[0] & 0x3F; } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_ClassDSCP_Set(void *cdev, - GSW_QoS_ClassDSCP_Cfg_t *parm) + GSW_QoS_ClassDSCP_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 dscp, pcp, value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_0 - || gswdev->gipver != LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (gswdev->gipver != LTQ_GSWIP_3_0 + || IS_VRSN_NOT_31(gswdev->gipver)) { for (value = 0; value < 16; value++) { pcetable.table = PCE_REMARKING_INDEX; pcetable.pcindex = value; @@ -5825,21 +7479,37 @@ GSW_return_t GSW_QoS_ClassDSCP_Set(void *cdev, gsw_pce_table_write(cdev, &pcetable); } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgGet(void *cdev, - GSW_QoS_DSCP_DropPrecedenceCfg_t *parm) + GSW_QoS_DSCP_DropPrecedenceCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + for (value = 0; value <= 63; value++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_DSCP_INDEX; @@ -5848,30 +7518,32 @@ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgGet(void *cdev, parm->nDSCP_DropPrecedence[value] = ((pcetable.val[0] >> 4) & 0x3); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgSet(void *cdev, - GSW_QoS_DSCP_DropPrecedenceCfg_t *parm) + GSW_QoS_DSCP_DropPrecedenceCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -#if 0 - memset(&pcetable, 0, sizeof(pctbl_prog_t)); - pcetable.table = PCE_DSCP_INDEX; - /* index of the DSCP configuration*/ - pcetable.pcindex = parm->nDSCP; - gsw_pce_table_read(cdev, &pcetable); - pcetable.val[0] &= ~(0x3 << 4); - pcetable.val[0] |= - ((parm->nDSCP_DropPrecedence[parm->nDSCP] & 0x3) << 4); - gsw_pce_table_write(cdev, &pcetable); -#else + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + for (value = 0; value <= 63; value++) { memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_DSCP_INDEX; @@ -5879,182 +7551,244 @@ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgSet(void *cdev, gsw_pce_table_read(cdev, &pcetable); pcetable.val[0] &= ~(0x3 << 4); pcetable.val[0] |= - ((parm->nDSCP_DropPrecedence[value] & 0x3) << 4); + ((parm->nDSCP_DropPrecedence[value] & 0x3) << 4); gsw_pce_table_write(cdev, &pcetable); } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); #endif - return GSW_statusOk; + return ret; + } GSW_return_t GSW_QoS_PortRemarkingCfgGet(void *cdev, - GSW_QoS_portRemarkingCfg_t *parm) + GSW_QoS_portRemarkingCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value, vclpen = 0, vdpen = 0, vdscpmod = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Applicable for 3.1 also*/ gsw_r32(cdev, (PCE_PCTRL_0_CLPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_CLPEN_SHIFT, PCE_PCTRL_0_CLPEN_SIZE, &vclpen); /*Applicable only for 3.0 and below switch version*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_r32(cdev, (PCE_PCTRL_0_DPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_DPEN_SHIFT, PCE_PCTRL_0_DPEN_SIZE, &vdpen); gsw_r32(cdev, (PCE_PCTRL_2_DSCPMOD_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCPMOD_SHIFT, PCE_PCTRL_2_DSCPMOD_SIZE, &vdscpmod); } - + /*Applicable only for 3.0 and below switch version*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if ((vclpen == 0) && (vdpen == 0) - && (vdscpmod == 0)) + && (vdscpmod == 0)) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_DISABLE; + GSW_DSCP_REMARK_DISABLE; else if ((vclpen == 1) && (vdpen == 0) - && (vdscpmod == 1)) + && (vdscpmod == 1)) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_TC6; + GSW_DSCP_REMARK_TC6; else if ((vclpen == 1) && (vdpen == 1) && - (vdscpmod == 1)) + (vdscpmod == 1)) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_TC3; + GSW_DSCP_REMARK_TC3; else if ((vclpen == 0) && (vdpen == 1) && - (vdscpmod == 1)) + (vdscpmod == 1)) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_DP3; + GSW_DSCP_REMARK_DP3; else if ((vclpen == 1) && (vdpen == 1) && - (vdscpmod == 1)) + (vdscpmod == 1)) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_DP3_TC3; + GSW_DSCP_REMARK_DP3_TC3; } - + /*Applicable only for 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (vclpen == 0) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_DISABLE; + GSW_DSCP_REMARK_DISABLE; else if (vclpen == 1) parm->eDSCP_IngressRemarkingEnable = - GSW_DSCP_REMARK_TC6; + GSW_DSCP_REMARK_TC6; } /*PCP Remarking Enable/Disable,Applicable for 3.1 also*/ gsw_r32(cdev, (PCE_PCTRL_0_PCPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_PCPEN_SHIFT, PCE_PCTRL_0_PCPEN_SIZE, &value); parm->bPCP_IngressRemarkingEnable = value; - + /*DSCP Remarking Enable/Disable,Applicable for 3.1 also*/ gsw_r32(cdev, (FDMA_PCTRL_DSCPRM_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_DSCPRM_SHIFT, FDMA_PCTRL_DSCPRM_SIZE, &value); parm->bDSCP_EgressRemarkingEnable = value; - + /*Applicable only for 3.0 and below switch version*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_r32(cdev, (FDMA_PCTRL_VLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_VLANMOD_SHIFT, FDMA_PCTRL_VLANMOD_SIZE, &value); + if (value == 3) parm->bPCP_EgressRemarkingEnable = 1; else parm->bPCP_EgressRemarkingEnable = 0; } - + /*Applicable only for 3.1 FDMA_PCTRL_VLANMOD is reduced to 1 bit in GSWIP 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - /*JIRA GSWIP-147 Implemented*/ + if (IS_VRSN_31(gswdev->gipver)) { + /*JIRA GSWIP-147 Implemented*/ gsw_r32(cdev, (FDMA_PCTRL_VLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_VLANMOD_SHIFT, FDMA_GSWIP3_1_PCTRL_VLANMOD_SIZE, &value); + if (value == 1) parm->bPCP_EgressRemarkingEnable = 1; else parm->bPCP_EgressRemarkingEnable = 0; } - + /*The following are not applicable for GSWIP 3.1*/ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_r32(cdev, (PCE_PCTRL_2_SPCPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCPEN_SHIFT, PCE_PCTRL_2_SPCPEN_SIZE, &parm->bSTAG_PCP_IngressRemarkingEnable); gsw_r32(cdev, (PCE_PCTRL_2_SDEIEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SDEIEN_SHIFT, PCE_PCTRL_2_SDEIEN_SIZE, &parm->bSTAG_DEI_IngressRemarkingEnable); gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_SVLANMOD_SHIFT, FDMA_PCTRL_SVLANMOD_SIZE, value); + if (value == 3) parm->bSTAG_PCP_DEI_EgressRemarkingEnable = 1; else parm->bSTAG_PCP_DEI_EgressRemarkingEnable = 0; - } - return GSW_statusOk; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, - GSW_QoS_portRemarkingCfg_t *parm) + GSW_QoS_portRemarkingCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value, vclpen = 0, vdpen = 0, vdscpmod = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + switch (parm->eDSCP_IngressRemarkingEnable) { case GSW_DSCP_REMARK_DISABLE: - vclpen = 0; vdpen = 0; vdscpmod = 0; + vclpen = 0; + vdpen = 0; + vdscpmod = 0; break; + case GSW_DSCP_REMARK_TC6: - vclpen = 1; vdpen = 0; vdscpmod = 1; + vclpen = 1; + vdpen = 0; + vdscpmod = 1; break; + case GSW_DSCP_REMARK_TC3: - vclpen = 1; vdpen = 1; vdscpmod = 1; + vclpen = 1; + vdpen = 1; + vdscpmod = 1; + /*Not supported in GSWIP 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + break; + case GSW_DSCP_REMARK_DP3: - vclpen = 0; vdpen = 1; vdscpmod = 1; + vclpen = 0; + vdpen = 1; + vdscpmod = 1; + /*Not supported in GSWIP 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + break; + case GSW_DSCP_REMARK_DP3_TC3: - vclpen = 1; vdpen = 1; + vclpen = 1; + vdpen = 1; vdscpmod = 1; + /*Not supported in GSWIP 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + break; } - + /*Applicable for 3.1 also*/ gsw_w32(cdev, PCE_PCTRL_0_CLPEN_OFFSET + (10 * parm->nPortId), @@ -6062,7 +7796,7 @@ GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, PCE_PCTRL_0_CLPEN_SIZE, vclpen); /*The following are not applicable for GSWIP 3.1*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_w32(cdev, PCE_PCTRL_0_DPEN_OFFSET + (10 * parm->nPortId), PCE_PCTRL_0_DPEN_SHIFT, @@ -6072,63 +7806,67 @@ GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, PCE_PCTRL_2_DSCPMOD_SHIFT, PCE_PCTRL_2_DSCPMOD_SIZE, vdscpmod); } - + /*DSCP Remarking Enable/Disable,Applicable for 3.1 also*/ if (parm->bDSCP_EgressRemarkingEnable > 0) value = parm->bDSCP_EgressRemarkingEnable; else value = 0; + gsw_w32(cdev, (FDMA_PCTRL_DSCPRM_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_DSCPRM_SHIFT, FDMA_PCTRL_DSCPRM_SIZE, value); - + /*PCP Remarking Enable/Disable,Applicable for 3.1 also*/ if (parm->bPCP_IngressRemarkingEnable > 0) value = parm->bPCP_IngressRemarkingEnable; else value = 0; + gsw_w32(cdev, (PCE_PCTRL_0_PCPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_0_PCPEN_SHIFT, PCE_PCTRL_0_PCPEN_SIZE, value); /*Applicable only for 3.0 and below switch version*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (parm->bPCP_EgressRemarkingEnable > 0) value = 3; else value = 0; + gsw_w32(cdev, (FDMA_PCTRL_VLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_VLANMOD_SHIFT, FDMA_PCTRL_VLANMOD_SIZE, value); } - + /*FDMA_PCTRL_VLANMOD is reduced to 1 bit in GSWIP 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1){ + if (IS_VRSN_31(gswdev->gipver)) { if (parm->bPCP_EgressRemarkingEnable > 0) value = 1; else value = 0; - /*JIRA GSWIP-147 Implemented*/ + + /*JIRA GSWIP-147 Implemented*/ gsw_w32(cdev, (FDMA_PCTRL_VLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_VLANMOD_SHIFT, FDMA_GSWIP3_1_PCTRL_VLANMOD_SIZE, value); } - + /*The following are not applicable for GSWIP 3.1*/ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_w32(cdev, (PCE_PCTRL_2_SPCPEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCPEN_SHIFT, PCE_PCTRL_2_SPCPEN_SIZE, parm->bSTAG_PCP_IngressRemarkingEnable); gsw_w32(cdev, (PCE_PCTRL_2_SDEIEN_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SDEIEN_SHIFT, PCE_PCTRL_2_SDEIEN_SIZE, parm->bSTAG_DEI_IngressRemarkingEnable); @@ -6138,32 +7876,48 @@ GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, value = 3; else value = 0; -/* gsw_w32(cdev, (FDMA_PCTRL_DEIMOD_OFFSET + */ -/* (6 * parm->nPortId)), */ -/* FDMA_PCTRL_DEIMOD_SHIFT,*/ -/* FDMA_PCTRL_DEIMOD_SIZE,*/ -/* parm->bSTAG_PCP_DEI_EgressRemarkingEnable); */ + + /* gsw_w32(cdev, (FDMA_PCTRL_DEIMOD_OFFSET + */ + /* (6 * parm->nPortId)), */ + /* FDMA_PCTRL_DEIMOD_SHIFT,*/ + /* FDMA_PCTRL_DEIMOD_SIZE,*/ + /* parm->bSTAG_PCP_DEI_EgressRemarkingEnable); */ gsw_w32(cdev, (FDMA_PCTRL_SVLANMOD_OFFSET + - (6 * parm->nPortId)), + (6 * parm->nPortId)), FDMA_PCTRL_SVLANMOD_SHIFT, FDMA_PCTRL_SVLANMOD_SIZE, value); } - - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_ClassPCP_Get(void *cdev, - GSW_QoS_ClassPCP_Cfg_t *parm) + GSW_QoS_ClassPCP_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (gswdev->gipver != LTQ_GSWIP_3_0 || - gswdev->gipver != LTQ_GSWIP_3_1) { + IS_VRSN_NOT_31(gswdev->gipver)) { for (value = 0; value < 16; value++) { pcetable.table = PCE_REMARKING_INDEX; pcetable.pcindex = value; @@ -6171,23 +7925,40 @@ GSW_return_t GSW_QoS_ClassPCP_Get(void *cdev, parm->nPCP[value] = (pcetable.val[0] >> 8) & 0x7; } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_ClassPCP_Set(void *cdev, - GSW_QoS_ClassPCP_Cfg_t *parm) + GSW_QoS_ClassPCP_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 dscp, pcp, value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (gswdev->gipver != LTQ_GSWIP_3_0 || - gswdev->gipver != LTQ_GSWIP_3_1) { + IS_VRSN_NOT_31(gswdev->gipver)) { for (value = 0; value < 16; value++) { pcetable.table = PCE_REMARKING_INDEX; pcetable.pcindex = value; @@ -6198,78 +7969,132 @@ GSW_return_t GSW_QoS_ClassPCP_Set(void *cdev, gsw_pce_table_write(cdev, &pcetable); } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_PCP_ClassGet(void *cdev, - GSW_QoS_PCP_ClassCfg_t *parm) + GSW_QoS_PCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + u8 inrPcpEntries = PCE_INNER_PCP_DFL_ENTRIES; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - for (value = 0; value < 8; value++) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + + + for (value = 0; value < inrPcpEntries; value++) { + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_PCP_INDEX; pcetable.pcindex = value; gsw_pce_table_read(cdev, &pcetable); parm->nTrafficClass[value] = (pcetable.val[0] & 0xF); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_PCP_ClassSet(void *cdev, - GSW_QoS_PCP_ClassCfg_t *parm) + GSW_QoS_PCP_ClassCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 value; + u32 ret; + u8 inrPcpEntries = PCE_INNER_PCP_DFL_ENTRIES; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - for (value = 0; value < 8; value++) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + + + for (value = 0; value < inrPcpEntries; value++) { + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_PCP_INDEX; pcetable.pcindex = value; pcetable.val[0] = (parm->nTrafficClass[value] & 0xF); gsw_pce_table_write(cdev, &pcetable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_QoS_PortCfgGet(void *cdev, - GSW_QoS_portCfg_t *parm) + GSW_QoS_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value, dscp, cpcp, spcp = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } gsw_r32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, &dscp); gsw_r32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, &cpcp); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_30_31(gswdev->gipver))) { gsw_r32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, &spcp); } - + if ((dscp == 0) && (cpcp == 0) && (spcp == 0)) parm->eClassMode = GSW_QOS_CLASS_SELECT_NO; else if ((dscp == 2) && (cpcp == 0) && (spcp == 0)) @@ -6294,202 +8119,235 @@ GSW_return_t GSW_QoS_PortCfgGet(void *cdev, parm->eClassMode = GSW_QOS_CLASS_SELECT_DSCP_SPCP_PCP; else parm->eClassMode = GSW_QOS_CLASS_SELECT_NO; + /*PCLASS is removed in PCE_PCTRL_2 for GSWIP 3.1*/ - if(gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_r32(cdev, (PCE_PCTRL_2_PCLASS_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCLASS_SHIFT, PCE_PCTRL_2_PCLASS_SIZE, &value); parm->nTrafficClass = value; - } - return GSW_statusOk; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_PortCfgSet(void *cdev, - GSW_QoS_portCfg_t *parm) + GSW_QoS_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + switch (parm->eClassMode) { case GSW_QOS_CLASS_SELECT_NO: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 0); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) - || (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + || (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET - + (10 * parm->nPortId)), + + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 0); } + break; + case GSW_QOS_CLASS_SELECT_DSCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 2); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 0); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 0); } + break; + case GSW_QOS_CLASS_SELECT_PCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 0); gsw_w32(cdev, PCE_PCTRL_2_PCP_OFFSET + (10 * parm->nPortId), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 0); } - break; + + break; + case GSW_QOS_CLASS_SELECT_DSCP_PCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 2); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 0); } + break; + case GSW_QOS_CLASS_SELECT_PCP_DSCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 0); } - break; - if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + + break; + + if ((gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { case GSW_QOS_CLASS_SELECT_SPCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; + case GSW_QOS_CLASS_SELECT_SPCP_DSCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; + case GSW_QOS_CLASS_SELECT_DSCP_SPCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 2); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; + case GSW_QOS_CLASS_SELECT_SPCP_PCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 0); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; + case GSW_QOS_CLASS_SELECT_SPCP_PCP_DSCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; + case GSW_QOS_CLASS_SELECT_DSCP_SPCP_PCP: gsw_w32(cdev, (PCE_PCTRL_2_DSCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_DSCP_SHIFT, PCE_PCTRL_2_DSCP_SIZE, 2); gsw_w32(cdev, (PCE_PCTRL_2_PCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_PCP_SHIFT, PCE_PCTRL_2_PCP_SIZE, 1); gsw_w32(cdev, (PCE_PCTRL_2_SPCP_OFFSET + - (10 * parm->nPortId)), + (10 * parm->nPortId)), PCE_PCTRL_2_SPCP_SHIFT, PCE_PCTRL_2_SPCP_SIZE, 1); break; @@ -6497,54 +8355,73 @@ GSW_return_t GSW_QoS_PortCfgSet(void *cdev, } /*PCLASS is removed in PCE_PCTRL_2 for GSWIP 3.1*/ - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nTrafficClass > 0xF) - return GSW_statusErr; - else + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nTrafficClass > 0xF) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } else { gsw_w32(cdev, PCE_PCTRL_2_PCLASS_OFFSET + (10 * parm->nPortId), PCE_PCTRL_2_PCLASS_SHIFT, PCE_PCTRL_2_PCLASS_SIZE, parm->nTrafficClass); + } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_QueuePortGet(void *cdev, - GSW_QoS_queuePort_t *parm) + GSW_QoS_queuePort_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; u32 sPceBpReg = 0; - + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d\n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_QUEUE_MAP_INDEX; pcetable.pcindex = ((parm->nPortId << 4) | parm->nTrafficClassId); + if ((gswdev->gipver == LTQ_GSWIP_3_0 && parm->bRedirectionBypass) || - (gswdev->gipver == LTQ_GSWIP_3_1 && parm->bExtrationEnable)) { + (IS_VRSN_31(gswdev->gipver) && parm->bExtrationEnable)) { pcetable.pcindex |= (1 << 8); } + gsw_pce_table_read(cdev, &pcetable); parm->nQueueId = (pcetable.val[0] & 0x3F); - if (gswdev->gipver == LTQ_GSWIP_3_1 && parm->bRedirectionBypass) { + if (IS_VRSN_31(gswdev->gipver) && parm->bRedirectionBypass) { /* PCE Bypass Configuration. GSWIP-3.1 only. */ - gsw_r32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), - &sPceBpReg); + gsw_r32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), + &sPceBpReg); GET_VAL_FROM_REG(parm->eQMapMode, SDMA_BYPASS_PCE_MD_SHIFT, SDMA_BYPASS_PCE_MD_SIZE, sPceBpReg); + if (!parm->bExtrationEnable) { GET_VAL_FROM_REG(parm->nQueueId, SDMA_BYPASS_PCE_NMQID_SHIFT, SDMA_BYPASS_PCE_NMQID_SIZE, sPceBpReg); } else { GET_VAL_FROM_REG(parm->nQueueId, SDMA_BYPASS_PCE_EXTQID_SHIFT, SDMA_BYPASS_PCE_EXTQID_SIZE, sPceBpReg); } } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_30_31(gswdev->gipver)) { bmtable.adr.qMapTbl.nQueueId = parm->nQueueId; bmtable.tableID = (BM_Table_ID) BUF_MGR_Q_MAP_TABLE; bmtable.numValues = 1; @@ -6552,65 +8429,84 @@ GSW_return_t GSW_QoS_QueuePortGet(void *cdev, parm->nRedirectPortId = (bmtable.value[0] & 0x7); parm->nRedirectPortId |= ((bmtable.value[0] >> 1) & 0x8); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_QoS_QueuePortSet(void *cdev, - GSW_QoS_queuePort_t *parm) + GSW_QoS_queuePort_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t pcetable; u32 eport = 0, qid, sPceBpReg = 0; - bmtbl_prog_t bmtable={0}; - + bmtbl_prog_t bmtable = {0}; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver==LTQ_GSWIP_3_0 || gswdev->gipver==LTQ_GSWIP_3_1) + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) qid = parm->nQueueId & 0x1F; else qid = parm->nQueueId & 0x3F; - - if (gswdev->gipver == LTQ_GSWIP_3_1 && parm->bRedirectionBypass) { - /* PCE Bypass Configuration. GSWIP-3.1 only. */ - gsw_r32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), - &sPceBpReg); + + if (IS_VRSN_31(gswdev->gipver) && parm->bRedirectionBypass) { + /* PCE Bypass Configuration. GSWIP-3.1 only. */ + gsw_r32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), + &sPceBpReg); + //Populate PCE Bypass control register. - if (!parm->bExtrationEnable) { - if (parm->eQMapMode == GSW_QOS_QMAP_SINGLE_MODE) - CLEAR_FILL_CTRL_REG (sPceBpReg, SDMA_BYPASS_PCE_MD_SHIFT, - SDMA_BYPASS_PCE_MD_SIZE, 1); + if (!parm->bExtrationEnable) { + if (parm->eQMapMode == GSW_QOS_QMAP_SINGLE_MODE) + CLEAR_FILL_CTRL_REG(sPceBpReg, SDMA_BYPASS_PCE_MD_SHIFT, + SDMA_BYPASS_PCE_MD_SIZE, 1); else - CLEAR_FILL_CTRL_REG (sPceBpReg, SDMA_BYPASS_PCE_MD_SHIFT, - SDMA_BYPASS_PCE_MD_SIZE, 0); - CLEAR_FILL_CTRL_REG (sPceBpReg, SDMA_BYPASS_PCE_NMQID_SHIFT, - SDMA_BYPASS_PCE_NMQID_SIZE, qid); - } else - CLEAR_FILL_CTRL_REG (sPceBpReg, SDMA_BYPASS_PCE_EXTQID_SHIFT, - SDMA_BYPASS_PCE_EXTQID_SIZE, qid); - gsw_w32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), - sPceBpReg); + CLEAR_FILL_CTRL_REG(sPceBpReg, SDMA_BYPASS_PCE_MD_SHIFT, + SDMA_BYPASS_PCE_MD_SIZE, 0); + + CLEAR_FILL_CTRL_REG(sPceBpReg, SDMA_BYPASS_PCE_NMQID_SHIFT, + SDMA_BYPASS_PCE_NMQID_SIZE, qid); + } else + CLEAR_FILL_CTRL_REG(sPceBpReg, SDMA_BYPASS_PCE_EXTQID_SHIFT, + SDMA_BYPASS_PCE_EXTQID_SIZE, qid); + + gsw_w32_raw(cdev, (SDMA_BYPASS_PCE_REG_OFFSET + (parm->nPortId * 0x6)), + sPceBpReg); } else { /*Program Queue Mapping Table*/ memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.table = PCE_QUEUE_MAP_INDEX; - pcetable.pcindex = ((parm->nPortId & 0x0F) << 4) | - (parm->nTrafficClassId & 0x0F); - if ((gswdev->gipver == LTQ_GSWIP_3_0 && parm->bRedirectionBypass) || - (gswdev->gipver == LTQ_GSWIP_3_1 && parm->bExtrationEnable)) { + pcetable.pcindex = ((parm->nPortId & 0x0F) << 4) | + (parm->nTrafficClassId & 0x0F); + + if ((gswdev->gipver == LTQ_GSWIP_3_0 && parm->bRedirectionBypass) || + (IS_VRSN_31(gswdev->gipver) && parm->bExtrationEnable)) { pcetable.pcindex |= 1 << 8; } + pcetable.val[0] = qid; gsw_pce_table_write(cdev, &pcetable); } + /*Program BM table*/ /* Assign the Egress Port Id and Enable the Queue */ if (gswdev->gipver == LTQ_GSWIP_3_0) { eport = (parm->nPortId & 0xF) << 8; eport |= (parm->nRedirectPortId & 0x7); eport |= (((parm->nRedirectPortId >> 3) & 0x1) << 4); - } else if (gswdev->gipver == LTQ_GSWIP_3_1){ + } else if (IS_VRSN_31(gswdev->gipver)) { eport = (parm->nRedirectPortId & 0x7); eport |= (((parm->nRedirectPortId >> 3) & 0x1) << 4); } else { @@ -6618,29 +8514,53 @@ GSW_return_t GSW_QoS_QueuePortSet(void *cdev, eport |= (((parm->nPortId >> 3) & 0x1) << 4); } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + bmtable.value[0] = eport; bmtable.adr.qMapTbl.nQueueId = parm->nQueueId; bmtable.tableID = BUF_MGR_Q_MAP_TABLE; bmtable.numValues = 1; - return gsw_bm_table_write(cdev, &bmtable); + ret = gsw_bm_table_write(cdev, &bmtable); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + + } GSW_return_t GSW_QoS_SchedulerCfgGet(void *cdev, - GSW_QoS_schedulerCfg_t *parm) + GSW_QoS_schedulerCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - int qid = parm->nQueueId; - bmtbl_prog_t bmtable={0}; + int qid = parm->nQueueId; + bmtbl_prog_t bmtable = {0}; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET,*/ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + /* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET,*/ + /* ETHSW_CAP_1_QUEUE_SHIFT, */ + /* ETHSW_CAP_1_QUEUE_SIZE, &value); */ + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } bmtable.adr.wfq.nQueueId = qid; bmtable.tableID = (BM_Table_ID) WFQ_PARAM; @@ -6648,54 +8568,90 @@ GSW_return_t GSW_QoS_SchedulerCfgGet(void *cdev, gsw_bm_table_read(cdev, &bmtable); parm->nWeight = bmtable.value[0]; - if((bmtable.value[0] == 0xFFFF) || (bmtable.value[0] == 0x1800)) + + if ((bmtable.value[0] == 0xFFFF) || (bmtable.value[0] == 0x1800)) parm->eType = GSW_QOS_SCHEDULER_STRICT; else parm->eType = GSW_QOS_SCHEDULER_WFQ; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_QoS_SchedulerCfgSet(void *cdev, - GSW_QoS_schedulerCfg_t *parm) + GSW_QoS_schedulerCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - int qid = parm->nQueueId; - bmtbl_prog_t bmtable={0}; + int qid = parm->nQueueId; + bmtbl_prog_t bmtable = {0}; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; - if ((parm->eType == GSW_QOS_SCHEDULER_WFQ) && (parm->nWeight == 0)) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + /* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ + /* ETHSW_CAP_1_QUEUE_SHIFT, */ + /* ETHSW_CAP_1_QUEUE_SIZE, &value); */ + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if ((parm->eType == GSW_QOS_SCHEDULER_WFQ) && (parm->nWeight == 0)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } bmtable.adr.wfq.nQueueId = qid; - bmtable.value[0] = (GSW_QOS_SCHEDULER_STRICT==parm->eType)?0xFFFF:parm->nWeight; + bmtable.value[0] = (GSW_QOS_SCHEDULER_STRICT == parm->eType) ? 0xFFFF : parm->nWeight; bmtable.tableID = WFQ_PARAM; bmtable.numValues = 1; gsw_bm_table_write(cdev, &bmtable); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_QoS_ShaperCfgGet(void *cdev, - GSW_QoS_ShaperCfg_t *parm) + GSW_QoS_ShaperCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); int rshid = parm->nRateShaperId; u32 value, exp, mant, ibs; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (rshid >= gswdev->num_of_shapers) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (rshid >= gswdev->num_of_shapers) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Enable/Disable the rate shaper */ gsw_r32(cdev, RS_CTRL_RSEN_OFFSET + (rshid * 0x5), RS_CTRL_RSEN_SHIFT, RS_CTRL_RSEN_SIZE, &value); @@ -6710,7 +8666,7 @@ GSW_return_t GSW_QoS_ShaperCfgGet(void *cdev, gsw_r32(cdev, RS_CIR_MANT_MANT_OFFSET + (rshid * 0x5), RS_CIR_MANT_MANT_SHIFT, RS_CIR_MANT_MANT_SIZE, &mant); - if( gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) gsw_r32(cdev, RS_IBS_IBS_OFFSET + (rshid * 0x5), RS_IBS_IBS_SHIFT, RS_IBS_IBS_SIZE_GSWIP_3_1, &ibs); else @@ -6718,94 +8674,135 @@ GSW_return_t GSW_QoS_ShaperCfgGet(void *cdev, RS_IBS_IBS_SHIFT, RS_IBS_IBS_SIZE, &ibs); /* calc the Rate */ - if( gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) parm->nRate = mratecalc_3_1(ibs, exp, mant); else parm->nRate = mratecalc(ibs, exp, mant); - + if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_r32(cdev, RS_CTRL_RSMOD_OFFSET + (rshid * 0x5), RS_CTRL_RSMOD_SHIFT, RS_CTRL_RSMOD_SIZE, &parm->bAVB); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_ShaperCfgSet(void *cdev, - GSW_QoS_ShaperCfg_t *parm) + GSW_QoS_ShaperCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); int rshid = parm->nRateShaperId; u32 value, exp = 0, mant = 0, rate = 0, ibs = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (rshid >= gswdev->num_of_shapers) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (rshid >= gswdev->num_of_shapers) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Committed Burst Size */ if (parm->nCbs > 0xFFC0) value = 0x3FF; else value = ((parm->nCbs + 63) / 64); + /* Committed Burst Size (CBS [bytes]) */ gsw_w32(cdev, RS_CBS_CBS_OFFSET + (rshid * 0x5), RS_CBS_CBS_SHIFT, RS_CBS_CBS_SIZE, value); /* Rate [kbit/s] */ /* Calc the Rate */ rate = parm->nRate; + if (rate) { - if( gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) calc_mtoken_3_1(rate, &ibs, &exp, &mant); else calc_mtoken(rate, &ibs, &exp, &mant); } + //Set CIR Exponent and Mantissa. gsw_w32(cdev, RS_CIR_EXP_EXP_OFFSET + (rshid * 0x5), - RS_CIR_EXP_EXP_SHIFT, RS_CIR_EXP_EXP_SIZE, exp); + RS_CIR_EXP_EXP_SHIFT, RS_CIR_EXP_EXP_SIZE, exp); gsw_w32(cdev, RS_CIR_MANT_MANT_OFFSET + (rshid * 0x5), RS_CIR_MANT_MANT_SHIFT, RS_CIR_MANT_MANT_SIZE, mant); + //Set Instantaneous Burst Size. - if( gswdev->gipver == LTQ_GSWIP_3_1) + if (IS_VRSN_31(gswdev->gipver)) gsw_w32(cdev, RS_IBS_IBS_OFFSET + (rshid * 0x5), RS_IBS_IBS_SHIFT, RS_IBS_IBS_SIZE_GSWIP_3_1, ibs); else gsw_w32(cdev, RS_IBS_IBS_OFFSET + (rshid * 0x5), RS_IBS_IBS_SHIFT, RS_IBS_IBS_SIZE, ibs); + /* Enable/Disable the Rate Shaper */ gsw_w32(cdev, RS_CTRL_RSEN_OFFSET + (rshid * 0x5), RS_CTRL_RSEN_SHIFT, RS_CTRL_RSEN_SIZE, parm->bEnable); + if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, RS_CTRL_RSMOD_OFFSET + (rshid * 0x5), RS_CTRL_RSMOD_SHIFT, RS_CTRL_RSMOD_SIZE, parm->bAVB); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_ShaperQueueAssign(void *cdev, - GSW_QoS_ShaperQueue_t *parm) + GSW_QoS_ShaperQueue_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 rshid = parm->nRateShaperId, qid = parm->nQueueId; u32 value1_RS, value1_ShaperId, value2_RS, value2_ShaperId; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (qid >= gswdev->num_of_queues) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + if (rshid >= gswdev->num_of_shapers) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /* Check Rate Shaper 1 Enable */ gsw_r32(cdev, PQM_RS_EN1_OFFSET + (qid * 2), PQM_RS_EN1_SHIFT, PQM_RS_EN1_SIZE, &value1_RS); @@ -6816,11 +8813,14 @@ GSW_return_t GSW_QoS_ShaperQueueAssign(void *cdev, PQM_RS_EN2_SHIFT, PQM_RS_EN2_SIZE, &value2_RS); gsw_r32(cdev, PQM_RS_RS2_OFFSET + (qid * 2), PQM_RS_RS2_SHIFT, PQM_RS_RS2_SIZE, &value2_ShaperId); - if ((value1_RS == 1) && (value1_ShaperId == rshid)) - return GSW_statusOk; - else if ((value2_RS == 1) && (value2_ShaperId == rshid)) - return GSW_statusOk; - else if (value1_RS == 0) { + + if ((value1_RS == 1) && (value1_ShaperId == rshid)) { + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; + } else if ((value2_RS == 1) && (value2_ShaperId == rshid)) { + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; + } else if (value1_RS == 0) { gswdev->shaper_idx[rshid].usageCount++; gsw_w32(cdev, PQM_RS_RS1_OFFSET + (qid * 2), PQM_RS_RS1_SHIFT, PQM_RS_RS1_SIZE, rshid); @@ -6839,27 +8839,49 @@ GSW_return_t GSW_QoS_ShaperQueueAssign(void *cdev, gsw_w32(cdev, RS_CTRL_RSEN_OFFSET + (rshid * 0x5), RS_CTRL_RSEN_SHIFT, RS_CTRL_RSEN_SIZE, 0x1); } else { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_ShaperQueueDeassign(void *cdev, - GSW_QoS_ShaperQueue_t *parm) + GSW_QoS_ShaperQueue_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 rshid = parm->nRateShaperId, qid = parm->nQueueId; u32 value1, value2, value3, value4; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; - if (rshid >= gswdev->num_of_shapers) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (rshid >= gswdev->num_of_shapers) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Rate Shaper 1 Read */ gsw_r32(cdev, PQM_RS_EN1_OFFSET + (qid * 2), PQM_RS_EN1_SHIFT, PQM_RS_EN1_SIZE, &value1); @@ -6870,78 +8892,117 @@ GSW_return_t GSW_QoS_ShaperQueueDeassign(void *cdev, PQM_RS_EN2_SHIFT, PQM_RS_EN2_SIZE, &value3); gsw_r32(cdev, PQM_RS_RS2_OFFSET + (qid * 2), PQM_RS_RS2_SHIFT, PQM_RS_RS2_SIZE, &value4); + if ((value1 == 1) && (value2 == rshid)) { gswdev->shaper_idx[rshid].usageCount--; gsw_w32(cdev, PQM_RS_EN1_OFFSET + (qid * 2), PQM_RS_EN1_SHIFT, PQM_RS_EN1_SIZE, 0); gsw_w32(cdev, PQM_RS_RS1_OFFSET + (qid * 2), PQM_RS_RS1_SHIFT, PQM_RS_RS1_SIZE, 0); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else if ((value3 == 1) && (value4 == rshid)) { gswdev->shaper_idx[rshid].usageCount--; gsw_w32(cdev, PQM_RS_EN2_OFFSET + (qid * 2), PQM_RS_EN2_SHIFT, PQM_RS_EN2_SIZE, 0); gsw_w32(cdev, PQM_RS_RS2_OFFSET + (qid * 2), PQM_RS_RS2_SHIFT, PQM_RS_RS2_SIZE, 0); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if ((value1 == 0) && (value3 == 0) && - (0==gswdev->shaper_idx[rshid].usageCount)) { + if ((value1 == 0) && (value3 == 0) && + (0 == gswdev->shaper_idx[rshid].usageCount)) { gsw_w32(cdev, RS_CTRL_RSEN_OFFSET + (rshid * 0x5), RS_CTRL_RSEN_SHIFT, RS_CTRL_RSEN_SIZE, 0); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_ShaperQueueGet(void *cdev, - GSW_QoS_ShaperQueueGet_t *parm) + GSW_QoS_ShaperQueueGet_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 rsh, value; u8 qid = parm->nQueueId; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } parm->bAssigned = 0; parm->nRateShaperId = 0; gsw_r32(cdev, PQM_RS_EN1_OFFSET + (qid * 2), PQM_RS_EN1_SHIFT, PQM_RS_EN1_SIZE, &rsh); + if (rsh == 1) { parm->bAssigned = 1; gsw_r32(cdev, PQM_RS_RS1_OFFSET + (qid * 2), PQM_RS_RS1_SHIFT, PQM_RS_RS1_SIZE, &value); parm->nRateShaperId = value; } + gsw_r32(cdev, PQM_RS_EN2_OFFSET + (qid * 2), PQM_RS_EN2_SHIFT, PQM_RS_EN2_SIZE, &rsh); + if (rsh == 1) { gsw_r32(cdev, PQM_RS_RS2_OFFSET + (qid * 2), PQM_RS_RS2_SHIFT, PQM_RS_RS2_SIZE, &value); parm->nRateShaperId = value; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_StormCfgSet(void *cdev, - GSW_QoS_stormCfg_t *parm) + GSW_QoS_stormCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 SCONBC, SCONMC, SCONUC, mid; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if ((parm->bBroadcast == 0) && - (parm->bMulticast == 0) && - (parm->bUnknownUnicast == 0)) { + (parm->bMulticast == 0) && + (parm->bUnknownUnicast == 0)) { /* Storm Control Mode */ gsw_w32(cdev, PCE_GCTRL_0_SCONMOD_OFFSET, PCE_GCTRL_0_SCONMOD_SHIFT, @@ -6954,11 +9015,12 @@ GSW_return_t GSW_QoS_StormCfgSet(void *cdev, gsw_w32(cdev, PCE_GCTRL_0_SCONMC_OFFSET, PCE_GCTRL_0_SCONMC_SHIFT, PCE_GCTRL_0_SCONMC_SIZE, 0); - /* Meter instances used for unknown unicast traffic */ + /* Meter instances used for unknown unicast traffic */ gsw_w32(cdev, PCE_GCTRL_0_SCONUC_OFFSET, PCE_GCTRL_0_SCONUC_SHIFT, PCE_GCTRL_0_SCONUC_SIZE, 0); } + /* Meter ID */ gsw_r32(cdev, PCE_GCTRL_0_SCONMET_OFFSET, PCE_GCTRL_0_SCONMET_SHIFT, @@ -6982,8 +9044,10 @@ GSW_return_t GSW_QoS_StormCfgSet(void *cdev, gsw_w32(cdev, PCE_GCTRL_0_SCONMOD_OFFSET, PCE_GCTRL_0_SCONMOD_SHIFT, PCE_GCTRL_0_SCONMOD_SIZE, 3); - } else if (parm->nMeterId != mid) - return GSW_statusErr; + } else if (parm->nMeterId != mid) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { /* Storm Control Mode */ gsw_w32(cdev, PCE_GCTRL_0_SCONMOD_OFFSET, @@ -6993,6 +9057,7 @@ GSW_return_t GSW_QoS_StormCfgSet(void *cdev, PCE_GCTRL_0_SCONMET_SHIFT, PCE_GCTRL_0_SCONMET_SIZE, parm->nMeterId); } + /* Meter instances used for broadcast traffic */ gsw_w32(cdev, PCE_GCTRL_0_SCONBC_OFFSET, PCE_GCTRL_0_SCONBC_SHIFT, @@ -7005,22 +9070,38 @@ GSW_return_t GSW_QoS_StormCfgSet(void *cdev, gsw_w32(cdev, PCE_GCTRL_0_SCONUC_OFFSET, PCE_GCTRL_0_SCONUC_SHIFT, PCE_GCTRL_0_SCONUC_SIZE, parm->bUnknownUnicast); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_StormCfgGet(void *cdev, - GSW_QoS_stormCfg_t *parm) + GSW_QoS_stormCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Storm Control Mode */ gsw_r32(cdev, PCE_GCTRL_0_SCONMOD_OFFSET, PCE_GCTRL_0_SCONMOD_SHIFT, PCE_GCTRL_0_SCONMOD_SIZE, &value); + if (value == 0) { parm->nMeterId = 0; parm->bBroadcast = 0; @@ -7047,38 +9128,48 @@ GSW_return_t GSW_QoS_StormCfgGet(void *cdev, PCE_GCTRL_0_SCONUC_SIZE, &value); parm->bUnknownUnicast = value; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_WredCfgGet(void *cdev, - GSW_QoS_WRED_Cfg_t *parm) + GSW_QoS_WRED_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 Gl_Mod_Size =0; + u8 Gl_Mod_Size = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Description: 'Drop Probability Profile' */ gsw_r32(cdev, BM_QUEUE_GCTRL_DPROB_OFFSET, BM_QUEUE_GCTRL_DPROB_SHIFT, BM_QUEUE_GCTRL_DPROB_SIZE, &parm->eProfile); + /*Automatic/Manual - Adaptive Watermark Type */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_30_31(gswdev->gipver)) { gsw_r32(cdev, BM_QUEUE_GCTRL_BUFMOD_OFFSET, BM_QUEUE_GCTRL_BUFMOD_SHIFT, BM_QUEUE_GCTRL_BUFMOD_SIZE, &parm->eMode); } - - if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE2; + + if ((gswdev->gipver == LTQ_GSWIP_2_2) || + (IS_VRSN_30_31(gswdev->gipver))) + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE2; else - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE; + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE; /* Get the Local/Global threshold */ gsw_r32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, @@ -7108,37 +9199,49 @@ GSW_return_t GSW_QoS_WredCfgGet(void *cdev, gsw_r32(cdev, BM_WRED_GTH_1_MAXTH_OFFSET, BM_WRED_GTH_1_MAXTH_SHIFT, BM_WRED_GTH_1_MAXTH_SIZE, &parm->nGreen_Max); - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_WredCfgSet(void *cdev, - GSW_QoS_WRED_Cfg_t *parm) + GSW_QoS_WRED_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 Gl_Mod_Size =0; + u8 Gl_Mod_Size = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Description: 'Drop Probability Profile' */ gsw_w32(cdev, BM_QUEUE_GCTRL_DPROB_OFFSET, BM_QUEUE_GCTRL_DPROB_SHIFT, BM_QUEUE_GCTRL_DPROB_SIZE, parm->eProfile); + /* Automatic/Manual - Adaptive Watermark Type */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_30_31(gswdev->gipver)) { gsw_w32(cdev, BM_QUEUE_GCTRL_BUFMOD_OFFSET, BM_QUEUE_GCTRL_BUFMOD_SHIFT, BM_QUEUE_GCTRL_BUFMOD_SIZE, parm->eMode); } + //GL_MOD size if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE2; + (IS_VRSN_30_31(gswdev->gipver))) + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE2; else - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE; + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE; switch (parm->eThreshMode) { case GSW_QOS_WRED_Local_Thresh: @@ -7147,24 +9250,28 @@ GSW_return_t GSW_QoS_WredCfgSet(void *cdev, BM_QUEUE_GCTRL_GL_MOD_SHIFT, Gl_Mod_Size, 0x0); break; + case GSW_QOS_WRED_Global_Thresh: /* Set the global threshold */ gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, BM_QUEUE_GCTRL_GL_MOD_SHIFT, Gl_Mod_Size, 0x1); break; - case GSW_QOS_WRED_Port_Thresh: - /* Port queue and Port WRED Thresholds */ - gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, - BM_QUEUE_GCTRL_GL_MOD_SHIFT, - Gl_Mod_Size, 0x2); + + case GSW_QOS_WRED_Port_Thresh: + /* Port queue and Port WRED Thresholds */ + gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, + BM_QUEUE_GCTRL_GL_MOD_SHIFT, + Gl_Mod_Size, 0x2); break; + default: /* Set the Local threshold */ gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, BM_QUEUE_GCTRL_GL_MOD_SHIFT, Gl_Mod_Size, 0x0); } + /* WRED Red Threshold - Minimum */ gsw_w32(cdev, BM_WRED_RTH_0_MINTH_OFFSET, BM_WRED_RTH_0_MINTH_SHIFT, @@ -7189,415 +9296,550 @@ GSW_return_t GSW_QoS_WredCfgSet(void *cdev, gsw_w32(cdev, BM_WRED_GTH_1_MAXTH_OFFSET, BM_WRED_GTH_1_MAXTH_SHIFT, BM_WRED_GTH_1_MAXTH_SIZE, parm->nGreen_Max); - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_WredQueueCfgGet(void *cdev, - GSW_QoS_WRED_QueueCfg_t *parm) + GSW_QoS_WRED_QueueCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 qid = parm->nQueueId, addr; u8 crcode; - bmtbl_prog_t bmtable={0}; + u32 ret; + bmtbl_prog_t bmtable = {0}; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + /* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ + /* ETHSW_CAP_1_QUEUE_SHIFT, */ + /* ETHSW_CAP_1_QUEUE_SIZE, &value); */ + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /* For different color 0(not drop) 1(Green) 2(Yellow) 3(Red) */ for (crcode = 1; crcode < 4; crcode++) { addr = ((qid << 3) | crcode); - bmtable.adr.raw = (u16)addr; - bmtable.numValues = 2; - bmtable.tableID = (BM_Table_ID) PQM_THRESHOLD; - gsw_bm_table_read(cdev,&bmtable); - switch (crcode) - { - case 3: - parm->nRed_Max = bmtable.value[1]; - parm->nRed_Min = bmtable.value[0]; - break; - case 2: - parm->nYellow_Max = bmtable.value[1]; - parm->nYellow_Min = bmtable.value[0]; - break; - case 1: - parm->nGreen_Max = bmtable.value[1]; - parm->nGreen_Min = bmtable.value[0]; - break; - } + bmtable.adr.raw = (u16)addr; + bmtable.numValues = 2; + bmtable.tableID = (BM_Table_ID) PQM_THRESHOLD; + gsw_bm_table_read(cdev, &bmtable); + + switch (crcode) { + case 3: + parm->nRed_Max = bmtable.value[1]; + parm->nRed_Min = bmtable.value[0]; + break; + + case 2: + parm->nYellow_Max = bmtable.value[1]; + parm->nYellow_Min = bmtable.value[0]; + break; + + case 1: + parm->nGreen_Max = bmtable.value[1]; + parm->nGreen_Min = bmtable.value[0]; + break; } - return GSW_statusOk; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_QoS_WredQueueCfgSet(void *cdev, - GSW_QoS_WRED_QueueCfg_t *parm) + GSW_QoS_WRED_QueueCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 qid = parm->nQueueId, addr; - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; u8 crcode; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (qid >= gswdev->num_of_queues) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + if (qid >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /* For different color 0(not drop) 1(Green) 2(Yellow) 3(Red) */ for (crcode = 1; crcode < 4; crcode++) { addr = (((qid << 3) & 0xF8) | crcode); bmtable.adr.raw = (u16)addr; + switch (crcode) { case 3: bmtable.value[1] = parm->nRed_Max; bmtable.value[0] = parm->nRed_Min; break; + case 2: bmtable.value[1] = parm->nYellow_Max; bmtable.value[0] = parm->nYellow_Min; break; + case 1: bmtable.value[1] = parm->nGreen_Max; bmtable.value[0] = parm->nGreen_Min; break; } + bmtable.tableID = PQM_THRESHOLD; bmtable.numValues = 2; gsw_bm_table_write(cdev, &bmtable); } + /* Set the local threshold */ -/* gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, */ -/* BM_QUEUE_GCTRL_GL_MOD_SHIFT, */ -/* BM_QUEUE_GCTRL_GL_MOD_SIZE, 0); */ - return GSW_statusOk; + /* gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, */ + /* BM_QUEUE_GCTRL_GL_MOD_SHIFT, */ + /* BM_QUEUE_GCTRL_GL_MOD_SIZE, 0); */ + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + } GSW_return_t GSW_QoS_WredPortCfgGet(void *cdev, - GSW_QoS_WRED_PortCfg_t *parm) + GSW_QoS_WRED_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns with*/ /* an error for older hardware revisions. */ /** WRED Red Threshold Min [number of segments].*/ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_r32(cdev, (BM_PWRED_RTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_RTH_0_MINTH_SHIFT, BM_PWRED_RTH_0_MINTH_SIZE, &parm->nRed_Min); - /** WRED Red Threshold Max [number of segments].*/ + /** WRED Red Threshold Max [number of segments].*/ gsw_r32(cdev, (BM_PWRED_RTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_RTH_1_MAXTH_SHIFT, BM_PWRED_RTH_1_MAXTH_SIZE, &parm->nRed_Max); - /* WRED Yellow Threshold - Minimum */ + /* WRED Yellow Threshold - Minimum */ gsw_r32(cdev, (BM_PWRED_YTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_YTH_0_MINTH_SHIFT, BM_PWRED_YTH_0_MINTH_SIZE, &parm->nYellow_Min); - /* WRED Yellow Threshold - Maximum */ + /* WRED Yellow Threshold - Maximum */ gsw_r32(cdev, (BM_PWRED_YTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_YTH_1_MAXTH_SHIFT, BM_PWRED_YTH_1_MAXTH_SIZE, &parm->nYellow_Max); - /* WRED Green Threshold - Minimum */ + /* WRED Green Threshold - Minimum */ gsw_r32(cdev, (BM_PWRED_GTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_GTH_0_MINTH_SHIFT, BM_PWRED_GTH_0_MINTH_SIZE, &parm->nGreen_Min); - /* WRED Green Threshold - Maximum */ + /* WRED Green Threshold - Maximum */ gsw_r32(cdev, (BM_PWRED_GTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_GTH_1_MAXTH_SHIFT, BM_PWRED_GTH_1_MAXTH_SIZE, &parm->nGreen_Max); - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_WredPortCfgSet(void *cdev, - GSW_QoS_WRED_PortCfg_t *parm) + GSW_QoS_WRED_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ /** WRED Red Threshold Min [number of segments]. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (BM_PWRED_RTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_RTH_0_MINTH_SHIFT, BM_PWRED_RTH_0_MINTH_SIZE, parm->nRed_Min); - /** WRED Red Threshold Max [number of segments]. */ + /** WRED Red Threshold Max [number of segments]. */ gsw_w32(cdev, (BM_PWRED_RTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_RTH_1_MAXTH_SHIFT, BM_PWRED_RTH_1_MAXTH_SIZE, parm->nRed_Max); - /* WRED Yellow Threshold - Minimum */ + /* WRED Yellow Threshold - Minimum */ gsw_w32(cdev, (BM_PWRED_YTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_YTH_0_MINTH_SHIFT, BM_PWRED_YTH_0_MINTH_SIZE, parm->nYellow_Min); - /* WRED Yellow Threshold - Maximum */ + /* WRED Yellow Threshold - Maximum */ gsw_w32(cdev, (BM_PWRED_YTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_YTH_1_MAXTH_SHIFT, BM_PWRED_YTH_1_MAXTH_SIZE, parm->nYellow_Max); - /* WRED Green Threshold - Minimum */ + /* WRED Green Threshold - Minimum */ gsw_w32(cdev, (BM_PWRED_GTH_0_MINTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_GTH_0_MINTH_SHIFT, BM_PWRED_GTH_0_MINTH_SIZE, parm->nGreen_Min); - /* WRED Green Threshold - Maximum */ + /* WRED Green Threshold - Maximum */ gsw_w32(cdev, (BM_PWRED_GTH_1_MAXTH_OFFSET - + (parm->nPortId * 0x6)), + + (parm->nPortId * 0x6)), BM_PWRED_GTH_1_MAXTH_SHIFT, BM_PWRED_GTH_1_MAXTH_SIZE, parm->nGreen_Max); - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_FlowctrlCfgGet(void *cdev, - GSW_QoS_FlowCtrlCfg_t *parm) + GSW_QoS_FlowCtrlCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Supported for GSWIP 2.2 and newer and returns */ /* with an error for older hardware revisions. */ /** Global Buffer Non Conforming Flow Control */ /* Threshold Minimum [number of segments]. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_r32(cdev, (SDMA_FCTHR1_THR1_OFFSET), SDMA_FCTHR1_THR1_SHIFT, SDMA_FCTHR1_THR1_SIZE, &parm->nFlowCtrlNonConform_Min); - /** Global Buffer Non Conforming Flow Control */ - /* Threshold Maximum [number of segments]. */ + /** Global Buffer Non Conforming Flow Control */ + /* Threshold Maximum [number of segments]. */ gsw_r32(cdev, (SDMA_FCTHR2_THR2_OFFSET), SDMA_FCTHR2_THR2_SHIFT, SDMA_FCTHR2_THR2_SIZE, &parm->nFlowCtrlNonConform_Max); - /** Global Buffer Conforming Flow Control Threshold */ - /* Minimum [number of segments]. */ + /** Global Buffer Conforming Flow Control Threshold */ + /* Minimum [number of segments]. */ gsw_r32(cdev, (SDMA_FCTHR3_THR3_OFFSET), SDMA_FCTHR3_THR3_SHIFT, SDMA_FCTHR3_THR3_SIZE, &parm->nFlowCtrlConform_Min); - /** Global Buffer Conforming Flow Control */ - /* Threshold Maximum [number of segments]. */ + /** Global Buffer Conforming Flow Control */ + /* Threshold Maximum [number of segments]. */ gsw_r32(cdev, (SDMA_FCTHR4_THR4_OFFSET), SDMA_FCTHR4_THR4_SHIFT, SDMA_FCTHR4_THR4_SIZE, &parm->nFlowCtrlConform_Max); - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_FlowctrlCfgSet(void *cdev, - GSW_QoS_FlowCtrlCfg_t *parm) + GSW_QoS_FlowCtrlCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Supported for GSWIP 2.2 and newer and returns with */ /* an error for older hardware revisions. */ /** Global Buffer Non Conforming Flow Control */ /* Threshold Minimum [number of segments]. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { gsw_w32(cdev, (SDMA_FCTHR1_THR1_OFFSET), SDMA_FCTHR1_THR1_SHIFT, SDMA_FCTHR1_THR1_SIZE, parm->nFlowCtrlNonConform_Min); - /** Global Buffer Non Conforming Flow Control */ - /* Threshold Maximum [number of segments]. */ + /** Global Buffer Non Conforming Flow Control */ + /* Threshold Maximum [number of segments]. */ gsw_w32(cdev, (SDMA_FCTHR2_THR2_OFFSET), SDMA_FCTHR2_THR2_SHIFT, SDMA_FCTHR2_THR2_SIZE, parm->nFlowCtrlNonConform_Max); - /** Global Buffer Conforming Flow Control Threshold */ - /* Minimum [number of segments]. */ + /** Global Buffer Conforming Flow Control Threshold */ + /* Minimum [number of segments]. */ gsw_w32(cdev, (SDMA_FCTHR3_THR3_OFFSET), SDMA_FCTHR3_THR3_SHIFT, SDMA_FCTHR3_THR3_SIZE, parm->nFlowCtrlConform_Min); - /** Global Buffer Conforming Flow Control Threshold */ - /* Maximum [number of segments]. */ + /** Global Buffer Conforming Flow Control Threshold */ + /* Maximum [number of segments]. */ gsw_w32(cdev, (SDMA_FCTHR4_THR4_OFFSET), SDMA_FCTHR4_THR4_SHIFT, SDMA_FCTHR4_THR4_SIZE, parm->nFlowCtrlConform_Max); - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_FlowctrlPortCfgGet(void *cdev, - GSW_QoS_FlowCtrlPortCfg_t *parm) + GSW_QoS_FlowCtrlPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns with */ /* an error for older hardware revisions. */ /** Ingress Port occupied Buffer Flow Control */ /* Threshold Minimum [number of segments]. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { gsw_r32(cdev, (SDMA_PFCTHR8_THR8_OFFSET22 - + (parm->nPortId * 0x4)), + + (parm->nPortId * 0x4)), SDMA_PFCTHR8_THR8_SHIFT, SDMA_PFCTHR8_THR8_SIZE, &parm->nFlowCtrl_Min); - /** Ingress Port occupied Buffer Flow Control */ - /* Threshold Maximum [number of segments]. */ + /** Ingress Port occupied Buffer Flow Control */ + /* Threshold Maximum [number of segments]. */ gsw_r32(cdev, (SDMA_PFCTHR9_THR9_OFFSET22 - + (parm->nPortId * 0x4)), + + (parm->nPortId * 0x4)), SDMA_PFCTHR9_THR9_SHIFT, SDMA_PFCTHR9_THR9_SIZE, &parm->nFlowCtrl_Max); - return GSW_statusOk; - } else if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { - /** Ingress Port occupied Buffer Flow Control */ - /* Threshold Minimum [number of segments]. */ + ret = GSW_statusOk; + } else if (IS_VRSN_30_31(gswdev->gipver)) { + /** Ingress Port occupied Buffer Flow Control */ + /* Threshold Minimum [number of segments]. */ gsw_r32(cdev, (SDMA_PFCTHR8_THR8_OFFSET30 - + (parm->nPortId * 0x2)), + + (parm->nPortId * 0x2)), SDMA_PFCTHR8_THR8_SHIFT, SDMA_PFCTHR8_THR8_SIZE, &parm->nFlowCtrl_Min); - /** Ingress Port occupied Buffer Flow Control */ - /* Threshold Maximum [number of segments]. */ + /** Ingress Port occupied Buffer Flow Control */ + /* Threshold Maximum [number of segments]. */ gsw_r32(cdev, (SDMA_PFCTHR9_THR9_OFFSET30 - + (parm->nPortId * 0x2)), + + (parm->nPortId * 0x2)), SDMA_PFCTHR9_THR9_SHIFT, SDMA_PFCTHR9_THR9_SIZE, &parm->nFlowCtrl_Max); - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QoS_FlowctrlPortCfgSet(void *cdev, - GSW_QoS_FlowCtrlPortCfg_t *parm) + GSW_QoS_FlowCtrlPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Supported for GSWIP 2.2 and newer and returns with */ /* an error for older hardware revisions. */ /** Ingress Port occupied Buffer Flow Control */ /* Threshold Minimum [number of segments]. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { gsw_w32(cdev, (SDMA_PFCTHR8_THR8_OFFSET22 - + (parm->nPortId * 0x4)), + + (parm->nPortId * 0x4)), SDMA_PFCTHR8_THR8_SHIFT, SDMA_PFCTHR8_THR8_SIZE, parm->nFlowCtrl_Min); - /** Ingress Port occupied Buffer Flow Control Threshold */ - /* Maximum [number of segments]. */ + /** Ingress Port occupied Buffer Flow Control Threshold */ + /* Maximum [number of segments]. */ gsw_w32(cdev, (SDMA_PFCTHR9_THR9_OFFSET22 - + (parm->nPortId * 0x4)), + + (parm->nPortId * 0x4)), SDMA_PFCTHR9_THR9_SHIFT, SDMA_PFCTHR9_THR9_SIZE, parm->nFlowCtrl_Max); - return GSW_statusOk; - } else if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { - /** Ingress Port occupied Buffer Flow Control Threshold*/ - /* Minimum [number of segments]. */ + ret = GSW_statusOk; + } else if (IS_VRSN_30_31(gswdev->gipver)) { + /** Ingress Port occupied Buffer Flow Control Threshold*/ + /* Minimum [number of segments]. */ gsw_w32(cdev, (SDMA_PFCTHR8_THR8_OFFSET30 - + (parm->nPortId * 0x2)), + + (parm->nPortId * 0x2)), SDMA_PFCTHR8_THR8_SHIFT, SDMA_PFCTHR8_THR8_SIZE, parm->nFlowCtrl_Min); - /** Ingress Port occupied Buffer Flow Control Threshold */ - /* Maximum [number of segments]. */ + /** Ingress Port occupied Buffer Flow Control Threshold */ + /* Maximum [number of segments]. */ gsw_w32(cdev, (SDMA_PFCTHR9_THR9_OFFSET30 - + (parm->nPortId * 0x2)), + + (parm->nPortId * 0x2)), SDMA_PFCTHR9_THR9_SHIFT, SDMA_PFCTHR9_THR9_SIZE, parm->nFlowCtrl_Max); - return GSW_statusOk; - } - else { - return GSW_statusErr; + ret = GSW_statusOk; + } else { + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_QoS_QueueBufferReserveCfgGet(void *cdev, - GSW_QoS_QueueBufferReserveCfg_t *parm) + GSW_QoS_QueueBufferReserveCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + /* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ + /* ETHSW_CAP_1_QUEUE_SHIFT, */ + /* ETHSW_CAP_1_QUEUE_SIZE, &value); */ + if (parm->nQueueId >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (parm->nQueueId >= gswdev->num_of_queues) - return GSW_statusErr; + /* Supported for GSWIP 2.2 and newer and returns with an error */ /* for older hardware revisions. */ /* Colourcode = 0 and fixed offset = 0 */ /* Set the BM RAM ADDR */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { /* What about mode2, mode3 and mode1 with color */ bmtable.adr.pqmThr.mode = 0; /*BM_RAM_ADDR.ADDR[2]=0 -> Mode 1*/ bmtable.adr.pqmThr.color_or_submode = 0; /* color = 0 (Not Drop eligible)*/ @@ -7606,39 +9848,52 @@ GSW_return_t GSW_QoS_QueueBufferReserveCfgGet(void *cdev, bmtable.numValues = 2; gsw_bm_table_read(cdev, &bmtable); /*Minimum threshold (used as reserved buffer threshold when color = 0)*/ - parm->nBufferReserved = bmtable.value[0]; + parm->nBufferReserved = bmtable.value[0]; /* value[1] Maximum threshold (not used when color = 0) */ - return GSW_statusOk; + ret = GSW_statusOk; } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + } GSW_return_t GSW_QoS_QueueBufferReserveCfgSet(void *cdev, - GSW_QoS_QueueBufferReserveCfg_t *parm) + GSW_QoS_QueueBufferReserveCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + /* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ + /* ETHSW_CAP_1_QUEUE_SHIFT, */ + /* ETHSW_CAP_1_QUEUE_SIZE, &value); */ + + if (parm->nQueueId >= gswdev->num_of_queues) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } -/* gsw_r32(cdev, ETHSW_CAP_1_QUEUE_OFFSET, */ -/* ETHSW_CAP_1_QUEUE_SHIFT, */ -/* ETHSW_CAP_1_QUEUE_SIZE, &value); */ - if (parm->nQueueId >= gswdev->num_of_queues) - return GSW_statusErr; /* Supported for GSWIP 2.2 and newer and returns with an error */ /* for older hardware revisions. */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { /* What about mode1 with color & mode2, mode3 */ bmtable.adr.pqmThr.mode = 0; /*BM_RAM_ADDR.ADDR[2]=0 -> Mode 1*/ bmtable.adr.pqmThr.color_or_submode = 0; /* color = 0 (Not Drop eligible)*/ @@ -7647,97 +9902,137 @@ GSW_return_t GSW_QoS_QueueBufferReserveCfgSet(void *cdev, /* value[1] Maximum threshold (not used when color = 0) */ bmtable.tableID = PQM_THRESHOLD; bmtable.numValues = 2; - return gsw_bm_table_write(cdev, &bmtable); + ret = gsw_bm_table_write(cdev, &bmtable); } else { - return GSW_statusErr; + ret = GSW_statusErr; } + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_QoS_Meter_Act(void *cdev, - GSW_QoS_mtrAction_t *parm) + GSW_QoS_mtrAction_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (parm->nCpuUserId >= 2) - return GSW_statusErr; + if (parm->nCpuUserId >= 2) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + value = parm->nMeterId; gsw_w32(cdev, (PCE_CPUMETER_MID0_MID_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_MID0_MID_SHIFT, PCE_CPUMETER_MID0_MID_SIZE, value); gsw_w32(cdev, (PCE_CPUMETER_CTRL_MT0EN_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_CTRL_MT0EN_SHIFT, PCE_CPUMETER_CTRL_MT0EN_SIZE, parm->bMeterEna); value = parm->nSecMeterId; gsw_w32(cdev, (PCE_CPUMETER_MID1_MID_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_MID1_MID_SHIFT, PCE_CPUMETER_MID1_MID_SIZE, value); gsw_w32(cdev, (PCE_CPUMETER_CTRL_MT1EN_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_CTRL_MT1EN_SHIFT, PCE_CPUMETER_CTRL_MT1EN_SIZE, parm->bSecMeterEna); value = parm->pktLen; gsw_w32(cdev, (PCE_CPUMETER_SIZE_SIZE_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_SIZE_SIZE_SHIFT, PCE_CPUMETER_SIZE_SIZE_SIZE, value); gsw_w32(cdev, (PCE_CPUMETER_CTRL_PRECOL_OFFSET - + (parm->nCpuUserId * 0x8)), + + (parm->nCpuUserId * 0x8)), PCE_CPUMETER_CTRL_PRECOL_SHIFT, PCE_CPUMETER_CTRL_PRECOL_SIZE, parm->ePreColor); -/* - gsw_w32(cdev, (PCE_CPUMETER_CTRL_REQ_OFFSET - + (parm->nCpuUserId * 0x8)), - PCE_CPUMETER_CTRL_REQ_SHIFT, - PCE_CPUMETER_CTRL_REQ_SIZE, 1); - - do { - gsw_r32(cdev, (PCE_CPUMETER_CTRL_REQ_OFFSET - + (parm->nCpuUserId * 0x8)), - PCE_CPUMETER_CTRL_REQ_SHIFT, - PCE_CPUMETER_CTRL_REQ_SIZE, &value); - } while(value); - - gsw_w32(cdev, PCE_CPUMETER_CTRL_AFTCOL_OFFSET - + (parm->nCpuUserId * 0x8), - PCE_CPUMETER_CTRL_AFTCOL_SHIFT, - PCE_CPUMETER_CTRL_AFTCOL_SIZE, parm->eOutColor); -*/ + /* + gsw_w32(cdev, (PCE_CPUMETER_CTRL_REQ_OFFSET + + (parm->nCpuUserId * 0x8)), + PCE_CPUMETER_CTRL_REQ_SHIFT, + PCE_CPUMETER_CTRL_REQ_SIZE, 1); + + do { + gsw_r32(cdev, (PCE_CPUMETER_CTRL_REQ_OFFSET + + (parm->nCpuUserId * 0x8)), + PCE_CPUMETER_CTRL_REQ_SHIFT, + PCE_CPUMETER_CTRL_REQ_SIZE, &value); + } while(value); + + gsw_w32(cdev, PCE_CPUMETER_CTRL_AFTCOL_OFFSET + + (parm->nCpuUserId * 0x8), + PCE_CPUMETER_CTRL_AFTCOL_SHIFT, + PCE_CPUMETER_CTRL_AFTCOL_SIZE, parm->eOutColor); + */ } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } + #endif /* CONFIG_LTQ_QOS */ + #if defined(CONFIG_LTQ_MULTICAST) && CONFIG_LTQ_MULTICAST GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, - GSW_multicastRouter_t *parm) + GSW_multicastRouter_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); gsw_igmp_t *hitbl = &gswdev->iflag; u32 value; u8 pidx = parm->nPortId; + u32 ret; + static GSW_PCE_rule_t pcrule; + int i; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - if ((gswdev->gipver != LTQ_GSWIP_3_1) || - ((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if ((IS_VRSN_NOT_31(gswdev->gipver)) || + ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { //Govind - Below registers are not supported in 3.1. Need to take care of it? /* Read the Default Router Port Map - DRPM */ gsw_r32(cdev, PCE_IGMP_DRPM_DRPM_OFFSET, PCE_IGMP_DRPM_DRPM_SHIFT, PCE_IGMP_DRPM_DRPM_SIZE, &value); + if (((value >> pidx) & 0x1) == 1) { pr_err("Error: the prot was already in the member\n"); } else { @@ -7749,24 +10044,25 @@ GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, } } - if ((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { //Govind - Returning an error for this case in read API? - pr_err("CPU Port for sending traffic %d\n",(1 << gswdev->cport)); + pr_err("CPU Port for sending traffic %d\n", (1 << gswdev->cport)); // In PCE rule, need to program 1, for PMAC 0 value = (1 << gswdev->cport); } - + if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_FORWARD) { - GSW_PCE_rule_t pcrule; - int i; + + for (i = 0; i < 2; i++) { memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); pcrule.pattern.bEnable = 1; pcrule.pattern.bProtocolEnable = 1; + switch (i) { case 0: - /* Management port remaining IGMP packets (forwarding */ - /* them to Router Ports) */ + /* Management port remaining IGMP packets (forwarding */ + /* them to Router Ports) */ pcrule.pattern.nIndex = MPCE_RULES_INDEX; pcrule.pattern.nProtocol = 0x2; /* IGMP */ pcrule.pattern.bAppMaskRangeMSB_Select = 1; @@ -7774,9 +10070,10 @@ GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, pcrule.pattern.nAppDataMSB = 0x1200; pcrule.pattern.nAppMaskRangeMSB = 0x1DFF; break; + case 1: - /* Management Port ICMPv6 Multicast Listerner Report */ - /* & Leave (Avoiding Loopback abd Discard) */ + /* Management Port ICMPv6 Multicast Listerner Report */ + /* & Leave (Avoiding Loopback abd Discard) */ pcrule.pattern.nIndex = MPCE_RULES_INDEX + 3; pcrule.pattern.bAppDataMSB_Enable = 1; pcrule.pattern.bAppMaskRangeMSB_Select = 1; @@ -7785,52 +10082,76 @@ GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, pcrule.pattern.nProtocol = 0x3A; /*for IPv6*/ break; } + /* Router portmap */ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; - pcrule.action.nForwardPortMap[0]= value; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + pcrule.action.nForwardPortMap[0] = value; + if (hitbl->igcos != 0) { pcrule.action.eTrafficClassAction = 1; //Govind - this should be 2? pcrule.action.nTrafficClassAlternate = gswdev->iflag.igcos; } + /* Set eForwardPort */ pcrule.pattern.bPortIdEnable = 1; + if (hitbl->igfport == GSW_PORT_FORWARD_PORT) pcrule.pattern.nPortId = hitbl->igfpid; else if (hitbl->igfport == GSW_PORT_FORWARD_CPU) - pcrule.pattern.nPortId = (gswdev->cport); + pcrule.pattern.nPortId = (gswdev->cport); + //Govind - what if both of above 'if' fails? Port-Id '0' will be written. if (hitbl->igxvlan) pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_CROSS; + GSW_PCE_ACTION_CROSS_VLAN_CROSS; else pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + /* We prepare everything and write into PCE Table */ if (0 != pce_rule_write(cdev, - &gswdev->phandler, &pcrule)) - return GSW_statusErr; + &gswdev->phandler, &pcrule)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_MulticastRouterPortRead(void *cdev, - GSW_multicastRouterRead_t *parm) + GSW_multicastRouterRead_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value_1, value_2; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { - pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + pr_err("%s:%s not supported in GSWIP v3.1 :%d\n", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + //Govind - Below registers are not supported in 3.1. Need to take care of it? if (parm->bInitial == 1) { /* Read the Default Router Port Map - DRPM*/ @@ -7845,41 +10166,66 @@ GSW_return_t GSW_MulticastRouterPortRead(void *cdev, parm->bInitial = 0; gswdev->mrtpcnt = 0; } + if (parm->bLast == 0) { /* Need to clarify the different between DRPM & IGPM */ while (((gswdev->iflag.igrport >> - gswdev->mrtpcnt) & 0x1) == 0) { + gswdev->mrtpcnt) & 0x1) == 0) { gswdev->mrtpcnt++; - if (gswdev->mrtpcnt > (gswdev->tpnum-1)) { + + if (gswdev->mrtpcnt > (gswdev->tpnum - 1)) { parm->bLast = 1; - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } } + parm->nPortId = gswdev->mrtpcnt; + if (gswdev->mrtpcnt < gswdev->tpnum) gswdev->mrtpcnt++; else parm->bLast = 1; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, - GSW_multicastRouter_t *parm) + GSW_multicastRouter_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); gsw_igmp_t *hitbl = &gswdev->iflag; u32 value_1, value_2; u8 pidx = parm->nPortId; + u32 ret; + static GSW_PCE_rule_t pcrule; + int i; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - if ((gswdev->gipver != LTQ_GSWIP_3_1) || - ((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if ((IS_VRSN_NOT_31(gswdev->gipver)) || + ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { //Govind - Below registers are not supported in 3.1. Need to take care of it? /* Read the Default Router Port Map - DRPM */ gsw_r32(cdev, PCE_IGMP_DRPM_DRPM_OFFSET, @@ -7889,34 +10235,37 @@ GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, gsw_r32(cdev, PCE_IGMP_STAT_IGPM_OFFSET, PCE_IGMP_STAT_IGPM_SHIFT, PCE_IGMP_STAT_IGPM_SIZE, &value_2); + if (((value_1 >> pidx) & 0x1) == 0) { pr_err("Error: the port was not in the member\n"); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } else { - value_1 = (value_1 & ~(1 << pidx)); - /* Write the Default Router Port Map - DRPM*/ - gsw_w32(cdev, PCE_IGMP_DRPM_DRPM_OFFSET, - PCE_IGMP_DRPM_DRPM_SHIFT, - PCE_IGMP_DRPM_DRPM_SIZE, value_1); + value_1 = (value_1 & ~(1 << pidx)); + /* Write the Default Router Port Map - DRPM*/ + gsw_w32(cdev, PCE_IGMP_DRPM_DRPM_OFFSET, + PCE_IGMP_DRPM_DRPM_SHIFT, + PCE_IGMP_DRPM_DRPM_SIZE, value_1); } } - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { value_1 = gsw_check_hashtable_entry(cdev); } + //Govind - Again creating a rule instaed of deleting? if ((hitbl->igmode == - GSW_MULTICAST_SNOOP_MODE_FORWARD) & value_1) { - GSW_PCE_rule_t pcrule; - int i; + GSW_MULTICAST_SNOOP_MODE_FORWARD) & value_1) { + for (i = 0; i < 2; i++) { memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); pcrule.pattern.bEnable = 1; pcrule.pattern.bProtocolEnable = 1; + switch (i) { case 0: - /* Management port remaining IGMP packets */ - /*(forwarding them to Router Ports) */ + /* Management port remaining IGMP packets */ + /*(forwarding them to Router Ports) */ pcrule.pattern.nIndex = MPCE_RULES_INDEX; /* for IPv4 */ pcrule.pattern.nProtocol = 0x2; @@ -7925,10 +10274,11 @@ GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, pcrule.pattern.nAppDataMSB = 0x1200; pcrule.pattern.nAppMaskRangeMSB = 0x1DFF; break; + case 1: - /* Management Port ICMPv6 Multicast Listerner Report */ - /* & Leave (Avoiding Loopback abd Discard) */ - pcrule.pattern.nIndex = MPCE_RULES_INDEX+3; + /* Management Port ICMPv6 Multicast Listerner Report */ + /* & Leave (Avoiding Loopback abd Discard) */ + pcrule.pattern.nIndex = MPCE_RULES_INDEX + 3; pcrule.pattern.bAppDataMSB_Enable = 1; pcrule.pattern.bAppMaskRangeMSB_Select = 1; pcrule.pattern.nAppDataMSB = 0x8300; @@ -7937,72 +10287,97 @@ GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, pcrule.pattern.nProtocol = 0x3A; break; } + /* Router portmap */ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; - pcrule.action.nForwardPortMap[0]= value_1; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + pcrule.action.nForwardPortMap[0] = value_1; + if (hitbl->igcos != 0) { pcrule.action.eTrafficClassAction = 1; pcrule.action.nTrafficClassAlternate = gswdev->iflag.igcos; } + /* Set eForwardPort */ pcrule.pattern.bPortIdEnable = 1; + if (hitbl->igfport == GSW_PORT_FORWARD_PORT) pcrule.pattern.nPortId = hitbl->igfpid; else if (hitbl->igfport == GSW_PORT_FORWARD_CPU) pcrule.pattern.nPortId = (gswdev->cport); + if (hitbl->igxvlan) pcrule.action.eVLAN_CrossAction = GSW_PCE_ACTION_CROSS_VLAN_CROSS; else pcrule.action.eVLAN_CrossAction = GSW_PCE_ACTION_CROSS_VLAN_DISABLE; - /* We prepare everything and write into PCE Table */ + + /* We prepare everything and write into PCE Table */ if (pce_rule_write(cdev, - &gswdev->phandler, &pcrule) != 0) - return GSW_statusErr; + &gswdev->phandler, &pcrule) != 0) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } else if ((hitbl->igmode == - GSW_MULTICAST_SNOOP_MODE_FORWARD) & !value_1){ - GSW_PCE_rule_t pcrule; - int i; + GSW_MULTICAST_SNOOP_MODE_FORWARD) & !value_1) { + for (i = 0; i < 2; i++) { memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); + switch (i) { case 0: pcrule.pattern.nIndex = MPCE_RULES_INDEX; break; + case 1: - /* Management Port ICMPv6 Multicast Listerner Report */ - /* & Leave (Avoiding Loopback abd Discard) */ + /* Management Port ICMPv6 Multicast Listerner Report */ + /* & Leave (Avoiding Loopback abd Discard) */ pcrule.pattern.nIndex = - MPCE_RULES_INDEX + 3; + MPCE_RULES_INDEX + 3; break; - } - if (pce_pattern_delete(cdev, &gswdev->phandler, pcrule.pattern.nIndex) != 0) - return GSW_statusErr; + } + + if (pce_pattern_delete(cdev, &gswdev->phandler, pcrule.pattern.nIndex) != 0) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } //Govind - Is this API compatible for 3.1? GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, - GSW_multicastSnoopCfg_t *parm) + GSW_multicastSnoopCfg_t *parm) { u32 data_1, data_2, value; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { //pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } parm->eIGMP_Mode = gswdev->iflag.igmode; @@ -8025,6 +10400,7 @@ GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, gsw_r32(cdev, PCE_IGMP_CTRL_JASUP_OFFSET, PCE_IGMP_CTRL_JASUP_SHIFT, PCE_IGMP_CTRL_JASUP_SIZE, &data_2); + if (data_1 == 0 && data_2 == 0) parm->eSuppressionAggregation = GSW_MULTICAST_TRANSPARENT; else if (data_1 == 1 && data_2 == 0) @@ -8037,22 +10413,26 @@ GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, gsw_r32(cdev, PCE_IGMP_CTRL_FLEAVE_OFFSET, PCE_IGMP_CTRL_FLEAVE_SHIFT, PCE_IGMP_CTRL_FLEAVE_SIZE, &value); + if (value == 1) parm->bFastLeave = 1; else parm->bFastLeave = 0; + gsw_r32(cdev, PCE_IGMP_CTRL_SRPEN_OFFSET, PCE_IGMP_CTRL_SRPEN_SHIFT, PCE_IGMP_CTRL_SRPEN_SIZE, &value); parm->bLearningRouter = value; + if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_r32(cdev, PCE_GCTRL_1_UKIPMC_OFFSET, PCE_GCTRL_1_UKIPMC_SHIFT, PCE_GCTRL_1_UKIPMC_SIZE, &parm->bMulticastUnknownDrop); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, PCE_GCTRL_1_MKFIDEN_OFFSET, PCE_GCTRL_1_MKFIDEN_SHIFT, @@ -8060,20 +10440,35 @@ GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, &parm->bMulticastFIDmode); } - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } //Govind - Is this API compatible for 3.1? GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, - GSW_multicastSnoopCfg_t *parm) + GSW_multicastSnoopCfg_t *parm) { u32 i, data_1 = 0, data_2 = 0, pmcindex = MPCE_RULES_INDEX; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - GSW_PCE_rule_t pcrule; + static GSW_PCE_rule_t pcrule; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /* Choose IGMP Mode */ switch (parm->eIGMP_Mode) { case GSW_MULTICAST_SNOOP_MODE_DISABLED: @@ -8084,12 +10479,15 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, gsw_w32(cdev, PCE_GCTRL_0_IGMP_OFFSET, PCE_GCTRL_0_IGMP_SHIFT, PCE_GCTRL_0_IGMP_SIZE, 0); + for (i = 0; i <= gswdev->tpnum; i++) { gsw_w32(cdev, PCE_PCTRL_0_MCST_OFFSET + (0xA * i), PCE_PCTRL_0_MCST_SHIFT, PCE_PCTRL_0_MCST_SIZE, 0); } + break; + case GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING: /* Snooping of Router Port Enable */ gsw_w32(cdev, PCE_GCTRL_0_IGMP_OFFSET, @@ -8098,36 +10496,47 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, gsw_w32(cdev, PCE_IGMP_CTRL_SRPEN_OFFSET, PCE_IGMP_CTRL_SRPEN_SHIFT, PCE_IGMP_CTRL_SRPEN_SIZE, 1); + for (i = 0; i <= gswdev->tpnum; i++) { gsw_w32(cdev, PCE_PCTRL_0_MCST_OFFSET + (0xA * i), PCE_PCTRL_0_MCST_SHIFT, PCE_PCTRL_0_MCST_SIZE, 1); } + break; + case GSW_MULTICAST_SNOOP_MODE_FORWARD: + /* Snooping of Router Port Forward */ - if ((gswdev->gipver != LTQ_GSWIP_3_1) || - ((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { - gsw_w32(cdev, PCE_IGMP_CTRL_SRPEN_OFFSET, - PCE_IGMP_CTRL_SRPEN_SHIFT, - PCE_IGMP_CTRL_SRPEN_SIZE, 0); + if ((IS_VRSN_NOT_31(gswdev->gipver)) || + ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { + gsw_w32(cdev, PCE_IGMP_CTRL_SRPEN_OFFSET, + PCE_IGMP_CTRL_SRPEN_SHIFT, + PCE_IGMP_CTRL_SRPEN_SIZE, 0); } + gsw_w32(cdev, PCE_GCTRL_0_IGMP_OFFSET, PCE_GCTRL_0_IGMP_SHIFT, PCE_GCTRL_0_IGMP_SIZE, 1); - if ((gswdev->gipver != LTQ_GSWIP_3_1) || - ((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { + + if ((IS_VRSN_NOT_31(gswdev->gipver)) || + ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_EN))) { for (i = 0; i < gswdev->tpnum; i++) { gsw_w32(cdev, PCE_PCTRL_0_MCST_OFFSET + (0xA * i), PCE_PCTRL_0_MCST_SHIFT, PCE_PCTRL_0_MCST_SIZE, 1); } } + break; + default: pr_err("This Mode doesn't exists\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Set the Flag for eIGMP_Mode flag*/ gswdev->iflag.igmode = parm->eIGMP_Mode; /* Set bIGMPv3 flag*/ @@ -8136,30 +10545,34 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, gswdev->iflag.igxvlan = parm->bCrossVLAN; /* Set eForwardPort flag */ gswdev->iflag.igfport = parm->eForwardPort; + /* Set nForwardPortId */ if (parm->eForwardPort == GSW_PORT_FORWARD_CPU) gswdev->iflag.igfpid = (1 << gswdev->cport); else gswdev->iflag.igfpid = parm->nForwardPortId; + gswdev->iflag.igcos = parm->nClassOfService; -/* If IGMP mode set to AutoLearning then the following Rule have to add it */ + + /* If IGMP mode set to AutoLearning then the following Rule have to add it */ if (parm->eIGMP_Mode == - GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { + GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { - //pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + //pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } for (i = pmcindex; i <= (pmcindex + 7); i++) { memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); pcrule.pattern.nIndex = i; pcrule.pattern.bEnable = 1; pcrule.pattern.bAppDataMSB_Enable = 1; + if ((i == pmcindex + 0) || - (i == pmcindex + 1) || - (i == pmcindex + 2)) + (i == pmcindex + 1) || + (i == pmcindex + 2)) pcrule.pattern.nAppDataMSB = 0x1100; else if (i == pmcindex + 3) pcrule.pattern.nAppDataMSB = 0x1200; @@ -8173,34 +10586,41 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, pcrule.pattern.nAppDataMSB = 0x3000; pcrule.pattern.bAppMaskRangeMSB_Select = 0; -/* if (gswdev->gipver == LTQ_GSWIP_3_0) { */ -/* pcrule.pattern.nAppMaskRangeMSB = 0x0; */ -/* } else { */ - pcrule.pattern.nAppMaskRangeMSB = 0x3; - /* } */ + /* if (gswdev->gipver == LTQ_GSWIP_3_0) { */ + /* pcrule.pattern.nAppMaskRangeMSB = 0x0; */ + /* } else { */ + pcrule.pattern.nAppMaskRangeMSB = 0x3; + + /* } */ if ((i == pmcindex + 0) || - (i == pmcindex + 1) || - (i == pmcindex + 6) || - (i == pmcindex + 7)) + (i == pmcindex + 1) || + (i == pmcindex + 6) || + (i == pmcindex + 7)) pcrule.pattern.eDstIP_Select = 1; + if ((i == pmcindex + 0) || - (i == pmcindex + 1)) + (i == pmcindex + 1)) pcrule.pattern.nDstIP.nIPv4 = 0xE0000001; else if (i == pmcindex + 6) pcrule.pattern.nDstIP.nIPv4 = 0xE0000002; else if (i == pmcindex + 7) pcrule.pattern.nDstIP.nIPv4 = 0xE00000A6; + pcrule.pattern.nDstIP_Mask = 0xFF00; + if (i == pmcindex + 1) pcrule.pattern.eSrcIP_Select = 1; else pcrule.pattern.eSrcIP_Select = 0; + if (i == pmcindex + 1) pcrule.pattern.nSrcIP_Mask = 0xFF00; else pcrule.pattern.nSrcIP_Mask = 0xFFFF; + pcrule.pattern.bProtocolEnable = 1; pcrule.pattern.nProtocol = 0x2; + if (gswdev->iflag.igcos == 0) { pcrule.action.eTrafficClassAction = 0; pcrule.action.nTrafficClassAlternate = 0; @@ -8209,44 +10629,51 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, pcrule.action.nTrafficClassAlternate = gswdev->iflag.igcos; } + if (i == pmcindex + 0) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_QUERY; + GSW_PCE_ACTION_IGMP_SNOOP_QUERY; else if (i == pmcindex + 1) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER; + GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER; else if (i == pmcindex + 2) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP; + GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP; else if (i == pmcindex + 3) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_REPORT; + GSW_PCE_ACTION_IGMP_SNOOP_REPORT; else if (i == pmcindex + 4) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_REPORT; + GSW_PCE_ACTION_IGMP_SNOOP_REPORT; else if (i == pmcindex + 5) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_LEAVE; + GSW_PCE_ACTION_IGMP_SNOOP_LEAVE; else if (i == pmcindex + 6) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_AD; + GSW_PCE_ACTION_IGMP_SNOOP_AD; else if (i == pmcindex + 7) pcrule.action.eSnoopingTypeAction = - GSW_PCE_ACTION_IGMP_SNOOP_AD; + GSW_PCE_ACTION_IGMP_SNOOP_AD; + pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_MULTICAST_ROUTER; + GSW_PCE_ACTION_PORTMAP_MULTICAST_ROUTER; + if (parm->bCrossVLAN) pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_CROSS; + GSW_PCE_ACTION_CROSS_VLAN_CROSS; else pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + /* We prepare everything and write into PCE Table */ if (0 != pce_rule_write(cdev, - &gswdev->phandler, &pcrule)) - return GSW_statusErr; + &gswdev->phandler, &pcrule)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } + /* If IGMP mode set to forwarding then the */ /* following Rule have to add it */ if (parm->eIGMP_Mode == GSW_MULTICAST_SNOOP_MODE_FORWARD) { @@ -8255,50 +10682,55 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, pcrule.pattern.nIndex = i; pcrule.pattern.bEnable = 1; pcrule.pattern.bProtocolEnable = 1; + switch (i - pmcindex) { -/* case 0: */ -/*Rule added by Router port ADD function based on router port for IPv4*/ -/* break; */ + /* case 0: */ + /*Rule added by Router port ADD function based on router port for IPv4*/ + /* break; */ case 1: -/* Avoid IGMP Packets Redirection when seen on Management Port */ + /* Avoid IGMP Packets Redirection when seen on Management Port */ pcrule.pattern.nProtocol = 0x2; /* for IPv4 */ pcrule.pattern.bPortIdEnable = 1; - /* Action Enabled, no redirection (default portmap) */ + /* Action Enabled, no redirection (default portmap) */ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_REGULAR; + GSW_PCE_ACTION_PORTMAP_REGULAR; break; + case 2: /* IGMPv1/2/3 IPv4 */ pcrule.pattern.nProtocol = 0x2; /* for IPv4 */ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; break; -/* case 3: */ - /*Rules added by Router port ADD function */ - /* based on router port for IPv6 */ -/* break; */ + + /* case 3: */ + /*Rules added by Router port ADD function */ + /* based on router port for IPv6 */ + /* break; */ case 4: - /* Managemnt Port Remaining ICMPv6/MLD packets */ - /* (Avoiding Loopback and Disacard) */ + /* Managemnt Port Remaining ICMPv6/MLD packets */ + /* (Avoiding Loopback and Disacard) */ pcrule.pattern.bPortIdEnable = 1; pcrule.pattern.nPortId = parm->nForwardPortId; pcrule.pattern.nProtocol = 0x3A; /*for IPv6*/ pcrule.pattern.bPortIdEnable = 1; pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_REGULAR; + GSW_PCE_ACTION_PORTMAP_REGULAR; break; + case 5: - /* ICMPv6 Multicast Listener Query/Report/Done(Leave) */ + /* ICMPv6 Multicast Listener Query/Report/Done(Leave) */ pcrule.pattern.bAppDataMSB_Enable = 1; pcrule.pattern.bAppMaskRangeMSB_Select = 1; pcrule.pattern.nAppDataMSB = 0x8200; pcrule.pattern.nAppMaskRangeMSB = 0x2FF; pcrule.pattern.nProtocol = 0x3A; /*for IPv6*/ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; break; + case 6: - /* ICMPv6 Multicast Listener Report */ + /* ICMPv6 Multicast Listener Report */ pcrule.pattern.bAppDataMSB_Enable = 1; pcrule.pattern.nAppDataMSB = 0x8F00; pcrule.pattern.nAppMaskRangeMSB = 0x3; @@ -8306,74 +10738,89 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, pcrule.action.ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; break; + case 7: - /* ICMPv6 Multicast Router Advertisement/Solicitation/Termination */ + /* ICMPv6 Multicast Router Advertisement/Solicitation/Termination */ pcrule.pattern.bAppDataMSB_Enable = 1; pcrule.pattern.bAppMaskRangeMSB_Select = 1; pcrule.pattern.nAppDataMSB = 0x9700; pcrule.pattern.nAppMaskRangeMSB = 0x2FF; pcrule.pattern.nProtocol = 0x3A; /*for IPv6*/ pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; break; + default: continue; } + if (gswdev->iflag.igcos != 0) { pcrule.action.eTrafficClassAction = 1; pcrule.action.nTrafficClassAlternate = - gswdev->iflag.igcos; + gswdev->iflag.igcos; } + /* Set eForwardPort */ if (parm->eForwardPort == GSW_PORT_FORWARD_PORT) { - pcrule.action.nForwardPortMap[0]= - (1 << parm->nForwardPortId); + pcrule.action.nForwardPortMap[0] = + (1 << parm->nForwardPortId); pcrule.pattern.nPortId = parm->nForwardPortId; } else if (parm->eForwardPort == GSW_PORT_FORWARD_CPU) { - pcrule.action.nForwardPortMap[0]= - (1 << gswdev->cport); + pcrule.action.nForwardPortMap[0] = + (1 << gswdev->cport); pcrule.pattern.nPortId = gswdev->cport; } + if (parm->bCrossVLAN) pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_CROSS; + GSW_PCE_ACTION_CROSS_VLAN_CROSS; else pcrule.action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + GSW_PCE_ACTION_CROSS_VLAN_DISABLE; + /* We prepare everything and write into PCE Table */ if (pce_rule_write(cdev, - &gswdev->phandler, &pcrule) != 0) - return GSW_statusErr; + &gswdev->phandler, &pcrule) != 0) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { //pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } if (parm->eIGMP_Mode == - GSW_MULTICAST_SNOOP_MODE_DISABLED) { + GSW_MULTICAST_SNOOP_MODE_DISABLED) { pmcindex = MPCE_RULES_INDEX; + for (i = pmcindex; i <= (pmcindex + 7); i++) { pcrule.pattern.nIndex = i; pcrule.pattern.bEnable = 0; + /* We prepare everything and write into PCE Table */ - if (0 != pce_pattern_delete(cdev, &gswdev->phandler, i)) - return GSW_statusErr; + if (0 != pce_pattern_delete(cdev, &gswdev->phandler, i)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } + if (parm->nRobust < 4) { gsw_w32(cdev, PCE_IGMP_CTRL_ROB_OFFSET, PCE_IGMP_CTRL_ROB_SHIFT, PCE_IGMP_CTRL_ROB_SIZE, parm->nRobust); } else { pr_err("The Robust time would only support 0..3\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + gsw_w32(cdev, PCE_IGMP_CTRL_DMRTEN_OFFSET, PCE_IGMP_CTRL_DMRTEN_SHIFT, PCE_IGMP_CTRL_DMRTEN_SIZE, 1); @@ -8382,20 +10829,26 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, PCE_IGMP_CTRL_DMRT_SIZE, parm->nQueryInterval); - + if (parm->eIGMP_Mode == - GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { + GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { switch (parm->eSuppressionAggregation) { case GSW_MULTICAST_REPORT_JOIN: - data_2 = 1; data_1 = 1; + data_2 = 1; + data_1 = 1; break; + case GSW_MULTICAST_REPORT: - data_2 = 0; data_1 = 1; + data_2 = 0; + data_1 = 1; break; + case GSW_MULTICAST_TRANSPARENT: - data_2 = 0; data_1 = 0; + data_2 = 0; + data_1 = 0; break; } + gsw_w32(cdev, PCE_IGMP_CTRL_REPSUP_OFFSET, PCE_IGMP_CTRL_REPSUP_SHIFT, PCE_IGMP_CTRL_REPSUP_SIZE, data_1); @@ -8405,11 +10858,12 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, } if (parm->eIGMP_Mode == - GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { + GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { gsw_w32(cdev, PCE_IGMP_CTRL_SRPEN_OFFSET, PCE_IGMP_CTRL_SRPEN_SHIFT, PCE_IGMP_CTRL_SRPEN_SIZE, parm->bLearningRouter); + if (parm->bFastLeave == 1) gsw_w32(cdev, PCE_IGMP_CTRL_FLEAVE_OFFSET, PCE_IGMP_CTRL_FLEAVE_SHIFT, @@ -8423,14 +10877,16 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, PCE_IGMP_CTRL_FLEAVE_SHIFT, PCE_IGMP_CTRL_FLEAVE_SIZE, 0); } + if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0)) { + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (gswdev->gipver == LTQ_GSWIP_3_0)) { gsw_w32(cdev, PCE_GCTRL_1_UKIPMC_OFFSET, PCE_GCTRL_1_UKIPMC_SHIFT, PCE_GCTRL_1_UKIPMC_SIZE, parm->bMulticastUnknownDrop); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, PCE_GCTRL_1_MKFIDEN_OFFSET, PCE_GCTRL_1_MKFIDEN_SHIFT, @@ -8438,67 +10894,93 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, parm->bMulticastFIDmode); } - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_MulticastTableEntryAdd(void *cdev, - GSW_multicastTable_t *parm) + GSW_multicastTable_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); gsw_igmp_t *hitbl = &gswdev->iflag; u8 pidx = parm->nPortId; - pctbl_prog_t ptdata; + static pctbl_prog_t ptdata; int ret = 0; - + u32 index = 0, i, available = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + ret = GSW_statusErr; + + goto UNLOCK_AND_RETURN; } + memset(&ptdata, 0, sizeof(pctbl_prog_t)); + if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { - u32 index = 0, i, available = 0; - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { - pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusErr; + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + pr_err("%s:%s not supported in GSWIP v3.1 :%d\n", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } if ((gswdev->iflag.igv3 == 1) || - (parm->eIPVersion == GSW_IP_SELECT_IPV6)) - return GSW_statusErr; + (parm->eIPVersion == GSW_IP_SELECT_IPV6)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Read Out all of the HW Table */ for (i = 0; i < gswdev->mctblsize; i++) { ptdata.table = PCE_MULTICAST_HW_INDEX; ptdata.pcindex = i; gsw_pce_table_read(cdev, &ptdata); + if (ptdata.valid) { if ((ptdata.key[0] == - (parm->uIP_Gda.nIPv4 & 0xFFFF)) && - (ptdata.key[1] == - ((parm->uIP_Gda.nIPv4 >> 16) & 0xFFFF))) { + (parm->uIP_Gda.nIPv4 & 0xFFFF)) && + (ptdata.key[1] == + ((parm->uIP_Gda.nIPv4 >> 16) & 0xFFFF))) { index = i; available = 1; break; } } } + ptdata.table = PCE_MULTICAST_HW_INDEX; + if (available == 0) { index = gswdev->mctblsize; + for (i = 0; i < gswdev->mctblsize; i++) { ptdata.pcindex = i; gsw_pce_table_read(cdev, &ptdata); + if (ptdata.valid == 0) { index = i; /* Free index */ break; } } } + if (index < gswdev->mctblsize) { ptdata.table = PCE_MULTICAST_HW_INDEX; ptdata.pcindex = index; @@ -8510,66 +10992,86 @@ GSW_return_t GSW_MulticastTableEntryAdd(void *cdev, gsw_pce_table_write(cdev, &ptdata); } else { pr_err("Error: (IGMP HW Table is full) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } else if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_FORWARD) { /* Program the Multicast SW Table */ if (gswdev->gipver == LTQ_GSWIP_3_0) gsw3x_msw_table_wr(cdev, parm); - else if (gswdev->gipver == LTQ_GSWIP_3_1) { + else if (IS_VRSN_31(gswdev->gipver)) { ret = gsw_insert_hashtable_entry(cdev, parm); - if(ret < 0) { - pr_err("%s:%s Entry Cannot insert :%d %d\n",__FILE__, __func__, __LINE__, ret); - return GSW_statusErr; - } - } - else + + if (ret < 0) { + pr_err("%s:%s Entry Cannot insert :%d %d\n", __FILE__, __func__, __LINE__, ret); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + } else gsw2x_msw_table_wr(cdev, parm); } else { /* Disable All Multicast SW Table */ pr_err("Please Select the IGMP Mode through Multicast Snooping Configuration API\n"); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_MulticastTableEntryRead(void *cdev, - GSW_multicastTableRead_t *parm) + GSW_multicastTableRead_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); gsw_igmp_t *hitbl = &gswdev->iflag; - pctbl_prog_t ptdata; + static pctbl_prog_t ptdata; u32 ret = 0; - + u32 dlsbid, slsbid, dmsbid, smsbid; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_DISABLED) { pr_err("Error: (IGMP snoop is not enabled) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - return GSW_statusErr; + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { - pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusErr; + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + pr_err("%s:%s not supported in GSWIP v3.1 :%d\n", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } if (parm->bInitial == 1) { gswdev->mhw_rinx = 0; /*Start from the index 0 */ parm->bInitial = 0; } + if (gswdev->mhw_rinx >= gswdev->mctblsize) { memset(parm, 0, sizeof(GSW_multicastTableRead_t)); parm->bLast = 1; gswdev->mhw_rinx = 0; - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } do { @@ -8578,14 +11080,16 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, ptdata.pcindex = gswdev->mhw_rinx; gsw_pce_table_read(cdev, &ptdata); gswdev->mhw_rinx++; + if (ptdata.valid != 0) break; } while (gswdev->mhw_rinx < gswdev->mctblsize); + if (ptdata.valid != 0) { parm->nPortId = ptdata.val[0] | 0x80000000; parm->uIP_Gda.nIPv4 = - ((ptdata.key[1] << 16) | - ptdata.key[0]); + ((ptdata.key[1] << 16) | + ptdata.key[0]); parm->uIP_Gsa.nIPv4 = 0; parm->eModeMember = GSW_IGMP_MEMBER_DONT_CARE; parm->eIPVersion = GSW_IP_SELECT_IPV4; @@ -8600,33 +11104,36 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, /*Snooping in Forward mode */ if (hitbl->igmode == GSW_MULTICAST_SNOOP_MODE_FORWARD) { - u32 dlsbid, slsbid, dmsbid, smsbid; + if (parm->bInitial == 1) { gswdev->msw_rinx = 0; /*Start from the index 0 */ parm->bInitial = 0; } + if (gswdev->msw_rinx >= gswdev->mctblsize) { memset(parm, 0, sizeof(GSW_multicastTableRead_t)); parm->bLast = 1; gswdev->msw_rinx = 0; - return GSW_statusOk; + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; } - if(gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { do { ret = gsw_get_swmcast_entry(cdev, parm, gswdev->msw_rinx); gswdev->msw_rinx++; - if(ret != 0) + + if (ret != 0) break; - + } while (gswdev->msw_rinx < gswdev->mctblsize); - if(ret) { + if (ret) { parm->bInitial = 0; parm->bLast = 0; - return GSW_statusOk; - } - else { + ret = GSW_statusOk; + goto UNLOCK_AND_RETURN; + } else { memset(parm, 0, sizeof(GSW_multicastTableRead_t)); parm->bLast = 1; gswdev->msw_rinx = 0; @@ -8639,6 +11146,7 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, ptdata.pcindex = gswdev->msw_rinx; gsw_pce_table_read(cdev, &ptdata); gswdev->msw_rinx++; + if (ptdata.valid != 0) break; } while (gswdev->msw_rinx < gswdev->mctblsize); @@ -8646,37 +11154,41 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, if (ptdata.valid == 1) { pctbl_prog_t iptbl; parm->nPortId = ptdata.val[0] | 0x80000000; + if (gswdev->gipver == LTQ_GSWIP_3_0) { parm->nSubIfId = (ptdata.val[1] >> 3) & 0xFFFF; parm->nFID = (ptdata.key[2] & 0x3F); parm->bExclSrcIP = - ((ptdata.key[2] >> 15) & 0x1); + ((ptdata.key[2] >> 15) & 0x1); } + dlsbid = ptdata.key[0] & 0xFF; dmsbid = (ptdata.key[0] >> 8) & 0xFF; slsbid = ptdata.key[1] & 0xFF; smsbid = (ptdata.key[1] >> 8) & 0xFF; + if (dlsbid <= 0x3F) { memset(&iptbl, 0, sizeof(pctbl_prog_t)); iptbl.table = PCE_IP_DASA_LSB_INDEX; /* Search the DIP */ iptbl.pcindex = dlsbid; gsw_pce_table_read(cdev, &iptbl); + if (iptbl.valid == 1) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((iptbl.mask[0] == 0x0) && - ((iptbl.mask[1] == 0x0)) && - ((iptbl.mask[2] == 0xFFFF)) && - ((iptbl.mask[3] == 0xFFFF))) { + ((iptbl.mask[1] == 0x0)) && + ((iptbl.mask[2] == 0xFFFF)) && + ((iptbl.mask[3] == 0xFFFF))) { parm->uIP_Gda.nIPv4 = - ((iptbl.key[1] << 16) - | (iptbl.key[0])); + ((iptbl.key[1] << 16) + | (iptbl.key[0])); parm->eIPVersion = - GSW_IP_SELECT_IPV4; + GSW_IP_SELECT_IPV4; } else if ((iptbl.mask[0] == 0x0) && - ((iptbl.mask[1] == 0x0)) && - ((iptbl.mask[2] == 0x0)) && - ((iptbl.mask[3] == 0x0))) { + ((iptbl.mask[1] == 0x0)) && + ((iptbl.mask[2] == 0x0)) && + ((iptbl.mask[3] == 0x0))) { parm->uIP_Gda.nIPv6[4] = (iptbl.key[3]); parm->uIP_Gda.nIPv6[5] = @@ -8686,15 +11198,15 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, parm->uIP_Gda.nIPv6[7] = (iptbl.key[0]); parm->eIPVersion = - GSW_IP_SELECT_IPV6; + GSW_IP_SELECT_IPV6; } } else { if (iptbl.mask[0] == 0xFF00) { parm->uIP_Gda.nIPv4 = - ((iptbl.key[1] << 16) - | (iptbl.key[0])); + ((iptbl.key[1] << 16) + | (iptbl.key[0])); parm->eIPVersion = - GSW_IP_SELECT_IPV4; + GSW_IP_SELECT_IPV4; } else if (iptbl.mask[0] == 0x0) { parm->uIP_Gda.nIPv6[4] = (iptbl.key[3]); @@ -8705,48 +11217,50 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, parm->uIP_Gda.nIPv6[7] = (iptbl.key[0]); parm->eIPVersion = - GSW_IP_SELECT_IPV6; + GSW_IP_SELECT_IPV6; } } } } + if (slsbid <= 0x3F) { memset(&iptbl, 0, sizeof(pctbl_prog_t)); iptbl.table = PCE_IP_DASA_LSB_INDEX; /* Search the SIP */ iptbl.pcindex = slsbid; gsw_pce_table_read(cdev, &iptbl); + if (iptbl.valid == 1) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((iptbl.mask[0] == 0x0) && - ((iptbl.mask[1] == 0x0)) && - ((iptbl.mask[2] == 0xFFFF)) && - ((iptbl.mask[3] == 0xFFFF))) { + ((iptbl.mask[1] == 0x0)) && + ((iptbl.mask[2] == 0xFFFF)) && + ((iptbl.mask[3] == 0xFFFF))) { parm->uIP_Gsa.nIPv4 = - ((iptbl.key[1] << 16) - | (iptbl.key[0])); + ((iptbl.key[1] << 16) + | (iptbl.key[0])); parm->eIPVersion = - GSW_IP_SELECT_IPV4; + GSW_IP_SELECT_IPV4; } else if ((iptbl.mask[0] == 0x0) && - ((iptbl.mask[1] == 0x0)) && - ((iptbl.mask[2] == 0x0)) && - ((iptbl.mask[3] == 0x0))) { + ((iptbl.mask[1] == 0x0)) && + ((iptbl.mask[2] == 0x0)) && + ((iptbl.mask[3] == 0x0))) { parm->uIP_Gsa.nIPv6[4] = - (iptbl.key[3]); + (iptbl.key[3]); parm->uIP_Gsa.nIPv6[5] = - (iptbl.key[2]); + (iptbl.key[2]); parm->uIP_Gsa.nIPv6[6] = - (iptbl.key[1]); + (iptbl.key[1]); parm->uIP_Gsa.nIPv6[7] = - (iptbl.key[0]); + (iptbl.key[0]); } } else { if (iptbl.mask[0] == 0xFF00) { parm->uIP_Gsa.nIPv4 = - ((iptbl.key[1] << 16) - | (iptbl.key[0])); + ((iptbl.key[1] << 16) + | (iptbl.key[0])); parm->eIPVersion = - GSW_IP_SELECT_IPV4; + GSW_IP_SELECT_IPV4; } else if (iptbl.mask == 0x0) { parm->uIP_Gsa.nIPv6[4] = (iptbl.key[3]); @@ -8760,18 +11274,20 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, } } } + if (dmsbid <= 0xF) { memset(&iptbl, 0, sizeof(pctbl_prog_t)); iptbl.table = PCE_IP_DASA_MSB_INDEX; /* Search the DIP */ iptbl.pcindex = dmsbid; gsw_pce_table_read(cdev, &iptbl); + if (iptbl.valid == 1) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((iptbl.mask[0] == 0) && - ((iptbl.mask[1] == 0)) && - ((iptbl.mask[2] == 0)) && - ((iptbl.mask[3] == 0))) { + ((iptbl.mask[1] == 0)) && + ((iptbl.mask[2] == 0)) && + ((iptbl.mask[3] == 0))) { parm->uIP_Gda.nIPv6[0] = (iptbl.key[3]); parm->uIP_Gda.nIPv6[1] = @@ -8795,18 +11311,20 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, } } } + if (smsbid <= 0xF) { memset(&iptbl, 0, sizeof(pctbl_prog_t)); iptbl.table = PCE_IP_DASA_MSB_INDEX; /* Search the DIP */ iptbl.pcindex = smsbid; gsw_pce_table_read(cdev, &iptbl); + if (iptbl.valid == 1) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if ((iptbl.mask[0] == 0) && - ((iptbl.mask[1] == 0)) && - ((iptbl.mask[2] == 0)) && - ((iptbl.mask[3] == 0))) { + ((iptbl.mask[1] == 0)) && + ((iptbl.mask[2] == 0)) && + ((iptbl.mask[3] == 0))) { parm->uIP_Gsa.nIPv6[0] = (iptbl.key[3]); parm->uIP_Gsa.nIPv6[1] = @@ -8830,8 +11348,9 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, } } } + parm->eModeMember = - hitbl->mctable[gswdev->msw_rinx-1].mcmode; + hitbl->mctable[gswdev->msw_rinx - 1].mcmode; parm->bInitial = 0; parm->bLast = 0; } else { @@ -8839,57 +11358,73 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, parm->bLast = 1; gswdev->msw_rinx = 0; } - } - - return GSW_statusOk; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_MulticastTableEntryRemove(void *cdev, - GSW_multicastTable_t *parm) + GSW_multicastTable_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); gsw_igmp_t *hitbl = &gswdev->iflag; u8 pidx = parm->nPortId; - pctbl_prog_t ptdata; + static pctbl_prog_t ptdata; ltq_bool_t dflag = 0; u32 port = 0, i; int ret = 0; - + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + ret = GSW_statusErr; } memset(&ptdata, 0, sizeof(pctbl_prog_t)); - if (hitbl->igmode == - GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { + GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING) { - if((gswdev->gipver == LTQ_GSWIP_3_1) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) - { - pr_err("%s:%s not supported in GSWIP v3.1 :%d\n",__FILE__, __func__, __LINE__); - return GSW_statusErr; + if ((IS_VRSN_31(gswdev->gipver)) && (gswdev->mcsthw_snoop == MCAST_HWSNOOP_DIS)) { + pr_err("%s:%s not supported in GSWIP v3.1 :%d\n", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (gswdev->iflag.igv3 == 1) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if (gswdev->iflag.igv3 == 1) - return GSW_statusErr; /* Read Out all of the HW Table */ for (i = 0; i < gswdev->mctblsize; i++) { memset(&ptdata, 0, sizeof(pctbl_prog_t)); ptdata.table = PCE_MULTICAST_HW_INDEX; ptdata.pcindex = i; gsw_pce_table_read(cdev, &ptdata); + /* Fill into Structure */ if (((ptdata.val[0] >> pidx) & 0x1) == 1) { if (parm->uIP_Gda.nIPv4 == - ((ptdata.key[1] << 16) - | (ptdata.key[0]))) { + ((ptdata.key[1] << 16) + | (ptdata.key[0]))) { port = (ptdata.val[0] & (~(1 << pidx))); + if (port == 0) { ptdata.val[0] = 0; ptdata.key[1] = 0; @@ -8897,44 +11432,67 @@ GSW_return_t GSW_MulticastTableEntryRemove(void *cdev, } else { ptdata.val[0] &= ~(1 << pidx); } + dflag = 1; gsw_pce_table_write(cdev, &ptdata); } } } + if (dflag == 0) pr_err("The input did not found\n"); - } - else if (hitbl->igmode == - GSW_MULTICAST_SNOOP_MODE_FORWARD) { - if (gswdev->gipver == LTQ_GSWIP_3_0) - gsw3x_msw_table_rm(cdev, parm); - else if (gswdev->gipver == LTQ_GSWIP_3_1) { - ret = gsw_remove_hashtable_entry(cdev, parm); - if(ret < 0) { - pr_err("%s:%s Entry Cannot remove :%d %d\n",__FILE__, __func__, __LINE__, ret); - return GSW_statusErr; - } + } else if (hitbl->igmode == + GSW_MULTICAST_SNOOP_MODE_FORWARD) { + if (gswdev->gipver == LTQ_GSWIP_3_0) + gsw3x_msw_table_rm(cdev, parm); + else if (IS_VRSN_31(gswdev->gipver)) { + ret = gsw_remove_hashtable_entry(cdev, parm); + + if (ret < 0) { + pr_err("%s:%s Entry Cannot remove :%d %d\n", __FILE__, __func__, __LINE__, ret); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - else - gsw2x_msw_table_rm(cdev, parm); - } - return GSW_statusOk; + } else + gsw2x_msw_table_rm(cdev, parm); + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } + #endif /*CONFIG_LTQ_MULTICAST*/ + GSW_return_t GSW_CapGet(void *cdev, GSW_cap_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value, data1, data2; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } - if (parm->nCapType >= GSW_CAP_TYPE_LAST) - return GSW_statusErr; - else + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nCapType >= GSW_CAP_TYPE_LAST) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } else { strcpy(parm->cDesc, capdes[parm->nCapType].desci); - /* As request, attached the code in the next version*/ + /* As request, attached the code in the next version*/ + } + switch (parm->nCapType) { case GSW_CAP_TYPE_PORT: gsw_r32(cdev, ETHSW_CAP_1_PPORTS_OFFSET, @@ -8942,12 +11500,14 @@ GSW_return_t GSW_CapGet(void *cdev, GSW_cap_t *parm) ETHSW_CAP_1_PPORTS_SIZE, &value); parm->nCap = value; break; + case GSW_CAP_TYPE_VIRTUAL_PORT: gsw_r32(cdev, ETHSW_CAP_1_VPORTS_OFFSET, ETHSW_CAP_1_VPORTS_SHIFT, ETHSW_CAP_1_VPORTS_SIZE, &value); parm->nCap = value; break; + case GSW_CAP_TYPE_BUFFER_SIZE: gsw_r32(cdev, ETHSW_CAP_11_BSIZEL_OFFSET, ETHSW_CAP_11_BSIZEL_SHIFT, @@ -8957,95 +11517,137 @@ GSW_return_t GSW_CapGet(void *cdev, GSW_cap_t *parm) ETHSW_CAP_12_BSIZEH_SIZE, &data2); parm->nCap = (data2 << 16 | data1); break; + case GSW_CAP_TYPE_SEGMENT_SIZE: /* This is Hard coded */ parm->nCap = LTQ_SOC_CAP_SEGMENT; break; + case GSW_CAP_TYPE_PRIORITY_QUEUE: parm->nCap = gswdev->num_of_queues; break; + case GSW_CAP_TYPE_METER: parm->nCap = gswdev->num_of_meters; break; + case GSW_CAP_TYPE_RATE_SHAPER: parm->nCap = gswdev->num_of_shapers; break; + case GSW_CAP_TYPE_VLAN_GROUP: parm->nCap = gswdev->avlantsz; break; + case GSW_CAP_TYPE_FID: /* This is Hard coded */ parm->nCap = VRX_PLATFORM_CAP_FID; break; + case GSW_CAP_TYPE_MAC_TABLE_SIZE: parm->nCap = gswdev->mactblsize; break; + case GSW_CAP_TYPE_MULTICAST_TABLE_SIZE: parm->nCap = gswdev->mctblsize; break; + case GSW_CAP_TYPE_PPPOE_SESSION: parm->nCap = gswdev->num_of_pppoe; break; + case GSW_CAP_TYPE_SVLAN_GROUP: parm->nCap = gswdev->avlantsz; break; + case GSW_CAP_TYPE_PMAC: parm->nCap = gswdev->num_of_pmac; break; + case GSW_CAP_TYPE_PAYLOAD: parm->nCap = gswdev->pdtblsize; break; + case GSW_CAP_TYPE_IF_RMON: parm->nCap = gswdev->num_of_ifrmon; break; + case GSW_CAP_TYPE_EGRESS_VLAN: parm->nCap = gswdev->num_of_egvlan; break; + case GSW_CAP_TYPE_RT_SMAC: parm->nCap = gswdev->num_of_rt_smac; break; + case GSW_CAP_TYPE_RT_DMAC: parm->nCap = gswdev->num_of_rt_dmac; break; + case GSW_CAP_TYPE_RT_PPPoE: parm->nCap = gswdev->num_of_rt_ppoe; break; + case GSW_CAP_TYPE_RT_NAT: parm->nCap = gswdev->num_of_rt_nat; break; + case GSW_CAP_TYPE_RT_MTU: parm->nCap = gswdev->num_of_rt_mtu; break; + case GSW_CAP_TYPE_RT_TUNNEL: parm->nCap = gswdev->num_of_rt_tunnel; break; + case GSW_CAP_TYPE_RT_RTP: parm->nCap = gswdev->num_of_rt_rtp; break; + case GSW_CAP_TYPE_LAST: parm->nCap = GSW_CAP_TYPE_LAST; break; + default: parm->nCap = 0; break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_CfgGet(void *cdev, GSW_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - struct mac_ops *ops; + u32 ret; +#if defined(CONFIG_MAC) && CONFIG_MAC + struct mac_ops *ops; +#endif u32 value, data2; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Aging Counter Mantissa Value */ gsw_r32(cdev, PCE_AGE_1_MANT_OFFSET, PCE_AGE_1_MANT_SHIFT, PCE_AGE_1_MANT_SIZE, &data2); + if (data2 == AGETIMER_1_DAY) parm->eMAC_TableAgeTimer = GSW_AGETIMER_1_DAY; else if (data2 == AGETIMER_1_HOUR) @@ -9058,8 +11660,8 @@ GSW_return_t GSW_CfgGet(void *cdev, GSW_cfg_t *parm) parm->eMAC_TableAgeTimer = GSW_AGETIMER_1_SEC; else parm->eMAC_TableAgeTimer = 0; - - if (gswdev->gipver != LTQ_GSWIP_3_1) { + + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_r32(cdev, MAC_FLEN_LEN_OFFSET, MAC_FLEN_LEN_SHIFT, MAC_FLEN_LEN_SIZE, &value); parm->nMaxPacketLen = value; @@ -9071,34 +11673,38 @@ GSW_return_t GSW_CfgGet(void *cdev, GSW_cfg_t *parm) PCE_GCTRL_0_VLAN_SHIFT, PCE_GCTRL_0_VLAN_SIZE, &value); parm->bVLAN_Aware = value; - } - else if (gswdev->gipver == LTQ_GSWIP_3_1) { - /* Get MTU for MAC2/3/4 */ + } else if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC + /* Get MTU for MAC2/3/4 */ ops = get_mac_ops(gswdev, 2); - if(!ops) { + + if (!ops) { pr_err("MAC 2 is not initialized\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - parm->nMaxPacketLen= ops->get_mtu(ops); + + parm->nMaxPacketLen = ops->get_mtu(ops); +#endif } - + /* MAC Address Learning Limitation Mode */ - gsw_r32(cdev, PCE_GCTRL_0_PLIMMOD_OFFSET , + gsw_r32(cdev, PCE_GCTRL_0_PLIMMOD_OFFSET, PCE_GCTRL_0_PLIMMOD_SHIFT, PCE_GCTRL_0_PLIMMOD_SIZE, &value); parm->bLearningLimitAction = value; - /*Accept or discard MAC spoofing and port MAC locking violation packets */ + + /*Accept or discard MAC spoofing and port MAC locking violation packets */ if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { - gsw_r32(cdev, PCE_GCTRL_0_PLCKMOD_OFFSET , + (gswdev->gipver == LTQ_GSWIP_2_2_ETC) || + (IS_VRSN_30_31(gswdev->gipver))) { + gsw_r32(cdev, PCE_GCTRL_0_PLCKMOD_OFFSET, PCE_GCTRL_0_PLCKMOD_SHIFT, PCE_GCTRL_0_PLCKMOD_SIZE, &parm->bMAC_SpoofingAction); } - - if (gswdev->gipver != LTQ_GSWIP_3_1) { + + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (parm->bPauseMAC_ModeSrc) { gsw_r32(cdev, MAC_PFSA_0_PFAD_OFFSET, MAC_PFSA_0_PFAD_SHIFT, MAC_PFSA_0_PFAD_SIZE, &value); @@ -9113,54 +11719,82 @@ GSW_return_t GSW_CfgGet(void *cdev, GSW_cfg_t *parm) parm->nPauseMAC_Src[1] = value & 0xFF; parm->nPauseMAC_Src[0] = (value >> 8) & 0xFF; } - } - else if (gswdev->gipver == LTQ_GSWIP_3_1) { + } else if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC /* Get MAC used in pause frame */ ops = get_mac_ops(gswdev, 2); - if(!ops) { + + if (!ops) { pr_err("MAC 2 is not initialized\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + ops->get_pfsa(ops, parm->nPauseMAC_Src, &parm->bPauseMAC_ModeSrc); +#endif } - - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_CfgSet(void *cdev, GSW_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); struct mac_ops *ops; - u32 MANT = 0, EXP = 0, value, i; + u32 max_mac; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + switch (parm->eMAC_TableAgeTimer) { case GSW_AGETIMER_1_SEC: - MANT = AGETIMER_1_SEC; EXP = 0x2; + MANT = AGETIMER_1_SEC; + EXP = 0x2; gswdev->matimer = 1; break; + case GSW_AGETIMER_10_SEC: - MANT = AGETIMER_10_SEC; EXP = 0x2; + MANT = AGETIMER_10_SEC; + EXP = 0x2; gswdev->matimer = 10; break; + case GSW_AGETIMER_300_SEC: - MANT = AGETIMER_300_SEC; EXP = 0x2; + MANT = AGETIMER_300_SEC; + EXP = 0x2; gswdev->matimer = 300; break; + case GSW_AGETIMER_1_HOUR: - MANT = AGETIMER_1_HOUR; EXP = 0x6; + MANT = AGETIMER_1_HOUR; + EXP = 0x6; gswdev->matimer = 3600; break; + case GSW_AGETIMER_1_DAY: - MANT = AGETIMER_1_DAY; EXP = 0xA; + MANT = AGETIMER_1_DAY; + EXP = 0xA; gswdev->matimer = 86400; break; + default: - MANT = AGETIMER_300_SEC; EXP = 0x2; + MANT = AGETIMER_300_SEC; + EXP = 0x2; gswdev->matimer = 300; } @@ -9170,14 +11804,17 @@ GSW_return_t GSW_CfgSet(void *cdev, GSW_cfg_t *parm) /* Aging Counter Mantissa Value */ gsw_w32(cdev, PCE_AGE_1_MANT_OFFSET, PCE_AGE_1_MANT_SHIFT, PCE_AGE_1_MANT_SIZE, MANT); + /* Maximum Ethernet packet length */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (parm->nMaxPacketLen < MAX_PACKET_LENGTH) value = parm->nMaxPacketLen; else value = MAX_PACKET_LENGTH; + gsw_w32(cdev, MAC_FLEN_LEN_OFFSET, MAC_FLEN_LEN_SHIFT, MAC_FLEN_LEN_SIZE, value); + if (parm->nMaxPacketLen > 0x5EE) { for (i = 0; i < 6; i++) { gsw_w32(cdev, (MAC_CTRL_2_MLEN_OFFSET + (i * 0xC)), @@ -9185,31 +11822,28 @@ GSW_return_t GSW_CfgSet(void *cdev, GSW_cfg_t *parm) MAC_CTRL_2_MLEN_SIZE, 1); } } - } - - else if (gswdev->gipver == LTQ_GSWIP_3_1) { - /* Set MTU for MAC2/3/4 */ + } else if (IS_VRSN_31(gswdev->gipver)) { + /* Set MTU for MAC2/3/4 */ if (parm->nMaxPacketLen < V31_MAX_PACKET_LENGTH) value = parm->nMaxPacketLen; else value = V31_MAX_PACKET_LENGTH; - for (i = 2; i < 5; i++) { +#if defined(CONFIG_MAC) && CONFIG_MAC + max_mac = gsw_get_mac_subifcnt(0); + + for (i = 2; i < max_mac + 2; i++) { ops = get_mac_ops(gswdev, i); - if(!ops) { + + if (!ops) { pr_err("MAC %d is not initialized\n", i); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + ops->set_mtu(ops, value); } -#if 0 //Decide not to change the MTU for PMAC0/1. - /* Set MTU for PMAC0 */ - gsw_w32(cdev, PMAC_CTRL_1_MLEN_OFFSET, - PMAC_CTRL_1_MLEN_SHIFT, PMAC_CTRL_1_MLEN_SIZE, value); - - /* Set MTU for PMAC1 */ - gsw_w32(cdev, PMAC_CTRL_1_1_MLEN_OFFSET, - PMAC_CTRL_1_1_MLEN_SHIFT, PMAC_CTRL_1_1_MLEN_SIZE, value); + #endif } @@ -9217,22 +11851,23 @@ GSW_return_t GSW_CfgSet(void *cdev, GSW_cfg_t *parm) gsw_w32(cdev, PCE_GCTRL_0_PLIMMOD_OFFSET, PCE_GCTRL_0_PLIMMOD_SHIFT, PCE_GCTRL_0_PLIMMOD_SIZE, parm->bLearningLimitAction); - /*Accept or discard MAC spoofing and port */ - /* MAC locking violation packets */ - if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1) || - (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { - gsw_w32(cdev, PCE_GCTRL_0_PLCKMOD_OFFSET , + + /*Accept or discard MAC spoofing and port */ + /* MAC locking violation packets */ + if ((gswdev->gipver == LTQ_GSWIP_2_2) || + (IS_VRSN_30_31(gswdev->gipver)) || + (gswdev->gipver == LTQ_GSWIP_2_2_ETC)) { + gsw_w32(cdev, PCE_GCTRL_0_PLCKMOD_OFFSET, PCE_GCTRL_0_PLCKMOD_SHIFT, PCE_GCTRL_0_PLCKMOD_SIZE, parm->bMAC_SpoofingAction); } + /* VLAN-aware Switching */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { gsw_w32(cdev, PCE_GCTRL_0_VLAN_OFFSET, PCE_GCTRL_0_VLAN_SHIFT, PCE_GCTRL_0_VLAN_SIZE, parm->bVLAN_Aware); - + if (parm->bPauseMAC_ModeSrc == 1) { gsw_w32(cdev, MAC_PFAD_CFG_SAMOD_OFFSET, MAC_PFAD_CFG_SAMOD_SHIFT, @@ -9248,52 +11883,85 @@ GSW_return_t GSW_CfgSet(void *cdev, GSW_cfg_t *parm) MAC_PFSA_2_PFAD_SHIFT, MAC_PFSA_2_PFAD_SIZE, value); } - } - else if (gswdev->gipver == LTQ_GSWIP_3_1) { - /* Set MAC to use in pause frame */ - ops = get_mac_ops(gswdev, 2); - if(!ops) { - pr_err("MAC 2 is not initialized\n"); - return GSW_statusErr; + } else if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC + max_mac = gsw_get_mac_subifcnt(0); + + for (i = 2; i < max_mac + 2; i++) { + + /* Set MAC to use in pause frame */ + ops = get_mac_ops(gswdev, 2); + + if (!ops) { + pr_err("MAC 2 is not initialized\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ops->set_pfsa(ops, parm->nPauseMAC_Src, + parm->bPauseMAC_ModeSrc); } - ops->set_pfsa(ops, parm->nPauseMAC_Src, parm->bPauseMAC_ModeSrc); + +#endif } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_HW_Init(void *cdev, GSW_HW_Init_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 j; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /* Reset the Switch via Switch IP register*/ j = 1; gsw_w32(cdev, ETHSW_SWRES_R0_OFFSET, ETHSW_SWRES_R0_SHIFT, ETHSW_SWRES_R0_SIZE, j); + do { // udelay(100); gsw_r32(cdev, ETHSW_SWRES_R0_OFFSET, ETHSW_SWRES_R0_SHIFT, ETHSW_SWRES_R0_SIZE, &j); } while (j); + #if defined(CONFIG_USE_EMULATOR) && CONFIG_USE_EMULATOR + if (gswdev->gipver == LTQ_GSWIP_3_0) { /* Set Auto-Polling of connected PHYs - For all ports */ gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x0); } else { /* Set Auto-Polling of connected PHYs - For all ports */ gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, 0x0); } + #else + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { +#ifdef __KERNEL__ gsw_r_init(); +#endif gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x1); } else { @@ -9301,10 +11969,11 @@ GSW_return_t GSW_HW_Init(void *cdev, GSW_HW_Init_t *parm) GSWT_MDCCFG_0_PEN_1_SHIFT, 6, 0x1e); } } + #endif /* CONFIG_USE_EMULATOR */ -/* platform_device_init(cdev); */ + /* platform_device_init(cdev); */ gswdev->hwinit = 1; -/* get_gsw_hw_cap (cdev); */ + /* get_gsw_hw_cap (cdev); */ /* Software Table Init */ #if defined(CONFIG_LTQ_VLAN) && CONFIG_LTQ_VLAN reset_vlan_sw_table(cdev); @@ -9316,53 +11985,70 @@ GSW_return_t GSW_HW_Init(void *cdev, GSW_HW_Init_t *parm) pce_table_init(&gswdev->phandler); /* HW Init */ gsw_pmicro_code_init(cdev); + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { - /*suresh*/ + /*suresh*/ // rt_table_init(); gsw_w32(cdev, PCE_TFCR_NUM_NUM_OFFSET, PCE_TFCR_NUM_NUM_SHIFT, PCE_TFCR_NUM_NUM_SIZE, 0x80); } + /* EEE auto negotiation overides:*/ /* clock disable (ANEG_EEE_0.CLK_STOP_CAPABLE) */ - for (j = 0; j < gswdev->pnum-1; j++) { + for (j = 0; j < gswdev->pnum - 1; j++) { gsw_w32(cdev, - ((GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_OFFSET - + (4 * j)) + GSW30_TOP_OFFSET), - GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SHIFT, - GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SIZE, 0x3); + ((GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_OFFSET + + (4 * j)) + GSW30_TOP_OFFSET), + GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SHIFT, + GSWT_ANEG_EEE_1_CLK_STOP_CAPABLE_SIZE, 0x3); } } else { /* Configure the MDIO Clock 97.6 Khz */ gsw_w32(cdev, (MDC_CFG_1_FREQ_OFFSET + GSW_TREG_OFFSET), MDC_CFG_1_FREQ_SHIFT, MDC_CFG_1_FREQ_SIZE, 0xFF); - for (j = 0; j < gswdev->pnum-1; j++) { - gsw_w32(cdev, ((ANEG_EEE_0_CLK_STOP_CAPABLE_OFFSET+j) - + GSW_TREG_OFFSET), + + for (j = 0; j < gswdev->pnum - 1; j++) { + gsw_w32(cdev, ((ANEG_EEE_0_CLK_STOP_CAPABLE_OFFSET + j) + + GSW_TREG_OFFSET), ANEG_EEE_0_CLK_STOP_CAPABLE_SHIFT, ANEG_EEE_0_CLK_STOP_CAPABLE_SIZE, 0x3); } } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_MDIO_CfgGet(void *cdev, GSW_MDIO_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mdio); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MDCCFG_1_FREQ_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_1_FREQ_SHIFT, GSWT_MDCCFG_1_FREQ_SIZE, &value); parm->nMDIO_Speed = value & 0xFF; gsw_r32(cdev, (GSWT_MDCCFG_1_MCEN_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_1_MCEN_SHIFT, GSWT_MDCCFG_1_MCEN_SIZE, &value); parm->bMDIO_Enable = value; @@ -9372,34 +12058,51 @@ GSW_return_t GSW_MDIO_CfgGet(void *cdev, GSW_MDIO_cfg_t *parm) MDC_CFG_1_FREQ_SIZE, &value); parm->nMDIO_Speed = value & 0xFF; gsw_r32(cdev, (MDC_CFG_1_MCEN_OFFSET - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MDC_CFG_1_MCEN_SHIFT, MDC_CFG_1_MCEN_SIZE, &value); parm->bMDIO_Enable = value; } + if (value == 1) parm->bMDIO_Enable = 1; else parm->bMDIO_Enable = 0; - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mdio); +#endif + return ret; } GSW_return_t GSW_MDIO_CfgSet(void *cdev, GSW_MDIO_cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - pr_err("**********%s:%s:%d*************\n",__FILE__, __func__, __LINE__); + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mdio); +#endif + + pr_err("**********%s:%s:%d*************\n", __FILE__, __func__, __LINE__); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MDCCFG_1_FREQ_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_1_FREQ_SHIFT, GSWT_MDCCFG_1_FREQ_SIZE, parm->nMDIO_Speed); + if (parm->bMDIO_Enable) value = 0x3F; else value = 0; + /* Set Auto-Polling of connected PHYs - For all ports */ gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, value); @@ -9408,10 +12111,12 @@ GSW_return_t GSW_MDIO_CfgSet(void *cdev, GSW_MDIO_cfg_t *parm) } else { gsw_w32(cdev, (MDC_CFG_1_FREQ_OFFSET + GSW_TREG_OFFSET), MDC_CFG_1_FREQ_SHIFT, MDC_CFG_1_FREQ_SIZE, parm->nMDIO_Speed); + if (parm->bMDIO_Enable) value = 0x3F; else value = 0; + /* Set Auto-Polling of connected PHYs - For all ports */ gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, value); @@ -9419,143 +12124,186 @@ GSW_return_t GSW_MDIO_CfgSet(void *cdev, GSW_MDIO_cfg_t *parm) MDC_CFG_1_MCEN_SHIFT, MDC_CFG_1_MCEN_SIZE, parm->bMDIO_Enable); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mdio); +#endif + return ret; } GSW_return_t GSW_MDIO_DataRead(void *cdev, GSW_MDIO_data_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mdio); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { CHECK_BUSY_MDIO((GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), - GSWT_MDCTRL_MBUSY_SHIFT,GSWT_MDCTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); - + GSWT_MDCTRL_MBUSY_SHIFT, GSWT_MDCTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); + value = ((0x2 << 10) | ((parm->nAddressDev & 0x1F) << 5) - | (parm->nAddressReg & 0x1F)); + | (parm->nAddressReg & 0x1F)); /* Special write command, becouse we need to write */ /* "MDIO Control Register" once at a time */ gsw_w32(cdev, (GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), 0, 16, value); CHECK_BUSY_MDIO((GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), - GSWT_MDCTRL_MBUSY_SHIFT,GSWT_MDCTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); - + GSWT_MDCTRL_MBUSY_SHIFT, GSWT_MDCTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); + gsw_r32(cdev, (GSWT_MDREAD_RDATA_OFFSET + GSW30_TOP_OFFSET), GSWT_MDREAD_RDATA_SHIFT, GSWT_MDREAD_RDATA_SIZE, &value); parm->nData = (value & 0xFFFF); } else { CHECK_BUSY_MDIO((MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), - MDIO_CTRL_MBUSY_SHIFT,MDIO_CTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); + MDIO_CTRL_MBUSY_SHIFT, MDIO_CTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); value = ((0x2 << 10) | ((parm->nAddressDev & 0x1F) << 5) - | (parm->nAddressReg & 0x1F)); + | (parm->nAddressReg & 0x1F)); /* Special write command, becouse we need to write */ /* "MDIO Control Register" once at a time */ gsw_w32(cdev, (MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), 0, 16, value); CHECK_BUSY_MDIO((MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), - MDIO_CTRL_MBUSY_SHIFT,MDIO_CTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); - + MDIO_CTRL_MBUSY_SHIFT, MDIO_CTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); + gsw_r32(cdev, (MDIO_READ_RDATA_OFFSET + GSW_TREG_OFFSET), MDIO_READ_RDATA_SHIFT, MDIO_READ_RDATA_SIZE, &value); parm->nData = (value & 0xFFFF); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mdio); +#endif + return ret; + } GSW_return_t GSW_MDIO_DataWrite(void *cdev, GSW_MDIO_data_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mdio); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { CHECK_BUSY_MDIO((GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), - GSWT_MDCTRL_MBUSY_SHIFT,GSWT_MDCTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); + GSWT_MDCTRL_MBUSY_SHIFT, GSWT_MDCTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); value = parm->nData & 0xFFFF; gsw_w32(cdev, (GSWT_MDWRITE_WDATA_OFFSET + GSW30_TOP_OFFSET), GSWT_MDWRITE_WDATA_SHIFT, GSWT_MDWRITE_WDATA_SIZE, value); value = ((0x1 << 10) | ((parm->nAddressDev & 0x1F) << 5) - | (parm->nAddressReg & 0x1F)); + | (parm->nAddressReg & 0x1F)); /* Special write command, becouse we need to write*/ /* "MDIO Control Register" once at a time */ gsw_w32(cdev, (GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), 0, 16, value); CHECK_BUSY_MDIO((GSWT_MDCTRL_MBUSY_OFFSET + GSW30_TOP_OFFSET), - GSWT_MDCTRL_MBUSY_SHIFT,GSWT_MDCTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); + GSWT_MDCTRL_MBUSY_SHIFT, GSWT_MDCTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); } else { CHECK_BUSY_MDIO((MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), - MDIO_CTRL_MBUSY_SHIFT,MDIO_CTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); + MDIO_CTRL_MBUSY_SHIFT, MDIO_CTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); value = parm->nData & 0xFFFF; gsw_w32(cdev, (MDIO_WRITE_WDATA_OFFSET + GSW_TREG_OFFSET), MDIO_WRITE_WDATA_SHIFT, MDIO_WRITE_WDATA_SIZE, value); value = ((0x1 << 10) | ((parm->nAddressDev & 0x1F) << 5) - | (parm->nAddressReg & 0x1F)); + | (parm->nAddressReg & 0x1F)); /* Special write command, becouse we need to write*/ /* "MDIO Control Register" once at a time */ gsw_w32(cdev, (MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), 0, 16, value); CHECK_BUSY_MDIO((MDIO_CTRL_MBUSY_OFFSET + GSW_TREG_OFFSET), - MDIO_CTRL_MBUSY_SHIFT,MDIO_CTRL_MBUSY_SIZE,RETURN_FROM_FUNCTION); + MDIO_CTRL_MBUSY_SHIFT, MDIO_CTRL_MBUSY_SIZE, RETURN_FROM_FUNCTION); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mdio); +#endif + return ret; + } static inline void ltq_mdelay(int delay) { int i; + for (i = delay; i > 0; i--) - ; - //udelay(1000); + ; + + //udelay(1000); } static int force_to_configure_phy_settings(void *cdev, u8 pidx, u8 link_status) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 mdio_stat_reg, phy_addr_reg = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (pidx >= (gswdev->pnum-1)) + + if (pidx >= (gswdev->pnum - 1)) return GSW_statusErr; + // if ((pidx == GSW_3X_SOC_CPU_PORT) || ((pidx == GSW_2X_SOC_CPU_PORT))) // return 1; if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET - + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), + + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, 16, &phy_addr_reg); gsw_r32(cdev, ((GSWT_MDIO_STAT_1_TXPAUEN_OFFSET - + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), + + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_MDIO_STAT_1_TXPAUEN_SHIFT, 16, &mdio_stat_reg); } else { gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, 16, &phy_addr_reg); gsw_r32(cdev, (MDIO_STAT_0_TXPAUEN_OFFSET - + GSW_TREG_OFFSET + pidx), + + GSW_TREG_OFFSET + pidx), MDIO_STAT_0_TXPAUEN_SHIFT, 16, &mdio_stat_reg); } + if (link_status) { /* PHY active Status */ if ((mdio_stat_reg >> 6) & 0x1) { u32 temp = 0; + /* Link Status */ if ((mdio_stat_reg >> 5) & 0x1) { phy_addr_reg &= ~(0xFFE0); phy_addr_reg |= (1 << 13); /* Link up */ temp = ((mdio_stat_reg >> 3) & 0x3); /*Speed */ phy_addr_reg |= (temp << 11); /*Speed */ - if ((mdio_stat_reg >> 2) & 0x1) /*duplex */ { + + if ((mdio_stat_reg >> 2) & 0x1) { /*duplex */ phy_addr_reg |= (0x1 << 9); /*duplex */ } else { phy_addr_reg |= (0x3 << 9); } + /*Receive Pause Enable Status */ if ((mdio_stat_reg >> 1) & 0x1) { /*Receive Pause Enable Status */ @@ -9563,6 +12311,7 @@ static int force_to_configure_phy_settings(void *cdev, u8 pidx, u8 link_status) } else { phy_addr_reg |= (0x3 << 5); } + /*Transmit Pause Enable Status */ if ((mdio_stat_reg >> 0) & 0x1) { /*Transmit Pause Enable Status */ @@ -9570,21 +12319,23 @@ static int force_to_configure_phy_settings(void *cdev, u8 pidx, u8 link_status) } else { phy_addr_reg |= (0x3 << 7); } + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { - //Reddy - } else { - } + //Reddy + } else { + } + gsw_w32(cdev, - ((GSWT_PHY_ADDR_1_ADDR_OFFSET - + ((pidx - 1) * 4)) - + GSW30_TOP_OFFSET), + ((GSWT_PHY_ADDR_1_ADDR_OFFSET + + ((pidx - 1) * 4)) + + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, 16, phy_addr_reg); } else { gsw_w32(cdev, - ((PHY_ADDR_0_ADDR_OFFSET - pidx) - + GSW_TREG_OFFSET), + ((PHY_ADDR_0_ADDR_OFFSET - pidx) + + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, 16, phy_addr_reg); } @@ -9593,21 +12344,24 @@ static int force_to_configure_phy_settings(void *cdev, u8 pidx, u8 link_status) } else { phy_addr_reg &= ~(0xFFE0); phy_addr_reg |= (0x3 << 11); + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { - //Reddy - } else { - } + //Reddy + } else { + } + gsw_w32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET - + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), + + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, 16, phy_addr_reg); } else { gsw_w32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, 16, phy_addr_reg); } } + return 1; } @@ -9616,10 +12370,17 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); GSW_MDIO_data_t mmd_data; u32 found = 0, rphy, rmdc, phy_addr, mdc_reg, dev, pidx; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mmd); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if ((parm->nAddressDev == 1)) { @@ -9630,12 +12391,14 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) found = 1; pidx = 1; } else { - return GSW_statusErr; - } + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { for (pidx = 1; pidx < gswdev->pnum; pidx++) { gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &phy_addr); + if (phy_addr == parm->nAddressDev) { found = 1; gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), @@ -9645,19 +12408,22 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) } } } else { - for (pidx = 0; pidx < (gswdev->pnum-1); pidx++) { + for (pidx = 0; pidx < (gswdev->pnum - 1); pidx++) { gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, PHY_ADDR_0_ADDR_SIZE, &phy_addr); + if (phy_addr == parm->nAddressDev) { found = 1; gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), - PHY_ADDR_0_ADDR_SHIFT, 16, &rphy); + PHY_ADDR_0_ADDR_SHIFT, 16, &rphy); break; } } } + if (found) { force_to_configure_phy_settings(cdev, pidx, 1); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, &mdc_reg); @@ -9665,9 +12431,11 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) gsw_r32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, &mdc_reg); } + rmdc = mdc_reg; mdc_reg &= ~(1 << pidx); dev = ((parm->nAddressReg >> 16) & 0x1F); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, mdc_reg); @@ -9675,6 +12443,7 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, mdc_reg); } + ltq_mdelay(20); mmd_data.nAddressDev = parm->nAddressDev; mmd_data.nAddressReg = 0xd; @@ -9708,13 +12477,23 @@ GSW_return_t GSW_MmdDataRead(void *cdev, GSW_MMD_data_t *parm) gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, rmdc); } + ltq_mdelay(100); force_to_configure_phy_settings(cdev, pidx, 0); } else { pr_err("(Invalid PHY Address) %s:%s:%d\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mmd); +#endif + return ret; + } GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) @@ -9722,10 +12501,17 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); GSW_MDIO_data_t mmd_data; u32 found = 0, rphy, rmdc, phy_addr, mdc_reg, dev, pidx; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mmd); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if ((parm->nAddressDev == 1)) { @@ -9736,12 +12522,14 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) found = 1; pidx = 1; } else { - return GSW_statusErr; - } + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { for (pidx = 1; pidx < gswdev->pnum; pidx++) { gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &phy_addr); + if (phy_addr == parm->nAddressDev) { found = 1; gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), @@ -9751,13 +12539,14 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) } } } else { - for (pidx = 0; pidx < (gswdev->pnum-1); pidx++) { + for (pidx = 0; pidx < (gswdev->pnum - 1); pidx++) { gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, PHY_ADDR_0_ADDR_SIZE, &phy_addr); + if (phy_addr == parm->nAddressDev) { found = 1; gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), - PHY_ADDR_0_ADDR_SHIFT, 16, &rphy); + PHY_ADDR_0_ADDR_SHIFT, 16, &rphy); break; } } @@ -9765,27 +12554,31 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) if (found) { force_to_configure_phy_settings(cdev, pidx, 1); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, &mdc_reg); } else { gsw_r32(cdev, (MDC_CFG_0_PEN_0_OFFSET - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, &mdc_reg); } + rmdc = mdc_reg; mdc_reg &= ~(1 << pidx); dev = ((parm->nAddressReg >> 16) & 0x1F); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, mdc_reg); } else { gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, mdc_reg); } + ltq_mdelay(20); mmd_data.nAddressDev = parm->nAddressDev; mmd_data.nAddressReg = 0xd; @@ -9806,6 +12599,7 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) mmd_data.nAddressReg = 0xe; mmd_data.nData = parm->nData; GSW_MDIO_DataWrite(cdev, &mmd_data); + // mdc_reg |= (1 << pidx); if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), @@ -9818,31 +12612,52 @@ GSW_return_t GSW_MmdDataWrite(void *cdev, GSW_MMD_data_t *parm) gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, rmdc); } + ltq_mdelay(100); force_to_configure_phy_settings(cdev, pidx, 0); } else { pr_err("(Invalid PHY Address) %s:%s:%d\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mmd); +#endif + return ret; + } static GSW_return_t GSW_MMD_MDIO_DataWrite(void *cdev, - GSW_MDIO_data_t *parm, u8 pidx, u8 dev) + GSW_MDIO_data_t *parm, u8 pidx, u8 dev) { GSW_MDIO_data_t mmd_data; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 mdc_reg; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (pidx >= (gswdev->pnum-1)) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_mmd); +#endif + + if (pidx >= (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + force_to_configure_phy_settings(cdev, pidx, 1); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, &mdc_reg); } else { gsw_r32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), @@ -9850,14 +12665,16 @@ static GSW_return_t GSW_MMD_MDIO_DataWrite(void *cdev, } mdc_reg &= ~(1 << pidx); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, mdc_reg); } else { gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, mdc_reg); } + ltq_mdelay(20); mmd_data.nAddressDev = parm->nAddressDev; @@ -9881,69 +12698,119 @@ static GSW_return_t GSW_MMD_MDIO_DataWrite(void *cdev, GSW_MDIO_DataWrite(cdev, &mmd_data); mdc_reg |= (1 << pidx); + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MDCCFG_0_PEN_1_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MDCCFG_0_PEN_1_SHIFT, 6, mdc_reg); } else { gsw_w32(cdev, (MDC_CFG_0_PEN_0_OFFSET + GSW_TREG_OFFSET), MDC_CFG_0_PEN_0_SHIFT, 6, mdc_reg); } + ltq_mdelay(100); force_to_configure_phy_settings(cdev, pidx, 0); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_mmd); +#endif + return ret; + } GSW_return_t GSW_MonitorPortCfgGet(void *cdev, GSW_monitorPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 pmapReg1; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + //Validate given Port-Id. - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + //Get monitoring port-map. gsw_r32_raw(cdev, PCE_PMAP_1_REG_OFFSET, &pmapReg1); parm->nPortId = pmapReg1; - if (gswdev->gipver == LTQ_GSWIP_3_1) { - GET_VAL_FROM_REG (parm->nPortId, PCE_PMAP_1_PID_SHIFT, PCE_PMAP_1_PID_SIZE, pmapReg1); - GET_VAL_FROM_REG (parm->nSubIfId, PCE_PMAP_1_SUBID_SHIFT, PCE_PMAP_1_SUBID_SIZE, pmapReg1); + + if (IS_VRSN_31(gswdev->gipver)) { + parm->bMonitorPort = 1; + GET_VAL_FROM_REG(parm->nPortId, PCE_PMAP_1_PID_SHIFT, PCE_PMAP_1_PID_SIZE, pmapReg1); + GET_VAL_FROM_REG(parm->nSubIfId, PCE_PMAP_1_SUBID_SHIFT, PCE_PMAP_1_SUBID_SIZE, pmapReg1); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_MonitorPortCfgSet(void *cdev, GSW_monitorPortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; - u32 pmapReg1= 0; + u32 pmapReg1 = 0; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + //Validate given Port-Id. - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + //En/disabel monitoring on given port-id. It is logical port-id. - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { //First read the monitoring register map. gsw_r32_raw(cdev, PCE_PMAP_1_REG_OFFSET, &pmapReg1); + if (parm->bMonitorPort == 1) pmapReg1 |= (1 << pidx); //Enable monitoring. else pmapReg1 = (pmapReg1 & ~(1 << pidx)); ////Disable monitoring. + //Update the monitoring register map. gsw_w32_raw(cdev, PCE_PMAP_1_REG_OFFSET, pmapReg1); } else { //To test, enable mirroring on ing/egr CTP port and check?. - FILL_CTRL_REG (pmapReg1, PCE_PMAP_1_PID_SHIFT, parm->nPortId); - FILL_CTRL_REG (pmapReg1, PCE_PMAP_1_SUBID_SHIFT, parm->nSubIfId); + FILL_CTRL_REG(pmapReg1, PCE_PMAP_1_PID_SHIFT, parm->nPortId); + FILL_CTRL_REG(pmapReg1, PCE_PMAP_1_SUBID_SHIFT, parm->nSubIfId); gsw_w32_raw(cdev, PCE_PMAP_1_REG_OFFSET, pmapReg1); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_PortLinkCfgGet(void *cdev, GSW_portLinkCfg_t *parm) @@ -9951,41 +12818,56 @@ GSW_return_t GSW_PortLinkCfgGet(void *cdev, GSW_portLinkCfg_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; u8 pidx = parm->nPortId; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_1) { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if (pidx == 15) pidx = 0; - else - return GSW_statusErr; + else { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { - if (!parm->nPortId || (parm->nPortId > (gswdev->pnum - 1))) - return GSW_statusErr; + if (!parm->nPortId || (parm->nPortId > (gswdev->pnum - 1))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + pidx = pidx - 1; } } else { - if (parm->nPortId > (gswdev->pnum-1)) - return GSW_statusErr; + if (parm->nPortId > (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - if (gswdev->gipver == LTQ_GSWIP_3_1) { - + if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC struct mac_ops *ops = get_mac_ops(gswdev, parm->nPortId); int val = 0; - if(!ops) - { - pr_err("MAC %d is not initialized\n",parm->nPortId); - return GSW_statusErr; + + if (!ops) { + pr_err("MAC %d is not initialized\n", parm->nPortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /* MAC API's to Get Duplex */ val = ops->get_duplex(ops); + if (val == -1) parm->bDuplexForce = 0; else { @@ -9998,112 +12880,140 @@ GSW_return_t GSW_PortLinkCfgGet(void *cdev, GSW_portLinkCfg_t *parm) /* MAC API's to Get Speed */ parm->eSpeed = ops->get_speed(ops); - if(parm->eSpeed != 0) + + if (parm->eSpeed != 0) parm->bSpeedForce = 1; - + parm->bLPI = ops->get_lpi(ops); val = ops->get_link_sts(ops); + if (val == -1) parm->bLinkForce = 0; else { parm->bLinkForce = 1; parm->eLink = val; } - } - else { + +#endif + } else { gsw_r32(cdev, (MAC_PSTAT_FDUP_OFFSET + (0xC * pidx)), - MAC_PSTAT_FDUP_SHIFT, MAC_PSTAT_FDUP_SIZE , &value); + MAC_PSTAT_FDUP_SHIFT, MAC_PSTAT_FDUP_SIZE, &value); + if (value) parm->eDuplex = GSW_DUPLEX_FULL; else parm->eDuplex = GSW_DUPLEX_HALF; + gsw_r32(cdev, (MAC_PSTAT_GBIT_OFFSET + (0xC * pidx)), - MAC_PSTAT_GBIT_SHIFT, MAC_PSTAT_GBIT_SIZE , &value); + MAC_PSTAT_GBIT_SHIFT, MAC_PSTAT_GBIT_SIZE, &value); + if (value) { parm->eSpeed = GSW_PORT_SPEED_1000; } else { gsw_r32(cdev, (MAC_PSTAT_MBIT_OFFSET + (0xC * pidx)), - MAC_PSTAT_MBIT_SHIFT, MAC_PSTAT_MBIT_SIZE , &value); + MAC_PSTAT_MBIT_SHIFT, MAC_PSTAT_MBIT_SIZE, &value); + if (value) parm->eSpeed = GSW_PORT_SPEED_100; else parm->eSpeed = GSW_PORT_SPEED_10; } + /* Low-power Idle Mode configuration*/ gsw_r32(cdev, (MAC_CTRL_4_LPIEN_OFFSET + (0xC * pidx)), MAC_CTRL_4_LPIEN_SHIFT, MAC_CTRL_4_LPIEN_SIZE, &value); parm->bLPI = value; gsw_r32(cdev, (MAC_PSTAT_LSTAT_OFFSET + (0xC * pidx)), - MAC_PSTAT_LSTAT_SHIFT, MAC_PSTAT_LSTAT_SIZE , &value); + MAC_PSTAT_LSTAT_SHIFT, MAC_PSTAT_LSTAT_SIZE, &value); + if (value) parm->eLink = GSW_PORT_LINK_UP; else parm->eLink = GSW_PORT_LINK_DOWN; + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, ((GSWT_PHY_ADDR_1_LNKST_OFFSET + ((pidx) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_LNKST_SHIFT, GSWT_PHY_ADDR_1_LNKST_SIZE, &value); } else { gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), - PHY_ADDR_5_LNKST_SHIFT, PHY_ADDR_5_LNKST_SIZE, &value); + PHY_ADDR_5_LNKST_SHIFT, PHY_ADDR_5_LNKST_SIZE, &value); } + if ((value == 1) || (value == 2)) { parm->bLinkForce = 1; } if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MII_CFG_1_MIIMODE_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MII_CFG_1_MIIMODE_SHIFT, GSWT_MII_CFG_1_MIIMODE_SIZE, &value); } else { gsw_r32(cdev, (MII_CFG_0_MIIMODE_OFFSET + (0x2 * pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MII_CFG_0_MIIMODE_SHIFT, MII_CFG_0_MIIMODE_SIZE, &value); } + switch (value) { case 0: parm->eMII_Mode = GSW_PORT_HW_MII; parm->eMII_Type = GSW_PORT_PHY; break; + case 1: parm->eMII_Mode = GSW_PORT_HW_MII; parm->eMII_Type = GSW_PORT_MAC; break; + case 2: parm->eMII_Mode = GSW_PORT_HW_RMII; parm->eMII_Type = GSW_PORT_PHY; break; + case 3: parm->eMII_Mode = GSW_PORT_HW_RMII; parm->eMII_Type = GSW_PORT_MAC; break; + case 4: parm->eMII_Mode = GSW_PORT_HW_RGMII; parm->eMII_Type = GSW_PORT_MAC; break; } + parm->eClkMode = GSW_PORT_CLK_NA; + if (parm->eMII_Mode == GSW_PORT_HW_RMII) { if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MII_CFG_1_RMII_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MII_CFG_1_RMII_SHIFT, GSWT_MII_CFG_1_RMII_SIZE, &value); } else { gsw_r32(cdev, (MII_CFG_0_RMII_OFFSET + (0x2 * pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MII_CFG_0_RMII_SHIFT, MII_CFG_0_RMII_SIZE, &value); } + if (value == 1) parm->eClkMode = GSW_PORT_CLK_MASTER; else parm->eClkMode = GSW_PORT_CLK_SLAVE; } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) @@ -10112,35 +13022,48 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) u32 data, phy_addr, phyreg, phy_ctrl = 0, duplex, PEN = 0, PACT = 0; u8 pidx = parm->nPortId; GSW_MDIO_data_t mddata; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver != LTQ_GSWIP_3_1) { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if (pidx == 15) pidx = 1; - else - return GSW_statusErr; + else { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { - if (!parm->nPortId || (parm->nPortId > (gswdev->pnum - 1))) - return GSW_statusErr; + if (!parm->nPortId || (parm->nPortId > (gswdev->pnum - 1))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } else { - if (parm->nPortId > (gswdev->pnum-1)) - return GSW_statusErr; + if (parm->nPortId > (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - if(gswdev->gipver == LTQ_GSWIP_3_1) { - + if (IS_VRSN_31(gswdev->gipver)) { +#if defined(CONFIG_MAC) && CONFIG_MAC struct mac_ops *ops = get_mac_ops(gswdev, parm->nPortId); - if(!ops) - { - pr_err("MAC %d is not initialized\n",parm->nPortId); - return GSW_statusErr; + + if (!ops) { + pr_err("MAC %d is not initialized\n", parm->nPortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /* MAC API's to Set Duplex */ @@ -10153,10 +13076,10 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) ops->set_mii_if(ops, parm->eMII_Mode); /* MAC API's to Set Speed */ - if (parm->bSpeedForce == 1) + if (parm->bSpeedForce == 1) ops->set_speed(ops, parm->eSpeed); - else - ops->set_speed(ops, 0);// Set to Auto + else + ops->set_speed(ops, 0);// Set to Auto /* LPI Wait Time for 1G -- 50us */ /* LPI Wait Time for 100M -- 21us */ @@ -10166,10 +13089,10 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) if (parm->bLinkForce == 1) ops->set_link_sts(ops, parm->eLink); else - ops->set_link_sts(ops, GSW_PORT_LINK_UP); // Default to UP - } - else - { + ops->set_link_sts(ops, GSW_PORT_LINK_UP); // Default to UP + +#endif + } else { if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (GSWT_MDCCFG_0_PEN_0_OFFSET + GSW30_TOP_OFFSET), (GSWT_MDCCFG_0_PEN_0_SHIFT + pidx), GSWT_MDCCFG_0_PEN_0_SIZE, &PEN); @@ -10183,7 +13106,7 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) gsw_r32(cdev, (MDIO_STAT_0_PACT_OFFSET + GSW_TREG_OFFSET + pidx), MDIO_STAT_0_PACT_SHIFT, MDIO_STAT_0_PACT_SIZE, &PACT); gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), - 0, 16, &phyreg); + 0, 16, &phyreg); } /*pr_err("%s:%s:%d PEN:%d, PACT:%d, phyreg:0x%08x\n", @@ -10191,64 +13114,82 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) if ((PEN == 1) && (PACT == 1)) { if (parm->bDuplexForce == 1) { if (parm->eDuplex == GSW_DUPLEX_FULL) { - data = DUPLEX_EN; duplex = DUPLEX_EN; + data = DUPLEX_EN; + duplex = DUPLEX_EN; } else { - data = DUPLEX_DIS; duplex = DUPLEX_DIS; + data = DUPLEX_DIS; + duplex = DUPLEX_DIS; } } else { data = DUPLEX_AUTO; duplex = DUPLEX_AUTO; } + data = 3; /*default value*/ + if (parm->bSpeedForce == 1) { switch (parm->eSpeed) { case GSW_PORT_SPEED_10: data = 0; + if (duplex == DUPLEX_DIS) phy_ctrl = PHY_AN_ADV_10HDX; else phy_ctrl = PHY_AN_ADV_10FDX; + break; + case GSW_PORT_SPEED_100: data = 1; + if (duplex == DUPLEX_DIS) phy_ctrl = PHY_AN_ADV_100HDX; else phy_ctrl = PHY_AN_ADV_100FDX; + break; + case GSW_PORT_SPEED_200: - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + case GSW_PORT_SPEED_1000: data = 2; + if (duplex == DUPLEX_DIS) phy_ctrl = PHY_AN_ADV_1000HDX; else phy_ctrl = PHY_AN_ADV_1000FDX; + break; + default: break; } } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET - + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), + + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &phy_addr); } else { gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, PHY_ADDR_0_ADDR_SIZE, &phy_addr); } + mddata.nAddressDev = phy_addr; GSW_MDIO_DataRead(cdev, &mddata); + if ((data == 0) || (data == 1)) { mddata.nAddressReg = 4; GSW_MDIO_DataRead(cdev, &mddata); mddata.nData &= ~(PHY_AN_ADV_10HDX - | PHY_AN_ADV_10FDX - | PHY_AN_ADV_100HDX - | PHY_AN_ADV_100FDX); + | PHY_AN_ADV_10FDX + | PHY_AN_ADV_100HDX + | PHY_AN_ADV_100FDX); mddata.nData |= phy_ctrl; GSW_MDIO_DataWrite(cdev, &mddata); mddata.nAddressReg = 9; @@ -10256,6 +13197,7 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) mddata.nData &= ~(PHY_AN_ADV_1000HDX | PHY_AN_ADV_1000FDX); GSW_MDIO_DataWrite(cdev, &mddata); } + if (data == 2) { mddata.nAddressReg = 9; GSW_MDIO_DataRead(cdev, &mddata); @@ -10265,43 +13207,48 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) mddata.nAddressReg = 4; GSW_MDIO_DataRead(cdev, &mddata); mddata.nData &= ~(PHY_AN_ADV_10HDX - | PHY_AN_ADV_10FDX - | PHY_AN_ADV_100HDX - | PHY_AN_ADV_100FDX); + | PHY_AN_ADV_10FDX + | PHY_AN_ADV_100HDX + | PHY_AN_ADV_100FDX); GSW_MDIO_DataWrite(cdev, &mddata); } + if (data == 3) { mddata.nAddressReg = 4; GSW_MDIO_DataRead(cdev, &mddata); + if (duplex == DUPLEX_DIS) { mddata.nData &= ~(PHY_AN_ADV_10HDX - | PHY_AN_ADV_10FDX - | PHY_AN_ADV_100HDX - | PHY_AN_ADV_100FDX); + | PHY_AN_ADV_10FDX + | PHY_AN_ADV_100HDX + | PHY_AN_ADV_100FDX); mddata.nData |= (PHY_AN_ADV_10HDX - | PHY_AN_ADV_100HDX); + | PHY_AN_ADV_100HDX); } else { mddata.nData |= (PHY_AN_ADV_10HDX - | PHY_AN_ADV_10FDX - | PHY_AN_ADV_100HDX - | PHY_AN_ADV_100FDX); + | PHY_AN_ADV_10FDX + | PHY_AN_ADV_100HDX + | PHY_AN_ADV_100FDX); } + GSW_MDIO_DataWrite(cdev, &mddata); mddata.nAddressReg = 9; GSW_MDIO_DataRead(cdev, &mddata); + if (duplex == DUPLEX_DIS) { mddata.nData &= ~(PHY_AN_ADV_1000HDX - | PHY_AN_ADV_1000FDX); + | PHY_AN_ADV_1000FDX); mddata.nData |= (PHY_AN_ADV_1000HDX); } else { mddata.nData |= (PHY_AN_ADV_1000HDX - | PHY_AN_ADV_1000FDX); + | PHY_AN_ADV_1000FDX); } + GSW_MDIO_DataWrite(cdev, &mddata); } if (gswdev->gipver == LTQ_GSWIP_3_0) { - gsw_w32(cdev, (MAC_CTRL_4_LPIEN_OFFSET + (0xC * (pidx - 1))), + gsw_w32(cdev, (MAC_CTRL_4_LPIEN_OFFSET + (0xC * (pidx - 1))), MAC_CTRL_4_LPIEN_SHIFT, MAC_CTRL_4_LPIEN_SIZE, parm->bLPI); /* LPI Wait Time for 1G -- 50us */ @@ -10325,12 +13272,14 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) MAC_CTRL_4_WAIT_SHIFT, MAC_CTRL_4_WAIT_SIZE, 0x15); } - /* LPI request controlled by data available for port */ + + /* LPI request controlled by data available for port */ gsw_w32(cdev, (FDMA_CTRL_LPI_MODE_OFFSET), FDMA_CTRL_LPI_MODE_SHIFT, FDMA_CTRL_LPI_MODE_SIZE, 0x4); mddata.nAddressDev = phy_addr; mddata.nAddressReg = 0x3C; + if (parm->bLPI == 1) { mddata.nData = 0x6; GSW_MMD_MDIO_DataWrite(cdev, &mddata, pidx, 0x07); @@ -10338,11 +13287,13 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) mddata.nData = 0x0; GSW_MMD_MDIO_DataWrite(cdev, &mddata, pidx, 0x07); } + mddata.nAddressDev = phy_addr; mddata.nAddressReg = 0; GSW_MDIO_DataRead(cdev, &mddata); mddata.nData = 0x1200; data = 0; + if (parm->bLinkForce == 1) { if (parm->eLink == GSW_PORT_LINK_UP) { data = 1; @@ -10351,46 +13302,58 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) mddata.nData = 0x800; } } + GSW_MDIO_DataWrite(cdev, &mddata); } else { if (parm->bDuplexForce == 1) { phyreg &= ~(3 << 9); + if (parm->eDuplex == GSW_DUPLEX_FULL) { phyreg |= (1 << 9); } else { phyreg |= (3 << 9); } } + if (parm->bLinkForce == 1) { phyreg &= ~(3 << 13); + if (parm->eLink == GSW_PORT_LINK_UP) { phyreg |= (1 << 13); } else { phyreg |= (2 << 13); } } + if (parm->bSpeedForce == 1) { phyreg &= ~(3 << 11); + switch (parm->eSpeed) { case GSW_PORT_SPEED_10: break; + case GSW_PORT_SPEED_100: phyreg |= (1 << 11); break; + case GSW_PORT_SPEED_200: - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + case GSW_PORT_SPEED_1000: phyreg |= (2 << 11); break; + default: break; } } - /* pr_err("%s:%s:%d PEN:%d, PACT:%d, phyreg:0x%08x\n", - __FILE__, __func__, __LINE__,PEN, PACT,phyreg);*/ + + /* pr_err("%s:%s:%d PEN:%d, PACT:%d, phyreg:0x%08x\n", + __FILE__, __func__, __LINE__,PEN, PACT,phyreg);*/ if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET + ((parm->nPortId - 1) * 4)) + GSW30_TOP_OFFSET), - 0, 16, phyreg); + 0, 16, phyreg); } else { gsw_w32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) + GSW_TREG_OFFSET), 0, 16, phyreg); @@ -10398,57 +13361,78 @@ GSW_return_t GSW_PortLinkCfgSet(void *cdev, GSW_portLinkCfg_t *parm) } data = 4; /*default mode */ + switch (parm->eMII_Mode) { case GSW_PORT_HW_MII: data = 1; + if (parm->eMII_Type == GSW_PORT_PHY) data = 0; + break; + case GSW_PORT_HW_RMII: data = 3; + if (parm->eMII_Type == GSW_PORT_PHY) data = 2; + break; + case GSW_PORT_HW_RGMII: data = 4; break; + case GSW_PORT_HW_GMII: - /* data = 1; */ + /* data = 1; */ break; + default: break; } + if (!(parm->eMII_Mode == GSW_PORT_HW_GMII)) { if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MII_CFG_1_MIIMODE_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MII_CFG_1_MIIMODE_SHIFT, GSWT_MII_CFG_1_MIIMODE_SIZE, data); } else { gsw_w32(cdev, (MII_CFG_0_MIIMODE_OFFSET + (0x2 * pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MII_CFG_0_MIIMODE_SHIFT, MII_CFG_0_MIIMODE_SIZE, data); } } + data = 0; + if (parm->eMII_Mode == GSW_PORT_HW_RMII) { if (parm->eClkMode == GSW_PORT_CLK_MASTER) data = 1; + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_MII_CFG_1_RMII_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_MII_CFG_1_RMII_SHIFT, GSWT_MII_CFG_1_RMII_SIZE, data); } else { gsw_w32(cdev, (MII_CFG_0_RMII_OFFSET + (0x2 * pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), MII_CFG_0_RMII_SHIFT, MII_CFG_0_RMII_SIZE, data); - } + } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_PortPHY_AddrGet(void *cdev, GSW_portPHY_Addr_t *parm) @@ -10456,38 +13440,66 @@ GSW_return_t GSW_PortPHY_AddrGet(void *cdev, GSW_portPHY_Addr_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId, num_ports; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (!parm->nPortId) - return GSW_statusErr; + if (!parm->nPortId) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { num_ports = gswdev->tpnum; + if (parm->nPortId == 15) pidx = 1; - else - return GSW_statusErr; + else { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + } else + num_ports = (gswdev->pnum - 1); + + if (parm->nPortId > (num_ports)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - else - num_ports = (gswdev->pnum -1); - if (parm->nPortId > (num_ports)) - return GSW_statusErr; + gsw_r32(cdev, ((GSWT_PHY_ADDR_1_ADDR_OFFSET - + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), + + ((pidx - 1) * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_ADDR_SHIFT, GSWT_PHY_ADDR_1_ADDR_SIZE, &value); } else { - if (parm->nPortId >= (gswdev->pnum - 1)) - return GSW_statusErr; + if (parm->nPortId >= (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_r32(cdev, ((PHY_ADDR_0_ADDR_OFFSET - pidx) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_ADDR_SHIFT, PHY_ADDR_0_ADDR_SIZE, &value); } + parm->nAddressDev = value; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_PortPHY_Query(void *cdev, GSW_portPHY_Query_t *parm) @@ -10495,38 +13507,70 @@ GSW_return_t GSW_PortPHY_Query(void *cdev, GSW_portPHY_Query_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) - return GSW_statusErr; + if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { - if (parm->nPortId >= (gswdev->pnum - 1)) - return GSW_statusErr; + if (parm->nPortId >= (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } + gsw_r32(cdev, (MAC_PSTAT_PACT_OFFSET + (0xC * pidx)), - MAC_PSTAT_PACT_SHIFT, MAC_PSTAT_PACT_SIZE , &value); + MAC_PSTAT_PACT_SHIFT, MAC_PSTAT_PACT_SIZE, &value); parm->bPHY_Present = value; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_PortRGMII_ClkCfgGet(void *cdev, GSW_portRGMII_ClkCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) - return GSW_statusErr; + if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { - if (parm->nPortId >= (gswdev->pnum-1)) - return GSW_statusErr; + if (parm->nPortId >= (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, GSWT_PCDU_1_RXDLY_OFFSET + GSW30_TOP_OFFSET, @@ -10550,43 +13594,72 @@ GSW_return_t GSW_PortRGMII_ClkCfgGet(void *cdev, GSW_portRGMII_ClkCfg_t *parm) PCDU_0_TXDLY_SIZE, &value); parm->nDelayTx = value; } - return GSW_statusOk; + + ret = GSW_statusOk; + + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_PortRGMII_ClkCfgSet(void *cdev, GSW_portRGMII_ClkCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) - return GSW_statusErr; + if (!parm->nPortId || (parm->nPortId > (gswdev->pnum))) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { - if (parm->nPortId >= (gswdev->pnum-1)) - return GSW_statusErr; + if (parm->nPortId >= (gswdev->pnum - 1)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (GSWT_PCDU_1_RXDLY_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_PCDU_1_RXDLY_SHIFT, GSWT_PCDU_1_RXDLY_SIZE, parm->nDelayRx); gsw_w32(cdev, (GSWT_PCDU_1_TXDLY_OFFSET - + GSW30_TOP_OFFSET), + + GSW30_TOP_OFFSET), GSWT_PCDU_1_TXDLY_SHIFT, GSWT_PCDU_1_TXDLY_SIZE, parm->nDelayTx); } else { gsw_w32(cdev, (PCDU_0_RXDLY_OFFSET + (0x2 * parm->nPortId) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PCDU_0_RXDLY_SHIFT, PCDU_0_RXDLY_SIZE, parm->nDelayRx); gsw_w32(cdev, (PCDU_0_TXDLY_OFFSET + (0x2 * parm->nPortId) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PCDU_0_TXDLY_SHIFT, PCDU_0_TXDLY_SIZE, parm->nDelayTx); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_PortRedirectGet(void *cdev, GSW_portRedirectCfg_t *parm) @@ -10594,46 +13667,77 @@ GSW_return_t GSW_PortRedirectGet(void *cdev, GSW_portRedirectCfg_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_r32(cdev, (PCE_PCTRL_3_EDIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_EDIR_SHIFT, PCE_PCTRL_3_EDIR_SIZE, &value); parm->bRedirectEgress = value; + if (prdflag > 0) parm->bRedirectIngress = 1; else parm->bRedirectIngress = 0; - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_PortRedirectSet(void *cdev, GSW_portRedirectCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - GSW_PCE_rule_t pcrule; + static GSW_PCE_rule_t pcrule; u8 pidx = parm->nPortId; + u32 ret; u32 rdport = 0, value = 0, i; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + value |= (1 << gswdev->mpnum); rdport = value; - gsw_w32(cdev, PCE_PMAP_1_MPMAP_OFFSET, PCE_PMAP_1_MPMAP_SHIFT, + gsw_w32(cdev, PCE_PMAP_1_MPMAP_OFFSET, PCE_PMAP_1_MPMAP_SHIFT, PCE_PMAP_1_MPMAP_SIZE, value); value = parm->bRedirectEgress; gsw_w32(cdev, (PCE_PCTRL_3_EDIR_OFFSET + (0xA * pidx)), PCE_PCTRL_3_EDIR_SHIFT, PCE_PCTRL_3_EDIR_SIZE, value); + if (parm->bRedirectIngress == 1) prdflag |= (1 << parm->nPortId); else prdflag &= ~(1 << parm->nPortId); + for (i = 0; i < gswdev->pnum; i++) { if (((prdflag >> i) & 0x1) == 1) { memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); @@ -10641,48 +13745,73 @@ GSW_return_t GSW_PortRedirectSet(void *cdev, GSW_portRedirectCfg_t *parm) pcrule.pattern.bEnable = 1; pcrule.pattern.bPortIdEnable = 1; pcrule.pattern.nPortId = i; + if (parm->bRedirectIngress == 1) pcrule.action.ePortMapAction = - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; - pcrule.action.nForwardPortMap[0]= rdport; + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; + + pcrule.action.nForwardPortMap[0] = rdport; + /* We prepare everything and write into PCE Table */ if (0 != pce_rule_write(cdev, - &gswdev->phandler, &pcrule)) - return GSW_statusErr; + &gswdev->phandler, &pcrule)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } else { if (0 != pce_pattern_delete(cdev, - &gswdev->phandler, PRD_PRULE_INDEX + i)) - return GSW_statusErr; + &gswdev->phandler, PRD_PRULE_INDEX + i)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 index, num_ports, pidx = parm->nRmonId; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if ((gswdev->sdev == LTQ_FLOW_DEV_INT_R && - gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + if ((gswdev->sdev == LTQ_FLOW_DEV_INT_R) && + (gswdev->gipver == LTQ_GSWIP_3_0)) { + /*if gswip 3.0: tpnum = physical port + virutual port*/ num_ports = gswdev->tpnum; - } - else { - /*pnum is logical port*/ + } else if (IS_VRSN_31(gswdev->gipver)) { + /*if gswpi 3.1: tpnum = physical port + virutual port*/ + num_ports = gswdev->tpnum; + } else { + /*pnum is logical port: pnum = physical port*/ num_ports = gswdev->pnum; } switch (parm->eRmonType) { case GSW_RMON_ALL_TYPE: - /* NOTE:Software Reset for All Interface RMON RAM in case of 3.0*/ - /* NOTE:Software Reset for All Bridge Port RMON RAM in case of 3.1*/ - gsw_w32(cdev, BM_RMON_GCTRL_ALLITF_RES_OFFSET, - BM_RMON_GCTRL_ALLITF_RES_SHIFT, - BM_RMON_GCTRL_ALLITF_RES_SIZE, 0x1); + /* NOTE:Software Reset for All Interface RMON RAM in case of 3.0*/ + /* NOTE:Software Reset for All Bridge Port RMON RAM in case of 3.1*/ + gsw_w32(cdev, BM_RMON_GCTRL_ALLITF_RES_OFFSET, + BM_RMON_GCTRL_ALLITF_RES_SHIFT, + BM_RMON_GCTRL_ALLITF_RES_SIZE, 0x1); /* Software Reset for PMAC RMON RAM*/ gsw_w32(cdev, BM_RMON_GCTRL_PMAC_RES_OFFSET, @@ -10692,18 +13821,18 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) gsw_w32(cdev, BM_RMON_GCTRL_METER_RES_OFFSET, BM_RMON_GCTRL_METER_RES_SHIFT, BM_RMON_GCTRL_METER_RES_SIZE, 0x1); - + /*Not Applicable for GSWIP 3.1*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { /* Software Reset for Redirection RMON RAM */ gsw_w32(cdev, BM_RMON_GCTRL_RED_RES_OFFSET, BM_RMON_GCTRL_RED_RES_SHIFT, BM_RMON_GCTRL_RED_RES_SIZE, 0x1); } - + /* Reset all port based RMON counter */ for (index = 0; index < num_ports; index++) { - pr_err("Rmon clear for CTP RX/TX --Logical Port %u\n",index); + pr_err("Rmon clear for CTP RX/TX --Logical Port %u\n", index); gsw_w32(cdev, BM_RMON_CTRL_RAM1_RES_OFFSET + (index * 2), BM_RMON_CTRL_RAM1_RES_SHIFT, @@ -10712,8 +13841,9 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) BM_RMON_CTRL_RAM2_RES_OFFSET + (index * 2), BM_RMON_CTRL_RAM2_RES_SHIFT, BM_RMON_CTRL_RAM2_RES_SIZE, 0x1); + /*Not Applicable for GSWIP 3.1*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { /* Software Reset for Routing RMON RAM */ gsw_w32(cdev, BM_RMON_CTRL_ROUT_RES_OFFSET + (index * 2), @@ -10721,17 +13851,23 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) BM_RMON_CTRL_ROUT_RES_SIZE, 0x1); } } + break; + case GSW_RMON_PMAC_TYPE: /* Software Reset for PMAC RMON RAM*/ gsw_w32(cdev, BM_RMON_GCTRL_PMAC_RES_OFFSET, BM_RMON_GCTRL_PMAC_RES_SHIFT, BM_RMON_GCTRL_PMAC_RES_SIZE, 0x1); break; + case GSW_RMON_PORT_TYPE: case GSW_RMON_CTP_TYPE: - if (pidx >= num_ports) - return GSW_statusErr; + if (pidx >= num_ports) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Reset all RMON counter */ /* Incase of GSWIP 3.1 Reset CTP pidx RX/TX counter */ gsw_w32(cdev, @@ -10743,12 +13879,14 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) BM_RMON_CTRL_RAM2_RES_SHIFT, BM_RMON_CTRL_RAM2_RES_SIZE, 0x1); break; + case GSW_RMON_METER_TYPE: /* Software Reset for Meter RMON RAM */ gsw_w32(cdev, BM_RMON_GCTRL_METER_RES_OFFSET, BM_RMON_GCTRL_METER_RES_SHIFT, BM_RMON_GCTRL_METER_RES_SIZE, 0x1); break; + case GSW_RMON_IF_TYPE: case GSW_RMON_BRIDGE_TYPE: /* Interface ID to be Reset 3.0 */ @@ -10761,225 +13899,314 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm) BM_RMON_GCTRL_INT_RES_SHIFT, BM_RMON_GCTRL_INT_RES_SIZE, 0x1); break; + case GSW_RMON_ROUTE_TYPE: - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Software Reset for Routing RMON RAM */ - gsw_w32(cdev, - BM_RMON_CTRL_ROUT_RES_OFFSET + (pidx * 2), - BM_RMON_CTRL_ROUT_RES_SHIFT, - BM_RMON_CTRL_ROUT_RES_SIZE, 0x1); + gsw_w32(cdev, + BM_RMON_CTRL_ROUT_RES_OFFSET + (pidx * 2), + BM_RMON_CTRL_ROUT_RES_SHIFT, + BM_RMON_CTRL_ROUT_RES_SIZE, 0x1); break; + case GSW_RMON_REDIRECT_TYPE: - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* Software Reset for Redirection RMON RAM */ gsw_w32(cdev, BM_RMON_GCTRL_RED_RES_OFFSET, BM_RMON_GCTRL_RED_RES_SHIFT, BM_RMON_GCTRL_RED_RES_SIZE, 0x1); break; + default: break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } static GSW_return_t GSW_RMON_Port_Get_Active(void *cdev, GSW_RMON_Port_cnt_t *parm) { - u8 RmonCntOffset=0; + u8 RmonCntOffset = 0; u32 data = 0, data1 = 0; u32 r_frame = 0, r_unicast = 0, r_multicast = 0, - t_frame = 0, t_unicast = 0, t_multicast = 0; + t_frame = 0, t_unicast = 0, t_multicast = 0; u32 rgbcl = 0, rbbcl = 0, tgbcl = 0; u64 rgbch = 0, rbbch = 0, tgbch = 0; - u32 Portmode=0,PortId=0; + u32 Portmode = 0, PortId = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 count = 0; - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; + u32 ret; + GSW_CTP_portAssignment_t ctp_get; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - Portmode=parm->ePortType; - PortId=parm->nPortId; + + Portmode = parm->ePortType; + PortId = parm->nPortId; /*Clear the structure before using*/ memset(parm, 0, sizeof(GSW_RMON_Port_cnt_t)); - + switch (Portmode) { - case GSW_RMON_CTP_PORT_RX: - case GSW_RMON_CTP_PORT_TX: - case GSW_RMON_CTP_PORT_PCE_BYPASS: - if(PortId >= gswdev->num_of_ctp) { - pr_err("PortId %d >= gswdev->num_of_ctp %d\n",PortId,gswdev->num_of_ctp); - return GSW_statusErr; - } - break; - case GSW_RMON_BRIDGE_PORT_RX: - case GSW_RMON_BRIDGE_PORT_TX: - if(PortId >= gswdev->num_of_bridge_port) { - pr_err("PortId %d >= gswdev->num_of_ctp %d\n",PortId,gswdev->num_of_bridge_port); - return GSW_statusErr; - } - break; - default: - pr_err("ePortType Not Supported :ERROR (ePortType=%d)\n",Portmode); + case GSW_CTP_PORT: + + /*check based on number of logical port*/ + if (PortId > gswdev->tpnum) { + pr_err("PortId %d >= gswdev->num_of_ctp %d\n", PortId, gswdev->num_of_ctp); + return GSW_statusErr; + } + + ctp_get.nLogicalPortId = PortId; + ret = GSW_CTP_PortAssignmentGet(cdev, &ctp_get); + + if (ret == GSW_statusErr) { + pr_err("GSW_CTP_PortAssignmentGet returns error\n"); + return ret; + } + + PortId = ctp_get.nFirstCtpPortId + parm->nSubIfIdGroup; + + if (PortId > gswdev->num_of_ctp) { + pr_err("PortId %d > gswdev->num_of_ctp\n", PortId); + return GSW_statusErr; + } + + if (PortId < ctp_get.nFirstCtpPortId || + PortId >= (ctp_get.nFirstCtpPortId + ctp_get.nNumberOfCtpPort)) { + pr_err("ERROR :CTP port not with in Allocated range\n"); + pr_err("Check CTP assignment Get\n"); + return GSW_statusErr; + } + + break; + + case GSW_BRIDGE_PORT: + if (PortId >= gswdev->num_of_bridge_port) { + pr_err("PortId %d >= gswdev->num_of_ctp %d\n", PortId, gswdev->num_of_bridge_port); return GSW_statusErr; - } + } + + break; + + default: + pr_err("ePortType Not Supported :ERROR (ePortType=%d)\n", Portmode); + return GSW_statusErr; + } /*GSW_ENABLE should be called before calling RMON_GET In GSW_ENABLE RMON Counter for 0- 15 logical port are enabled*/ - if(Portmode == GSW_RMON_CTP_PORT_RX || Portmode == GSW_RMON_BRIDGE_PORT_RX) - count = RMON_COUNTER_OFFSET_GSWIP3_1; - else - count = 14; + /*Only for RX, As per SAS counter offset 0 - 21 is + shared between RX and TX. + Depends upon ePortType selection*/ + //One-time populate. bmtable.adr.rmon.portOffset = PortId; - bmtable.tableID = (BM_Table_ID)Portmode; + + if (Portmode == GSW_CTP_PORT) { + bmtable.tableID = (BM_Table_ID)GSW_RMON_CTP_PORT_RX; + } else { + bmtable.tableID = (BM_Table_ID)GSW_RMON_BRIDGE_PORT_RX; + } + bmtable.b64bitMode = 1; bmtable.numValues = 4; - - for (RmonCntOffset = 0; RmonCntOffset < count; RmonCntOffset++) - { + count = RMON_COUNTER_OFFSET_GSWIP3_1; + + for (RmonCntOffset = 0; (RmonCntOffset < count) && !parm->bPceBypass; RmonCntOffset++) { bmtable.adr.rmon.counterOffset = RmonCntOffset; gsw_bm_table_read(cdev, &bmtable); data = (bmtable.value[1] << 16) | (bmtable.value[0] & 0xFFFF); data1 = (bmtable.value[3] << 16) | (bmtable.value[2] & 0xFFFF); - - /*Only for RX, As per SAS counter offset 0 - 21 is - shared between RX and TX. - Depends upon ePortType selection*/ - if(Portmode == GSW_RMON_CTP_PORT_RX || - Portmode == GSW_RMON_BRIDGE_PORT_RX) - { - switch (RmonCntOffset) { - case 0x00: /*RX Size 64 frame count*/ - parm->nRx64BytePkts = data; - parm->nRx127BytePkts = data1; /* Receive Size 65-127 Frame Count */ - break; - case 0x02: /* Receive Size 128-255 Frame Count */ - parm->nRx255BytePkts = data; - parm->nRx511BytePkts = data1; /* Receive Size 256-511 Frame Count */ - break; - case 0x04: /* Receive Size 512-1023 Frame Count */ - parm->nRx1023BytePkts = data; - parm->nRxMaxBytePkts = data1; /* Receive Size 1024 - 1518 Frame Count */ - break; - case 0x06: /* Receive Unicast Frame Count */ - parm->nRxUnicastPkts = r_unicast = data; - parm->nRxMulticastPkts = r_multicast = data1; /* Receive Multicast Frame Count1 */ - break; - case 0x08: /* Receive Undersize Good Count */ - parm->nRxUnderSizeGoodPkts = data; /* Less than 64 byes. */ - parm->nRxOversizeGoodPkts = data1; /* Receive Oversize (> 1518) Good Count */ - break; - case 0x0A: /* Receive Good Byte Count (Low) */ - rgbcl = data; - rgbch = data1; /* Receive Good Byte Count (High) */ - break; - case 0x0C: /* Receive Frme Count */ - parm->nRxBroadcastPkts = r_frame = data; - parm->nRxFilteredPkts = data1; /* Receive Drop (Filter) Frame Count */ - break; - case 0x0E: /* Receive Extended Vlan Discard Frame Count */ - parm->nRxExtendedVlanDiscardPkts = data; - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - parm->nRxFCSErrorPkts = data1; /* Receive MAC/FCS Error frame Count */ - break; - case 0x10: /* Receive Undersize Bad Count */ - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - parm->nRxUnderSizeErrorPkts = data; - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - parm->nRxOversizeErrorPkts = data1; /* Receive Oversize Bad Count */ - break; - case 0x12: /* MTU Exceed Discard Count */ - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - parm->nMtuExceedDiscardPkts = data; - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - parm->nRxDroppedPkts = data1; /* Receive Discard (Tail-Drop) Frame Count */ - break; - case 0x14: /* Receive Bad Byte Count (Low) */ - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - rbbcl = data; - /*only applicable for CTP RX*/ - if(Portmode == GSW_RMON_CTP_PORT_RX) - rbbch = data1; /* Receive Bad Byte Count (High) */ - break; - } - } - - /*Only for TX, As per SAS counter offset 0 - 21 is - shared between RX and TX. - Depends upon ePortType selection*/ - if(Portmode == GSW_RMON_CTP_PORT_TX || - Portmode == GSW_RMON_CTP_PORT_PCE_BYPASS || - Portmode == GSW_RMON_BRIDGE_PORT_TX) - { - switch (RmonCntOffset) { - case 0x00: /* Transmit Size 64 Frame Count */ - parm->nTx64BytePkts = data; - parm->nTx127BytePkts = data1; /* Transmit Size 65-127 Frame Count */ - break; - case 0x02: /* Transmit Size 128-255 Frame Count */ - parm->nTx255BytePkts = data; - parm->nTx511BytePkts = data1; /* Transmit Size 256-511 Frame Count */ - break; - case 0x04: /* Transmit Size 512-1023 Frame Count */ - parm->nTx1023BytePkts = data; - parm->nTxMaxBytePkts = data1; /* Transmit Size 1024 - 1518 Frame Count */ - break; - case 0x06: /* Transmit Unicast Frame Count */ - parm->nTxUnicastPkts = t_unicast = data; - parm->nTxMulticastPkts = t_multicast = data1; /* Transmit Multicast Frame Count1 */ - break; - case 0x08: /* Transmit Undersize Good Count */ - parm->nTxUnderSizeGoodPkts = data; /* Less than 64 byes */ - parm->nTxOversizeGoodPkts = data1; /* Transmit Oversize (> 1518) Good Count */ - break; - case 0x0A: /* Transmit Good Byte Count (Low) */ - tgbcl = data; - tgbch = data1; /* Transmit Good Byte Count (High) */ - break; - case 0x0C: /* Transmit BroadCast Count */ - parm->nTxBroadcastPkts = t_frame = data; - parm->nTxAcmDroppedPkts = data1; /* Egress Queue Discard,(Active Congestion Management) frame count.*/ - break; - } + + switch (RmonCntOffset) { + case 0x00: /*RX Size 64 frame count*/ + parm->nRx64BytePkts = data; + parm->nRx127BytePkts = data1; /* Receive Size 65-127 Frame Count */ + break; + + case 0x02: /* Receive Size 128-255 Frame Count */ + parm->nRx255BytePkts = data; + parm->nRx511BytePkts = data1; /* Receive Size 256-511 Frame Count */ + break; + + case 0x04: /* Receive Size 512-1023 Frame Count */ + parm->nRx1023BytePkts = data; + parm->nRxMaxBytePkts = data1; /* Receive Size 1024 - 1518 Frame Count */ + break; + + case 0x06: /* Receive Unicast Frame Count */ + parm->nRxUnicastPkts = r_unicast = data; + parm->nRxMulticastPkts = r_multicast = data1; /* Receive Multicast Frame Count1 */ + break; + + case 0x08: /* Receive Undersize Good Count */ + parm->nRxUnderSizeGoodPkts = data; /* Less than 64 byes. */ + parm->nRxOversizeGoodPkts = data1; /* Receive Oversize (> 1518) Good Count */ + break; + + case 0x0A: /* Receive Good Byte Count (Low) */ + rgbcl = data; + rgbch = data1; /* Receive Good Byte Count (High) */ + break; + + case 0x0C: /* Receive Frme Count */ + parm->nRxBroadcastPkts = r_frame = data; + parm->nRxFilteredPkts = data1; /* Receive Drop (Filter) Frame Count */ + break; + + case 0x0E: /* Receive Extended Vlan Discard Frame Count */ + parm->nRxExtendedVlanDiscardPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxFCSErrorPkts = data1; /* Receive MAC/FCS Error frame Count */ + + break; + + case 0x10: /* Receive Undersize Bad Count */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxUnderSizeErrorPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxOversizeErrorPkts = data1; /* Receive Oversize Bad Count */ + + break; + + case 0x12: /* MTU Exceed Discard Count */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nMtuExceedDiscardPkts = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + parm->nRxDroppedPkts = data1; /* Receive Discard (Tail-Drop) Frame Count */ + + break; + + case 0x14: /* Receive Bad Byte Count (Low) */ + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + rbbcl = data; + + /*only applicable for CTP RX*/ + if (Portmode == GSW_RMON_CTP_PORT_RX) + rbbch = data1; /* Receive Bad Byte Count (High) */ + + break; } - RmonCntOffset = RmonCntOffset + 1; + + RmonCntOffset = RmonCntOffset + 1; } - if(Portmode == GSW_RMON_CTP_PORT_RX || - Portmode == GSW_RMON_BRIDGE_PORT_RX) - { + + if ((Portmode == GSW_CTP_PORT || + Portmode == GSW_BRIDGE_PORT) && + !parm->bPceBypass) { /* Receive Good Byte Count */ parm->nRxGoodBytes = (u64)(((rgbch & 0xFFFFFFFF) << 32) | (rgbcl & 0xFFFFFFFF)); - if(Portmode == GSW_RMON_CTP_PORT_RX) - { + + if (Portmode == GSW_CTP_PORT) { /* Receive Bad Byte Count */ parm->nRxBadBytes = (u64)(((rbbch & 0xFFFFFFFF) << 32) | (rbbcl & 0xFFFFFFFF)); } + parm->nRxGoodPkts = r_frame + r_unicast + r_multicast; } - if(Portmode == GSW_RMON_CTP_PORT_TX || - Portmode == GSW_RMON_CTP_PORT_PCE_BYPASS || - Portmode == GSW_RMON_BRIDGE_PORT_TX) - { - parm->nTxGoodPkts = t_frame + t_unicast + t_multicast; - /* Transmit Good Byte Count */ - parm->nTxGoodBytes = (u64)(((tgbch & 0xFFFFFFFF)<< 32) | (tgbcl & 0xFFFFFFFF) ); + + /*Only for TX, As per SAS counter offset 0 - 13 is + shared between RX and TX. + Depends upon ePortType selection*/ + + //One-time populate. + bmtable.adr.rmon.portOffset = PortId; + + if (Portmode == GSW_CTP_PORT) { + if (parm->bPceBypass) + bmtable.tableID = (BM_Table_ID)GSW_RMON_CTP_PORT_PCE_BYPASS; + else + bmtable.tableID = (BM_Table_ID)GSW_RMON_CTP_PORT_TX; + } else { + bmtable.tableID = (BM_Table_ID)GSW_RMON_BRIDGE_PORT_TX; + } + + bmtable.b64bitMode = 1; + bmtable.numValues = 4; + count = 14; + + for (RmonCntOffset = 0; RmonCntOffset < count; RmonCntOffset++) { + + bmtable.adr.rmon.counterOffset = RmonCntOffset; + gsw_bm_table_read(cdev, &bmtable); + data = (bmtable.value[1] << 16) | (bmtable.value[0] & 0xFFFF); + data1 = (bmtable.value[3] << 16) | (bmtable.value[2] & 0xFFFF); + + switch (RmonCntOffset) { + case 0x00: /* Transmit Size 64 Frame Count */ + parm->nTx64BytePkts = data; + parm->nTx127BytePkts = data1; /* Transmit Size 65-127 Frame Count */ + break; + + case 0x02: /* Transmit Size 128-255 Frame Count */ + parm->nTx255BytePkts = data; + parm->nTx511BytePkts = data1; /* Transmit Size 256-511 Frame Count */ + break; + + case 0x04: /* Transmit Size 512-1023 Frame Count */ + parm->nTx1023BytePkts = data; + parm->nTxMaxBytePkts = data1; /* Transmit Size 1024 - 1518 Frame Count */ + break; + + case 0x06: /* Transmit Unicast Frame Count */ + parm->nTxUnicastPkts = t_unicast = data; + parm->nTxMulticastPkts = t_multicast = data1; /* Transmit Multicast Frame Count1 */ + break; + + case 0x08: /* Transmit Undersize Good Count */ + parm->nTxUnderSizeGoodPkts = data; /* Less than 64 byes */ + parm->nTxOversizeGoodPkts = data1; /* Transmit Oversize (> 1518) Good Count */ + break; + + case 0x0A: /* Transmit Good Byte Count (Low) */ + tgbcl = data; + tgbch = data1; /* Transmit Good Byte Count (High) */ + break; + + case 0x0C: /* Transmit BroadCast Count */ + parm->nTxBroadcastPkts = t_frame = data; + parm->nTxAcmDroppedPkts = data1; /* Egress Queue Discard,(Active Congestion Management) frame count.*/ + break; + } + + RmonCntOffset = RmonCntOffset + 1; } - - parm->ePortType=Portmode; - parm->nPortId=PortId; + + parm->nTxGoodPkts = t_frame + t_unicast + t_multicast; + /* Transmit Good Byte Count */ + parm->nTxGoodBytes = (u64)(((tgbch & 0xFFFFFFFF) << 32) | (tgbcl & 0xFFFFFFFF)); return GSW_statusOk; } @@ -10987,19 +14214,21 @@ static GSW_return_t GSW_RMON_Port_Get_Active(void *cdev, GSW_RMON_Port_cnt_t *pa static GSW_return_t GSW_RMON_Port_Get_Legacy(void *cdev, GSW_RMON_Port_cnt_t *parm) { u8 pidx, i; - u32 data,value, bcast_cnt; + u32 data, value, bcast_cnt; u32 r_frame = 0, r_unicast = 0, r_multicast = 0, - t_frame = 0, t_unicast = 0, t_multicast = 0; + t_frame = 0, t_unicast = 0, t_multicast = 0; u32 rgbcl = 0, rbbcl = 0, tgbcl = 0; u64 rgbch = 0, rbbch = 0, tgbch = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - bmtbl_prog_t bmtable={0}; + bmtbl_prog_t bmtable = {0}; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + pidx = parm->nPortId; + if (gswdev) { if (gswdev->gipver == LTQ_GSWIP_3_0) { if (parm->nPortId >= gswdev->tpnum) @@ -11009,6 +14238,7 @@ static GSW_return_t GSW_RMON_Port_Get_Legacy(void *cdev, GSW_RMON_Port_cnt_t *pa return GSW_statusErr; } } + gsw_w32(cdev, BM_PCFG_CNTEN_OFFSET + (pidx * 2), BM_PCFG_CNTEN_SHIFT, BM_PCFG_CNTEN_SIZE, 1); memset(parm, 0, sizeof(GSW_RMON_Port_cnt_t)); @@ -11016,158 +14246,199 @@ static GSW_return_t GSW_RMON_Port_Get_Legacy(void *cdev, GSW_RMON_Port_cnt_t *pa gsw_r32(cdev, BM_RMON_CTRL_BCAST_CNT_OFFSET + (pidx * 2), BM_RMON_CTRL_BCAST_CNT_SHIFT, BM_RMON_CTRL_BCAST_CNT_SIZE, &bcast_cnt); - - for (i = 0; i < RMON_COUNTER_OFFSET; i++) - { + + for (i = 0; i < RMON_COUNTER_OFFSET; i++) { bmtable.adr.raw = (u16)i; - if (gswdev->gipver == LTQ_GSWIP_3_0) - { - value = (pidx >= 8)?(pidx + 8):parm->nPortId; + + if (gswdev->gipver == LTQ_GSWIP_3_0) { + value = (pidx >= 8) ? (pidx + 8) : parm->nPortId; bmtable.tableID = (BM_Table_ID)value; - } - else - { + } else { bmtable.tableID = (BM_Table_ID)pidx; } + bmtable.numValues = 2; gsw_bm_table_read(cdev, &bmtable); data = (bmtable.value[1] << 16) | bmtable.value[0]; + switch (i) { case 0x1F: /* Receive Frme Count */ if (bcast_cnt == 1) parm->nRxBroadcastPkts = data; else parm->nRxGoodPkts = data; + r_frame = data; break; + case 0x23: /* Receive Unicast Frame Count */ parm->nRxUnicastPkts = data; r_unicast = data; break; + case 0x22: /* Receive Multicast Frame Count1 */ parm->nRxMulticastPkts = data; r_multicast = data; break; + case 0x21: /* Receive CRC Errors Count */ parm->nRxFCSErrorPkts = data; break; + case 0x1D: /* Receive Undersize Good Count */ parm->nRxUnderSizeGoodPkts = data; break; + case 0x1B: /* Receive Oversize Good Count */ parm->nRxOversizeGoodPkts = data; break; + case 0x1E: /* Receive Undersize Bad Count */ parm->nRxUnderSizeErrorPkts = data; break; + case 0x20: /* Receive Pause Good Count */ parm->nRxGoodPausePkts = data; break; + case 0x1C: /* Receive Oversize Bad Count */ parm->nRxOversizeErrorPkts = data; break; + case 0x1A: /* Receive Alignment Errors Count */ parm->nRxAlignErrorPkts = data; break; + case 0x12: /* Receive Size 64 Frame Count1 */ parm->nRx64BytePkts = data; break; + case 0x13: /* Receive Size 65-127 Frame Count */ parm->nRx127BytePkts = data; break; + case 0x14: /* Receive Size 128-255 Frame Count */ parm->nRx255BytePkts = data; break; + case 0x15: /* Receive Size 256-511 Frame Count */ parm->nRx511BytePkts = data; break; + case 0x16: /* Receive Size 512-1023 Frame Count */ parm->nRx1023BytePkts = data; break; + case 0x17: /* Receive Size Greater 1023 Frame Count */ parm->nRxMaxBytePkts = data; break; + case 0x18: /* Receive Discard (Tail-Drop) Frame Count */ parm->nRxDroppedPkts = data; break; + case 0x19: /* Receive Drop (Filter) Frame Count */ parm->nRxFilteredPkts = data; break; + case 0x24: /* Receive Good Byte Count (Low) */ rgbcl = data; break; + case 0x25: /* Receive Good Byte Count (High) */ rgbch = data; break; + case 0x26: /* Receive Bad Byte Count (Low) */ rbbcl = data; break; + case 0x27: /* Receive Bad Byte Count (High) */ rbbch = data; break; + case 0x0C: /* Transmit Frame Count */ if (bcast_cnt == 1) parm->nTxBroadcastPkts = data; else parm->nTxGoodPkts = data; + t_frame = data; break; + case 0x06: /* Transmit Unicast Frame Count */ parm->nTxUnicastPkts = data; t_unicast = data; break; + case 0x07: /* Transmit Multicast Frame Count1 */ parm->nTxMulticastPkts = data; t_multicast = data; break; + case 0x00: /* Transmit Size 64 Frame Count */ parm->nTx64BytePkts = data; break; + case 0x01: /* Transmit Size 65-127 Frame Count */ parm->nTx127BytePkts = data; break; + case 0x02: /* Transmit Size 128-255 Frame Count */ parm->nTx255BytePkts = data; break; + case 0x03: /* Transmit Size 256-511 Frame Count */ parm->nTx511BytePkts = data; break; + case 0x04: /* Transmit Size 512-1023 Frame Count */ parm->nTx1023BytePkts = data; break; + case 0x05: /* Transmit Size Greater 1024 Frame Count */ parm->nTxMaxBytePkts = data; break; + case 0x08: /* Transmit Single Collision Count. */ parm->nTxSingleCollCount = data; break; + case 0x09: /* Transmit Multiple Collision Count */ parm->nTxMultCollCount = data; break; + case 0x0A: /* Transmit Late Collision Count */ parm->nTxLateCollCount = data; break; + case 0x0B: /* Transmit Excessive Collision.*/ parm->nTxExcessCollCount = data; break; + case 0x0D: /* Transmit Pause Frame Count */ parm->nTxPauseCount = data; break; + case 0x10: /* Transmit Drop Frame Count */ parm->nTxDroppedPkts = data; break; + case 0x0E: /* Transmit Good Byte Count (Low) */ tgbcl = data; break; + case 0x0F: /* Transmit Good Byte Count (High) */ tgbch = data; break; + case 0x11: -/* Transmit Dropped Packet Cound, based on Congestion Management.*/ + /* Transmit Dropped Packet Cound, based on Congestion Management.*/ parm->nTxAcmDroppedPkts = data; break; } } + if (bcast_cnt == 1) { parm->nRxGoodPkts = r_frame + r_unicast + r_multicast; parm->nTxGoodPkts = t_frame + t_unicast + t_multicast; @@ -11177,125 +14448,181 @@ static GSW_return_t GSW_RMON_Port_Get_Legacy(void *cdev, GSW_RMON_Port_cnt_t *pa /* Transmit Broadcase Frme Count */ parm->nTxBroadcastPkts = t_frame - t_unicast - t_multicast; } + /* Receive Good Byte Count */ parm->nRxGoodBytes = (u64)(((rgbch & 0xFFFFFFFF) << 32) | (rgbcl & 0xFFFFFFFF)); /* Receive Bad Byte Count */ parm->nRxBadBytes = (u64)(((rbbch & 0xFFFFFFFF) << 32) | (rbbcl & 0xFFFFFFFF)); /* Transmit Good Byte Count */ - parm->nTxGoodBytes = (u64)(((tgbch & 0xFFFFFFFF)<< 32) | (tgbcl & 0xFFFFFFFF) ); + parm->nTxGoodBytes = (u64)(((tgbch & 0xFFFFFFFF) << 32) | (tgbcl & 0xFFFFFFFF)); return GSW_statusOk; } GSW_return_t GSW_RMON_Port_Get(void *cdev, GSW_RMON_Port_cnt_t *parm) { - u8 ret; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev->gipver == LTQ_GSWIP_3_1) - { - ret = GSW_RMON_Port_Get_Active(cdev,parm); - if(ret == GSW_statusErr) - return GSW_statusErr; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_RMON_Port_Get_Active(cdev, parm); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; } else { - ret = GSW_RMON_Port_Get_Legacy(cdev,parm); - if(ret == GSW_statusErr) - return GSW_statusErr; + ret = GSW_RMON_Port_Get_Legacy(cdev, parm); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + } GSW_return_t GSW_RMON_Mode_Set(void *cdev, GSW_RMON_mode_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + if (((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) || - gswdev->gipver == LTQ_GSWIP_3_1) { + IS_VRSN_31(gswdev->gipver)) { switch (parm->eRmonType) { case GSW_RMON_ALL_TYPE: break; + case GSW_RMON_PMAC_TYPE: break; + case GSW_RMON_PORT_TYPE: break; + case GSW_RMON_METER_TYPE: - if (parm->eCountMode == GSW_RMON_COUNT_BYTES) + if (parm->eCountMode == GSW_RMON_COUNT_BYTES) gsw_w32(cdev, BM_RMON_GCTRL_MRMON_OFFSET, BM_RMON_GCTRL_MRMON_SHIFT, \ BM_RMON_GCTRL_MRMON_SIZE, 1); else gsw_w32(cdev, BM_RMON_GCTRL_MRMON_OFFSET, BM_RMON_GCTRL_MRMON_SHIFT, \ BM_RMON_GCTRL_MRMON_SIZE, 0); + break; + case GSW_RMON_IF_TYPE: - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (parm->eCountMode == GSW_RMON_DROP_COUNT) gsw_w32(cdev, BM_RMON_GCTRL_INTMON_OFFSET, BM_RMON_GCTRL_INTMON_SHIFT, \ BM_RMON_GCTRL_INTMON_SIZE, 1); else gsw_w32(cdev, BM_RMON_GCTRL_INTMON_OFFSET, BM_RMON_GCTRL_INTMON_SHIFT, \ BM_RMON_GCTRL_INTMON_SIZE, 0); + break; + case GSW_RMON_ROUTE_TYPE: - if (gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusErr; + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (parm->eCountMode == GSW_RMON_COUNT_BYTES) gsw_w32(cdev, PCE_GCTRL_1_RSCNTMD_OFFSET, PCE_GCTRL_1_RSCNTMD_SHIFT, \ PCE_GCTRL_1_RSCNTMD_SIZE, 1); else gsw_w32(cdev, PCE_GCTRL_1_RSCNTMD_OFFSET, PCE_GCTRL_1_RSCNTMD_SHIFT, \ PCE_GCTRL_1_RSCNTMD_SIZE, 0); + break; + case GSW_RMON_REDIRECT_TYPE: break; + default: break; } } else { - return GSW_statusErr; + ret = GSW_statusErr; } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } static GSW_return_t GSW_RMON_Meter_Get_Legacy(void *cdev, GSW_RMON_Meter_cnt_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) { u8 index, addr; u32 data, data0, data1; u8 i, j, m, rpt, loc, hc, crd[MAX_READ] = {0}; u32 rdcount[MAX_READ], br; u8 meterid = parm->nMeterId; + if (parm->nMeterId >= gswdev->num_of_meters) return GSW_statusErr; + for (index = 0; index <= 3; index++) { - rpt = 0; hc = 0; br = 0; + rpt = 0; + hc = 0; + br = 0; addr = (meterid | (index << 6)); gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, addr); - repeat: +repeat: rpt++; - for ( i = 0; i < MAX_READ; i++) + + for (i = 0; i < MAX_READ; i++) crd[i] = 0; - loc = 0; - for ( j = 0; j < MAX_READ; j++) { + + loc = 0; + + for (j = 0; j < MAX_READ; j++) { #ifndef CONFIG_X86_INTEL_CE2700 -/*suresh*/ + /*suresh*/ // ltq_w32(0x8019, gswr_bm_addr); // ltq_w32(0x0019, gswr_bm_addr); - // asm("SYNC"); + // asm("SYNC"); // ltq_w32(0x8019, gswr_bm_addr); #endif - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); - for ( i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -11303,97 +14630,122 @@ static GSW_return_t GSW_RMON_Meter_Get_Legacy(void *cdev, GSW_RMON_Meter_cnt_t * BM_RAM_VAL_1_VAL1_SHIFT, BM_RAM_VAL_1_VAL1_SIZE, &data1); } + data = (data1 << 16 | data0); + switch (index) { case 0: rdcount[j] = data; break; + case 1: rdcount[j] = data; break; + case 2: rdcount[j] = data; break; + case 3: rdcount[j] = data; break; } } + switch (index) { case 0: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nResCount = br; - break; + break; + case 1: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nGreenCount = br; - break; + break; + case 2: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nYellowCount = br; - break; + break; + case 3: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nRedCount = br; - break; + break; } } } else { return GSW_statusErr; } - return 0; + + return GSW_statusOk; } -static GSW_return_t GSW_RMON_Meter_Get_Active (void *cdev, GSW_RMON_Meter_cnt_t *parm) +static GSW_return_t GSW_RMON_Meter_Get_Active(void *cdev, GSW_RMON_Meter_cnt_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 counter, data0, data1; u32 meterIndex, ctrlRegData = 0, addrRegData = 0, cntOffset = 0; + if (gswdev == NULL) { pr_err("%s:%s:%d\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + //Temp store. - meterIndex = parm->nMeterId; + meterIndex = parm->nMeterId; //Init to zero. memset(parm, 0, sizeof(GSW_RMON_Meter_cnt_t)); //Restire back. - parm->nMeterId = meterIndex; + parm->nMeterId = meterIndex; + //Validate meter-id. if (parm->nMeterId > gswdev->num_of_meters) //Max index check. return GSW_statusErr; //Populate 'data' register's Meter-Id. FILL_CTRL_REG(addrRegData, BM_RAM_ADDR_RMON_METER_NUM_SHIFT, meterIndex); - + //Populate 'control' register data. FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_ADDR_SHIFT, GSW_RMON_METER); //RAM in read mode. @@ -11402,65 +14754,92 @@ static GSW_return_t GSW_RMON_Meter_Get_Active (void *cdev, GSW_RMON_Meter_cnt_t FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_BAS_SHIFT, 1); //Read all Green/Yellow/Red counters. - for (cntOffset = GSW_RMON_METER_COLOR_GREEN; - cntOffset <= GSW_RMON_METER_COLOR_RED; cntOffset++) { + for (cntOffset = GSW_RMON_METER_COLOR_GREEN; + cntOffset <= GSW_RMON_METER_COLOR_RED; cntOffset++) { //Populate 'data' register's Counter-Offset. - CLEAR_FILL_CTRL_REG(addrRegData, BM_RAM_ADDR_RMON_METER_CLR_SHIFT, - BM_RAM_ADDR_RMON_METER_CLR_SIZE, cntOffset); + CLEAR_FILL_CTRL_REG(addrRegData, BM_RAM_ADDR_RMON_METER_CLR_SHIFT, + BM_RAM_ADDR_RMON_METER_CLR_SIZE, cntOffset); //Set RAM address to read. gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, addrRegData); //Set RAM table to read. gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to read. CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, &data0); gsw_r32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, &data1); counter = (data1 << 16 | data0); switch (cntOffset) { - case GSW_RMON_METER_COLOR_GREEN: /* Green color */ - parm->nGreenCount = counter; + case GSW_RMON_METER_COLOR_GREEN: /* Green color */ + parm->nGreenCount = counter; break; - case GSW_RMON_METER_COLOR_YELLOW: /* Yellow color */ - parm->nYellowCount = counter; + + case GSW_RMON_METER_COLOR_YELLOW: /* Yellow color */ + parm->nYellowCount = counter; break; - case GSW_RMON_METER_COLOR_RED: /* Red color */ - parm->nRedCount = counter; + + case GSW_RMON_METER_COLOR_RED: /* Red color */ + parm->nRedCount = counter; break; - default: + + default: break; } + counter = data0 = data1 = 0; } + return GSW_statusOk; } GSW_return_t GSW_RMON_Meter_Get(void *cdev, GSW_RMON_Meter_cnt_t *parm) { - u8 ret; + u32 ret; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev->gipver == LTQ_GSWIP_3_1) - { - ret = GSW_RMON_Meter_Get_Active(cdev,parm); - if(ret == GSW_statusErr) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + if (IS_VRSN_31(gswdev->gipver)) { + ret = GSW_RMON_Meter_Get_Active(cdev, parm); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; } else { - ret = GSW_RMON_Meter_Get_Legacy(cdev,parm); - if(ret == GSW_statusErr) - return GSW_statusErr; + ret = GSW_RMON_Meter_Get_Legacy(cdev, parm); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + } GSW_return_t GSW_RMON_Redirect_Get(void *cdev, GSW_RMON_Redirect_cnt_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + if ((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) { u8 index; u8 i, j, m, rpt, loc, hc, crd[MAX_READ] = {0}; @@ -11468,27 +14847,35 @@ GSW_return_t GSW_RMON_Redirect_Get(void *cdev, GSW_RMON_Redirect_cnt_t *parm) u32 data, data0, data1; u64 rxbytes_l = 0, rxbytes_h = 0; u64 txbytes_l = 0, txbytes_h = 0; + for (index = 0; index < 8; index++) { - rpt = 0; hc = 0; br = 0; + rpt = 0; + hc = 0; + br = 0; gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, index); - repeat: +repeat: rpt++; - for ( i = 0; i < MAX_READ; i++) + + for (i = 0; i < MAX_READ; i++) crd[i] = 0; - loc = 0; - for ( j = 0; j < MAX_READ; j++) { + + loc = 0; + + for (j = 0; j < MAX_READ; j++) { #ifndef CONFIG_X86_INTEL_CE2700 -/*suresh*/ + /*suresh*/ // ltq_w32(0x8018, gswr_bm_addr); // ltq_w32(0x0018, gswr_bm_addr); - // asm("SYNC"); + // asm("SYNC"); // ltq_w32(0x8018, gswr_bm_addr); #endif - if( GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, - BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_OFFSET,RETURN_ERROR_CODE)) + + if (GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, + BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_OFFSET, RETURN_ERROR_CODE)) continue; /*Error already printed. Try the next iteration*/ - for ( i = 0; i < 4; i++) { + + for (i = 0; i < 4; i++) { gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -11496,180 +14883,247 @@ GSW_return_t GSW_RMON_Redirect_Get(void *cdev, GSW_RMON_Redirect_cnt_t *parm) BM_RAM_VAL_1_VAL1_SHIFT, BM_RAM_VAL_1_VAL1_SIZE, &data1); } + data = (data1 << 16 | data0); + switch (index) { case 0: rdcount[j] = data; break; + case 1: rdcount[j] = data; break; + case 2: rdcount[j] = data; break; + case 3: rdcount[j] = data; break; + case 4: rdcount[j] = data; break; + case 5: rdcount[j] = data; break; + case 6: rdcount[j] = data; break; + case 7: rdcount[j] = data; break; } } + switch (index) { case 0: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nRxPktsCount = br; break; + case 1: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nRxDiscPktsCount = br; break; + case 2: calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + rxbytes_l = br; break; + case 3: calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + rxbytes_h = br; break; + case 4: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nTxPktsCount = br; break; + case 5: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nTxDiscPktsCount = br; break; + case 6: calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + txbytes_l = br; - /* parm->nTxBytesCount = br; */ + /* parm->nTxBytesCount = br; */ break; + case 7: calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + txbytes_h = br; - /* parm->nTxBytesCount |= (br << 32); */ + /* parm->nTxBytesCount |= (br << 32); */ break; } } + parm->nRxBytesCount = (u64)(((rxbytes_h & 0xFFFFFFFF) << 32) | (rxbytes_l & 0xFFFFFFFF)); parm->nTxBytesCount = (u64)(((txbytes_h & 0xFFFFFFFF) << 32) | (txbytes_l & 0xFFFFFFFF)); } else { - return GSW_statusErr; + ret = GSW_statusErr; } - return 0; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + } GSW_return_t GSW_RMON_If_Get(void *cdev, GSW_RMON_If_cnt_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + if ((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) { u8 index, i, j, m, rpt, loc, hc, crd[MAX_READ] = {0}; - u32 data, data0, data1,addr, intmon; + u32 data, data0, data1, addr, intmon; u32 rdcount[MAX_READ], br; u8 ifid = parm->nIfId; - if (parm->nIfId >= 256) /* ETHSW_CAP_13 register*/ - return GSW_statusErr; + + if (parm->nIfId >= 256) { /* ETHSW_CAP_13 register*/ + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_r32(cdev, BM_RMON_GCTRL_INTMON_OFFSET, BM_RMON_GCTRL_INTMON_SHIFT, BM_RMON_GCTRL_INTMON_SIZE, &intmon); + if (intmon) parm->countMode = GSW_RMON_DROP_COUNT; else parm->countMode = GSW_RMON_COUNT_BYTES; - + for (index = 0; index <= 3; index++) { - rpt = 0; hc = 0; br = 0; + rpt = 0; + hc = 0; + br = 0; addr = (ifid | (index << 8)); gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, addr); - repeat: +repeat: rpt++; - for ( i = 0; i < MAX_READ; i++) + + for (i = 0; i < MAX_READ; i++) crd[i] = 0; - loc = 0; - for ( j = 0; j < MAX_READ; j++) { + + loc = 0; + + for (j = 0; j < MAX_READ; j++) { #ifndef CONFIG_X86_INTEL_CE2700 -/*suresh*/ - // ltq_w32(0x801A, gswr_bm_addr); - // ltq_w32(0x001A, gswr_bm_addr); - // asm("SYNC"); - // ltq_w32(0x801A, gswr_bm_addr); -#endif - if( GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, - BM_RAM_CTRL_BAS_SHIFT,BM_RAM_CTRL_BAS_SIZE,RETURN_ERROR_CODE) ) + /*suresh*/ + // ltq_w32(0x801A, gswr_bm_addr); + // ltq_w32(0x001A, gswr_bm_addr); + // asm("SYNC"); + // ltq_w32(0x801A, gswr_bm_addr); +#endif + + if (GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, + BM_RAM_CTRL_BAS_SHIFT, BM_RAM_CTRL_BAS_SIZE, RETURN_ERROR_CODE)) continue; - - for ( i = 0; i < 4; i++) { + + for (i = 0; i < 4; i++) { gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -11677,77 +15131,99 @@ GSW_return_t GSW_RMON_If_Get(void *cdev, GSW_RMON_If_cnt_t *parm) BM_RAM_VAL_1_VAL1_SHIFT, BM_RAM_VAL_1_VAL1_SIZE, &data1); } + data = (data1 << 16 | data0); + switch (index) { case 0: rdcount[j] = data; break; + case 1: rdcount[j] = data; break; + case 2: rdcount[j] = data; break; + case 3: rdcount[j] = data; break; } } + switch (index) { - case 0: + case 0: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nRxPktsCount = br; break; - case 1: + + case 1: if (intmon) calc_credit_value(rdcount, &m, &loc); else calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + if (intmon) { - parm->nRxDiscPktsCount = br; - parm->nRxBytesCount = 0; - } else { - parm->nRxBytesCount = br; - parm->nRxDiscPktsCount = 0; - } + parm->nRxDiscPktsCount = br; + parm->nRxBytesCount = 0; + } else { + parm->nRxBytesCount = br; + parm->nRxDiscPktsCount = 0; + } + break; - case 2: + + case 2: calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + parm->nTxPktsCount = br; break; - case 3: + + case 3: if (intmon) calc_credit_value(rdcount, &m, &loc); else calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { + + if (m > hc) { hc = m; br = rdcount[loc]; } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { goto repeat; } + if (intmon) { parm->nTxDiscPktsCount = br; parm->nTxBytesCount = 0; @@ -11755,53 +15231,79 @@ GSW_return_t GSW_RMON_If_Get(void *cdev, GSW_RMON_If_cnt_t *parm) parm->nTxBytesCount = br; parm->nTxDiscPktsCount = 0; } + break; } } } else { - return GSW_statusErr; + ret = GSW_statusErr; } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_RMON_Route_Get(void *cdev, GSW_RMON_Route_cnt_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + if ((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) { u8 index, addr; u8 i, j, m, rpt, loc, hc, crd[MAX_READ] = {0}; u32 rdcount[MAX_READ], br; u32 data, data0, data1; u8 rid = parm->nRoutedPortId; - if (parm->nRoutedPortId >= 16 /* gswdev->tpnum*/) - return GSW_statusErr; + + if (parm->nRoutedPortId >= 16 /* gswdev->tpnum*/) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + for (index = 0; index <= 13; index++) { addr = (rid | (index << 4)); gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, addr); - rpt = 0; hc = 0; br = 0; - repeat: + rpt = 0; + hc = 0; + br = 0; +repeat: rpt++; - for ( i = 0; i < MAX_READ; i++) + + for (i = 0; i < MAX_READ; i++) crd[i] = 0; - loc = 0; - for ( j = 0; j < MAX_READ; j++) { + + loc = 0; + + for (j = 0; j < MAX_READ; j++) { #ifndef CONFIG_X86_INTEL_CE2700 -/*suresh*/ + /*suresh*/ // ltq_w32(0x801B, gswr_bm_addr); // ltq_w32(0x001B, gswr_bm_addr); - // asm("SYNC"); + // asm("SYNC"); // ltq_w32(0x801B, gswr_bm_addr); #endif - if( GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_SIZE, - BM_RAM_CTRL_BAS_SHIFT,BM_RAM_CTRL_BAS_SIZE,RETURN_ERROR_CODE)) - continue; - - for ( i = 0; i < 4; i++) { + + if (GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_SIZE, + BM_RAM_CTRL_BAS_SHIFT, BM_RAM_CTRL_BAS_SIZE, RETURN_ERROR_CODE)) + continue; + + for (i = 0; i < 4; i++) { gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -11809,310 +15311,412 @@ GSW_return_t GSW_RMON_Route_Get(void *cdev, GSW_RMON_Route_cnt_t *parm) BM_RAM_VAL_1_VAL1_SHIFT, BM_RAM_VAL_1_VAL1_SIZE, &data1); } + data = (data1 << 16 | data0); + switch (index) { case 0: rdcount[j] = data; break; + case 1: rdcount[j] = data; break; + case 2: rdcount[j] = data; break; + case 3: rdcount[j] = data; break; + case 4: rdcount[j] = data; break; + case 5: rdcount[j] = data; break; + case 6: rdcount[j] = data; break; + case 7: rdcount[j] = data; break; + case 8: rdcount[j] = data; break; + case 9: rdcount[j] = data; break; + case 0x0A: rdcount[j] = data; break; + case 0x0B: rdcount[j] = data; break; + case 0x0C: rdcount[j] = data; break; + case 0x0D: rdcount[j] = data; break; } } + switch (index) { - case 0: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxUCv4UDPPktsCount = br; - break; - case 1: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxUCv4TCPPktsCount = br; - break; - case 2: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxMCv4PktsCount = br; - break; - case 3: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxUCv6UDPPktsCount = br; - break; - case 4: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxUCv6TCPPktsCount = br; - break; - case 5: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxMCv6PktsCount = br; - break; - case 6: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxIPv4BytesCount = br; - break; - case 7: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxIPv6BytesCount = br; - break; - case 8: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxCpuPktsCount = br; - break; - case 9: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxCpuBytesCount = br; - break; - case 0x0A: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxPktsDropCount = br; - break; - case 0x0B: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nRxBytesDropCount = br; - break; - case 0x0C: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nTxPktsCount = br; - break; - case 0x0D: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nTxBytesCount = br; - break; - } - } - } else { - return GSW_statusErr; - } - return 0; -} + case 0: + calc_credit_value(rdcount, &m, &loc); -static GSW_return_t GSW_PMAC_CountGet_v31(void *cdev, GSW_PMAC_Cnt_t *parm) -{ - u8 i=0; - u32 data; - bmtbl_prog_t bmtable={0}; + if (m > hc) { + hc = m; + br = rdcount[loc]; + } - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } - /* For Ingress it is 0 - 16, for Egress 0 - 15. */ - if ((parm->nTxDmaChanId >= 17) || (parm->nPmacId >= 2)) - return GSW_statusErr; + parm->nRxUCv4UDPPktsCount = br; + break; - for (i = 0; i < 8; i++) - { - /* Egress csum counter not present with 3.1 */ - if ((i==2) || (i==3)) - continue; + case 1: + calc_credit_value(rdcount, &m, &loc); - bmtable.adr.pmacRmon.channel_or_port = parm->nTxDmaChanId; - bmtable.adr.pmacRmon.count = i; - bmtable.adr.pmacRmon.pmacNo = parm->nPmacId; - bmtable.b64bitMode = parm->b64BitMode; - bmtable.tableID = PMAC_RMON_COUNTER; - bmtable.numValues = 2; - gsw_bm_table_read(cdev, &bmtable); - data = (bmtable.value[1] << 16) | (bmtable.value[0] & 0xFFFF); + if (m > hc) { + hc = m; + br = rdcount[loc]; + } - switch (i) { - case 0: - parm->nDiscPktsCount = data; + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxUCv4TCPPktsCount = br; break; - case 1: - parm->nDiscBytesCount = data; + + case 2: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxMCv4PktsCount = br; + break; + + case 3: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxUCv6UDPPktsCount = br; break; + case 4: - parm->nIngressPktsCount = data; + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxUCv6TCPPktsCount = br; break; + case 5: - parm->nIngressBytesCount = data; + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxMCv6PktsCount = br; break; + case 6: - parm->nEgressPktsCount = data; + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxIPv4BytesCount = br; break; + case 7: - parm->nEgressBytesCount = data; + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxIPv6BytesCount = br; break; - default: + + case 8: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxCpuPktsCount = br; break; - } - } - - return 0; -} + case 9: + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxCpuBytesCount = br; + break; + + case 0x0A: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxPktsDropCount = br; + break; + + case 0x0B: + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nRxBytesDropCount = br; + break; + + case 0x0C: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nTxPktsCount = br; + break; + + case 0x0D: + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nTxBytesCount = br; + break; + } + } + } else { + ret = GSW_statusErr; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; + +} + +static GSW_return_t GSW_PMAC_CountGet_v31(void *cdev, GSW_PMAC_Cnt_t *parm) +{ + u8 i = 0; + u32 data; + bmtbl_prog_t bmtable = {0}; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + /* For Ingress it is 0 - 16, for Egress 0 - 15. */ + if ((parm->nTxDmaChanId >= 17) || (parm->nPmacId >= 2)) { + return GSW_statusErr; + } + + for (i = 0; i < 8; i++) { + /* Egress csum counter not present with 3.1 */ + if ((i == 2) || (i == 3)) + continue; + + bmtable.adr.pmacRmon.channel_or_port = parm->nTxDmaChanId; + bmtable.adr.pmacRmon.count = i; + bmtable.adr.pmacRmon.pmacNo = parm->nPmacId; + bmtable.b64bitMode = parm->b64BitMode; + bmtable.tableID = PMAC_RMON_COUNTER; + bmtable.numValues = 2; + gsw_bm_table_read(cdev, &bmtable); + data = (bmtable.value[1] << 16) | (bmtable.value[0] & 0xFFFF); + + switch (i) { + case 0: + parm->nDiscPktsCount = data; + break; + + case 1: + parm->nDiscBytesCount = data; + break; + + case 4: + parm->nIngressPktsCount = data; + break; + + case 5: + parm->nIngressBytesCount = data; + break; + + case 6: + parm->nEgressPktsCount = data; + break; + + case 7: + parm->nEgressBytesCount = data; + break; + + default: + break; + } + } + + return GSW_statusOk; +} + +int GSW_PMAC_CountGet(void *cdev, GSW_PMAC_Cnt_t *parm) +{ + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif -int GSW_PMAC_CountGet(void *cdev, GSW_PMAC_Cnt_t *parm) -{ - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } if ((gswdev->gipver == LTQ_GSWIP_3_0) && (gswdev->sdev == LTQ_FLOW_DEV_INT_R)) { u8 index; u8 i, j, m, rpt, loc, hc, crd[MAX_READ] = {0}; u32 rdcount[MAX_READ], br; u32 data0, data1, data, value; - if (parm->nTxDmaChanId >= 16) - return GSW_statusErr; + + if (parm->nTxDmaChanId >= 16) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + for (index = 0; index < 4; index++) { value = ((index << 4) | (parm->nTxDmaChanId & 0xF)); gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, value); - rpt = 0; hc = 0; br = 0; - repeat: + rpt = 0; + hc = 0; + br = 0; +repeat: rpt++; - for ( i = 0; i < MAX_READ; i++) + + for (i = 0; i < MAX_READ; i++) crd[i] = 0; + loc = 0; - for ( j = 0; j < MAX_READ; j++) { + + for (j = 0; j < MAX_READ; j++) { #ifndef CONFIG_X86_INTEL_CE2700 //ltq_w32(0x801C, gswr_bm_addr); //ltq_w32(0x001C, gswr_bm_addr); // asm("SYNC"); //ltq_w32(0x801C, gswr_bm_addr); #endif - if(GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, - BM_RAM_CTRL_BAS_SHIFT,BM_RAM_CTRL_BAS_SIZE,RETURN_ERROR_CODE)) - continue; - - for ( i = 0; i < 4; i++) { + + if (GSW_statusErr == CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, + BM_RAM_CTRL_BAS_SHIFT, BM_RAM_CTRL_BAS_SIZE, RETURN_ERROR_CODE)) + continue; + + for (i = 0; i < 4; i++) { gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -12120,396 +15724,428 @@ int GSW_PMAC_CountGet(void *cdev, GSW_PMAC_Cnt_t *parm) BM_RAM_VAL_1_VAL1_SHIFT, BM_RAM_VAL_1_VAL1_SIZE, &data1); } + data = (data1 << 16 | data0); + switch (index) { case 0: rdcount[j] = data; break; + case 1: rdcount[j] = data; break; + case 2: rdcount[j] = data; break; + case 3: rdcount[j] = data; break; } } + switch (index) { - case 0: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nDiscPktsCount = br; - break; - case 1: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nDiscBytesCount = br; - break; - case 2: - calc_credit_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nChkSumErrPktsCount = br; - break; - case 3: - calc_credit_byte_value(rdcount, &m, &loc); - if ( m > hc) { - hc = m; - br = rdcount[loc]; - } - if ((m < REPEAT_L) && (rpt < REPEAT_M)) { - goto repeat; - } - parm->nChkSumErrBytesCount = br; - break; + case 0: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nDiscPktsCount = br; + break; + + case 1: + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nDiscBytesCount = br; + break; + + case 2: + calc_credit_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nChkSumErrPktsCount = br; + break; + + case 3: + calc_credit_byte_value(rdcount, &m, &loc); + + if (m > hc) { + hc = m; + br = rdcount[loc]; + } + + if ((m < REPEAT_L) && (rpt < REPEAT_M)) { + goto repeat; + } + + parm->nChkSumErrBytesCount = br; + break; } } - } - else if (gswdev->gipver == LTQ_GSWIP_3_1) { + } else if ((gswdev->gipver == LTQ_GSWIP_3_1)) { GSW_PMAC_CountGet_v31(cdev, parm); + } else { + ret = GSW_statusErr; } - else { - return GSW_statusErr; - } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } + + GSW_return_t GSW_PMAC_GLBL_CfgSet(void *cdev, GSW_PMAC_Glbl_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 pmac_ctrl0, pmac_ctrl1, pmac_ctrl2, pmac_ctrl3, pmac_ctrl4; - + u32 pmac_ctrl0_off, + pmac_ctrl1_off, + pmac_ctrl2_off, + pmac_ctrl3_off, + pmac_ctrl4_off, + pmac_bsl1_off, + pmac_bsl2_off, + pmac_bsl3_off; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - gsw_r32_raw(cdev, (PMAC_CTRL_0_PADEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl0); - if (gswdev->gipver == LTQ_GSWIP_3_1) - gsw_r32_raw(cdev, (PMAC_CTRL_1_MLEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl1); - gsw_r32_raw(cdev, (PMAC_CTRL_2_LCHKL_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl2); - gsw_r32_raw(cdev, (PMAC_CTRL_3_JUMBO_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl3); - gsw_r32_raw(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl4); - - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) - { - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_PADEN_SHIFT, - PMAC_CTRL_0_PADEN_SIZE, parm->bPadEna); - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_VPADEN_SHIFT, - PMAC_CTRL_0_VPADEN_SIZE, parm->bVPadEna); - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_VPAD2EN_SHIFT, - PMAC_CTRL_0_VPAD2EN_SIZE, parm->bSVPadEna); - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_FCS_SHIFT, - PMAC_CTRL_0_FCS_SIZE, parm->bTxFCSDis); - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_FCSEN_SHIFT, - PMAC_CTRL_0_FCSEN_SIZE, parm->bRxFCSDis); - } - - if (gswdev->gipver == LTQ_GSWIP_3_0) { - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_CHKREG_SHIFT, - PMAC_CTRL_0_CHKREG_SIZE, parm->bIPTransChkRegDis); - pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_CHKVER_SHIFT, - PMAC_CTRL_0_CHKVER_SIZE, parm->bIPTransChkVerDis); - pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_FLAGEN_SIZE, parm->bProcFlagsEgCfgEna); - } - - if (parm->bJumboEna == 1) { - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, - PMAC_CTRL_2_MLEN_SIZE, 1); - if (gswdev->gipver == LTQ_GSWIP_3_1) - pmac_ctrl1 = gsw_field_w32(pmac_ctrl1, PMAC_CTRL_1_MLEN_SHIFT, - PMAC_CTRL_1_MLEN_SIZE, parm->nMaxJumboLen); - if (gswdev->gipver == LTQ_GSWIP_3_0) - pmac_ctrl3 = gsw_field_w32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, - PMAC_CTRL_3_JUMBO_SIZE, parm->nMaxJumboLen); - } else { - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, - PMAC_CTRL_2_MLEN_SIZE, 0); - if (gswdev->gipver == LTQ_GSWIP_3_0) - pmac_ctrl3 = gsw_field_w32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, - PMAC_CTRL_3_JUMBO_SIZE, 0x8F8); - } - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKL_SHIFT, - PMAC_CTRL_2_LCHKL_SIZE, parm->bLongFrmChkDis); - switch(parm->eShortFrmChkType) { - case GSW_PMAC_SHORT_LEN_DIS: - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, - PMAC_CTRL_2_LCHKS_SIZE, 0); - break; - case GSW_PMAC_SHORT_LEN_ENA_UNTAG: - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, - PMAC_CTRL_2_LCHKS_SIZE, 1); - break; - case GSW_PMAC_SHORT_LEN_ENA_TAG: - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, - PMAC_CTRL_2_LCHKS_SIZE, 2); - break; - case GSW_PMAC_SHORT_LEN_RESERVED: - pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, - PMAC_CTRL_2_LCHKS_SIZE, 3); - break; - } - - if (gswdev->gipver == LTQ_GSWIP_3_1) - { - switch(parm->eProcFlagsEgCfg) { - case GSW_PMAC_PROC_FLAGS_NONE: - break; - case GSW_PMAC_PROC_FLAGS_TC: - pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 0); - break; - case GSW_PMAC_PROC_FLAGS_FLAG: - pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 1); - break; - case GSW_PMAC_PROC_FLAGS_MIX: - pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 2); - break; - } - - if(parm->nBslThreshold[0]) { - gsw_w32(cdev, (PMAC_BSL_LEN0_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN0_SHIFT, PMAC_BSL_LEN0_SIZE, - parm->nBslThreshold[0]); - } - - if(parm->nBslThreshold[1]) { - gsw_w32(cdev, (PMAC_BSL_LEN1_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN1_SHIFT, PMAC_BSL_LEN1_SIZE, - parm->nBslThreshold[1]); - } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif - if(parm->nBslThreshold[2]) { - gsw_w32(cdev, (PMAC_BSL_LEN2_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN2_SHIFT, PMAC_BSL_LEN2_SIZE, - parm->nBslThreshold[2]); + pmac_ctrl0_off = pmac_addr_off(PMAC_CTRL_0_PADEN_OFFSET, parm->nPmacId); + pmac_ctrl1_off = pmac_addr_off(PMAC_CTRL_1_MLEN_OFFSET, parm->nPmacId); + pmac_ctrl2_off = pmac_addr_off(PMAC_CTRL_2_LCHKL_OFFSET, parm->nPmacId); + pmac_ctrl3_off = pmac_addr_off(PMAC_CTRL_3_JUMBO_OFFSET, parm->nPmacId); + pmac_ctrl4_off = pmac_addr_off(PMAC_CTRL_4_FLAGEN_OFFSET, parm->nPmacId); + + pmac_bsl1_off = pmac_addr_off(PMAC_BSL_LEN0_OFFSET, parm->nPmacId); + pmac_bsl2_off = pmac_addr_off(PMAC_BSL_LEN1_OFFSET, parm->nPmacId); + pmac_bsl3_off = pmac_addr_off(PMAC_BSL_LEN2_OFFSET, parm->nPmacId); + + gsw_r32_raw(cdev, pmac_ctrl0_off, &pmac_ctrl0); + + if (IS_VRSN_31(gswdev->gipver)) + gsw_r32_raw(cdev, pmac_ctrl1_off, &pmac_ctrl1); + + gsw_r32_raw(cdev, pmac_ctrl2_off, &pmac_ctrl2); + gsw_r32_raw(cdev, pmac_ctrl3_off, &pmac_ctrl3); + gsw_r32_raw(cdev, pmac_ctrl4_off, &pmac_ctrl4); + + if (IS_VRSN_30_31(gswdev->gipver)) { + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_APADEN_SHIFT, + PMAC_CTRL_0_APADEN_SIZE, parm->bAPadEna); + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_PADEN_SHIFT, + PMAC_CTRL_0_PADEN_SIZE, parm->bPadEna); + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_VPADEN_SHIFT, + PMAC_CTRL_0_VPADEN_SIZE, parm->bVPadEna); + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_VPAD2EN_SHIFT, + PMAC_CTRL_0_VPAD2EN_SIZE, parm->bSVPadEna); + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_FCS_SHIFT, + PMAC_CTRL_0_FCS_SIZE, parm->bTxFCSDis); + + if (IS_VRSN_31(gswdev->gipver)) { + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_FCSEN_SHIFT, + PMAC_CTRL_0_FCSEN_SIZE, parm->bRxFCSDis); } - } - gsw_w32_raw(cdev, (PMAC_CTRL_0_PADEN_OFFSET + (parm->nPmacId * 0x80)), - pmac_ctrl0); - if (gswdev->gipver == LTQ_GSWIP_3_1) - gsw_w32_raw(cdev, (PMAC_CTRL_1_MLEN_OFFSET + (parm->nPmacId * 0x80)), - pmac_ctrl1); - gsw_w32_raw(cdev, (PMAC_CTRL_2_LCHKL_OFFSET + (parm->nPmacId * 0x80)), - pmac_ctrl2); - gsw_w32_raw(cdev, (PMAC_CTRL_3_JUMBO_OFFSET + (parm->nPmacId * 0x80)), - pmac_ctrl3); - gsw_w32_raw(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), - pmac_ctrl4); + if (gswdev->gipver == LTQ_GSWIP_3_0) { + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_CHKREG_SHIFT, + PMAC_CTRL_0_CHKREG_SIZE, parm->bIPTransChkRegDis); + pmac_ctrl0 = gsw_field_w32(pmac_ctrl0, PMAC_CTRL_0_CHKVER_SHIFT, + PMAC_CTRL_0_CHKVER_SIZE, parm->bIPTransChkVerDis); + pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_FLAGEN_SIZE, parm->bProcFlagsEgCfgEna); } - return 0; -} -GSW_return_t GSW_PMAC_GLBL_CfgGet(void *cdev, GSW_PMAC_Glbl_Cfg_t *parm) -{ - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 regval; - u32 pmac_ctrl0, pmac_ctrl1, pmac_ctrl2, pmac_ctrl3, pmac_ctrl4; - - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } + if (parm->bJumboEna == 1) { + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, + PMAC_CTRL_2_MLEN_SIZE, 1); - gsw_r32_raw(cdev, (PMAC_CTRL_0_PADEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl0); - if (gswdev->gipver == LTQ_GSWIP_3_1) - gsw_r32_raw(cdev, (PMAC_CTRL_1_MLEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl1); - gsw_r32_raw(cdev, (PMAC_CTRL_2_LCHKL_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl2); - gsw_r32_raw(cdev, (PMAC_CTRL_3_JUMBO_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl3); - gsw_r32_raw(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), - &pmac_ctrl4); - - - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { - - parm->bPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_PADEN_SHIFT, - PMAC_CTRL_0_PADEN_SIZE); - parm->bVPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_VPADEN_SHIFT, - PMAC_CTRL_0_VPADEN_SIZE); - parm->bSVPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_VPAD2EN_SHIFT, - PMAC_CTRL_0_VPAD2EN_SIZE); - parm->bTxFCSDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_FCS_SHIFT, - PMAC_CTRL_0_FCS_SIZE); - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - parm->bRxFCSDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_FCSEN_SHIFT, - PMAC_CTRL_0_FCSEN_SIZE); - } - - if (gswdev->gipver == LTQ_GSWIP_3_0) { - parm->bIPTransChkRegDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_CHKREG_SHIFT, - PMAC_CTRL_0_CHKREG_SIZE); - parm->bIPTransChkVerDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_CHKVER_SHIFT, - PMAC_CTRL_0_CHKVER_SIZE); - parm->bProcFlagsEgCfgEna = gsw_field_r32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_FLAGEN_SIZE); - regval = gsw_field_r32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, - PMAC_CTRL_3_JUMBO_SIZE); - parm->nMaxJumboLen = regval; - } - - parm->bJumboEna = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, - PMAC_CTRL_2_MLEN_SIZE); - parm->bLongFrmChkDis = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_LCHKL_SHIFT, - PMAC_CTRL_2_LCHKL_SIZE); - regval = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, - PMAC_CTRL_2_LCHKS_SIZE); - parm->eShortFrmChkType = regval; - - - if (gswdev->gipver == LTQ_GSWIP_3_1) - { - gsw_r32_raw(cdev, (PMAC_CTRL_1_MLEN_OFFSET + (parm->nPmacId * 0x80)), ®val); - parm->nMaxJumboLen = regval; - - parm->eProcFlagsEgCfg = gsw_field_r32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE); + if (IS_VRSN_31(gswdev->gipver)) + pmac_ctrl1 = gsw_field_w32(pmac_ctrl1, PMAC_CTRL_1_MLEN_SHIFT, + PMAC_CTRL_1_MLEN_SIZE, parm->nMaxJumboLen); - gsw_r32(cdev, (PMAC_BSL_LEN0_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN0_SHIFT, PMAC_BSL_LEN0_SIZE, &parm->nBslThreshold[0]); + if (gswdev->gipver == LTQ_GSWIP_3_0) + pmac_ctrl3 = gsw_field_w32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, + PMAC_CTRL_3_JUMBO_SIZE, parm->nMaxJumboLen); + } else { + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, + PMAC_CTRL_2_MLEN_SIZE, 0); - gsw_r32(cdev, (PMAC_BSL_LEN1_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN1_SHIFT, PMAC_BSL_LEN1_SIZE, &parm->nBslThreshold[1]); + if (gswdev->gipver == LTQ_GSWIP_3_0) + pmac_ctrl3 = gsw_field_w32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, + PMAC_CTRL_3_JUMBO_SIZE, 0x8F8); + } - gsw_r32(cdev, (PMAC_BSL_LEN2_OFFSET + (parm->nPmacId * 0x80)), - PMAC_BSL_LEN2_SHIFT, PMAC_BSL_LEN2_SIZE, &parm->nBslThreshold[2]); - } - } - return 0; -} + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKL_SHIFT, + PMAC_CTRL_2_LCHKL_SIZE, parm->bLongFrmChkDis); -int xwayflow_pmac_table_read(void *cdev, pmtbl_prog_t *ptdata) -{ - u32 value; - CHECK_BUSY((PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT,PMAC_TBL_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); - gsw_w32(cdev, (PMAC_TBL_ADDR_ADDR_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_ADDR_ADDR_SHIFT, - PMAC_TBL_ADDR_ADDR_SIZE, ptdata->ptaddr); - gsw_w32(cdev, (PMAC_TBL_CTRL_ADDR_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_ADDR_SHIFT, - PMAC_TBL_CTRL_ADDR_SIZE, ptdata->ptcaddr); - gsw_w32(cdev, (PMAC_TBL_CTRL_OPMOD_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_OPMOD_SHIFT, - PMAC_TBL_CTRL_OPMOD_SIZE, 0 /* ptdata->op_mode */); - gsw_w32(cdev, (PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT, - PMAC_TBL_CTRL_BAS_SIZE, 1); - CHECK_BUSY((PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT,PMAC_TBL_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); - gsw_r32(cdev, (PMAC_TBL_VAL_4_VAL4_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_4_VAL4_SHIFT, - PMAC_TBL_VAL_4_VAL4_SIZE, &value); - ptdata->val[4] = value; - gsw_r32(cdev, (PMAC_TBL_VAL_3_VAL3_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_3_VAL3_SHIFT, - PMAC_TBL_VAL_3_VAL3_SIZE, &value); - ptdata->val[3] = value; - gsw_r32(cdev, (PMAC_TBL_VAL_2_VAL2_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_2_VAL2_SHIFT, - PMAC_TBL_VAL_2_VAL2_SIZE, &value); - ptdata->val[2] = value; - gsw_r32(cdev, (PMAC_TBL_VAL_1_VAL1_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_1_VAL1_SHIFT, - PMAC_TBL_VAL_1_VAL1_SIZE, &value); - ptdata->val[1] = value; - gsw_r32(cdev, (PMAC_TBL_VAL_0_VAL0_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_0_VAL0_SHIFT, - PMAC_TBL_VAL_0_VAL0_SIZE, &value); - ptdata->val[0] = value; - return 0; + switch (parm->eShortFrmChkType) { + case GSW_PMAC_SHORT_LEN_DIS: + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, + PMAC_CTRL_2_LCHKS_SIZE, 0); + break; + + case GSW_PMAC_SHORT_LEN_ENA_UNTAG: + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, + PMAC_CTRL_2_LCHKS_SIZE, 1); + break; + + case GSW_PMAC_SHORT_LEN_ENA_TAG: + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, + PMAC_CTRL_2_LCHKS_SIZE, 2); + break; + + case GSW_PMAC_SHORT_LEN_RESERVED: + pmac_ctrl2 = gsw_field_w32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, + PMAC_CTRL_2_LCHKS_SIZE, 3); + break; + } + + if (IS_VRSN_31(gswdev->gipver)) { + switch (parm->eProcFlagsEgCfg) { + case GSW_PMAC_PROC_FLAGS_NONE: + break; + + case GSW_PMAC_PROC_FLAGS_TC: + pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 0); + break; + + case GSW_PMAC_PROC_FLAGS_FLAG: + pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 1); + break; + + case GSW_PMAC_PROC_FLAGS_MIX: + pmac_ctrl4 = gsw_field_w32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, 2); + break; + } + + if (parm->nBslThreshold[0]) { + gsw_w32(cdev, pmac_bsl1_off, + PMAC_BSL_LEN0_SHIFT, + PMAC_BSL_LEN0_SIZE, + parm->nBslThreshold[0]); + } + + if (parm->nBslThreshold[1]) { + gsw_w32(cdev, pmac_bsl2_off, + PMAC_BSL_LEN1_SHIFT, + PMAC_BSL_LEN1_SIZE, + parm->nBslThreshold[1]); + } + + if (parm->nBslThreshold[2]) { + gsw_w32(cdev, pmac_bsl3_off, + PMAC_BSL_LEN2_SHIFT, + PMAC_BSL_LEN2_SIZE, + parm->nBslThreshold[2]); + } + } + + gsw_w32_raw(cdev, pmac_ctrl0_off, pmac_ctrl0); + + if (IS_VRSN_31(gswdev->gipver)) + gsw_w32_raw(cdev, pmac_ctrl1_off, pmac_ctrl1); + + gsw_w32_raw(cdev, pmac_ctrl2_off, pmac_ctrl2); + gsw_w32_raw(cdev, pmac_ctrl3_off, pmac_ctrl3); + gsw_w32_raw(cdev, pmac_ctrl4_off, pmac_ctrl4); + } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; } -int xwayflow_pmac_table_write(void *cdev, pmtbl_prog_t *ptdata) +GSW_return_t GSW_PMAC_GLBL_CfgGet(void *cdev, GSW_PMAC_Glbl_Cfg_t *parm) { - CHECK_BUSY((PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT,PMAC_TBL_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); - gsw_w32(cdev, (PMAC_TBL_ADDR_ADDR_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_ADDR_ADDR_SHIFT, - PMAC_TBL_ADDR_ADDR_SIZE, ptdata->ptaddr); - gsw_w32(cdev, (PMAC_TBL_CTRL_ADDR_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_ADDR_SHIFT, - PMAC_TBL_CTRL_ADDR_SIZE, ptdata->ptcaddr); - gsw_w32(cdev, (PMAC_TBL_CTRL_OPMOD_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_OPMOD_SHIFT, - PMAC_TBL_CTRL_OPMOD_SIZE, 1 /* ptdata->op_mode */); - gsw_w32(cdev, (PMAC_TBL_VAL_4_VAL4_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_4_VAL4_SHIFT, - PMAC_TBL_VAL_4_VAL4_SIZE, ptdata->val[4]); - gsw_w32(cdev, (PMAC_TBL_VAL_3_VAL3_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_3_VAL3_SHIFT, - PMAC_TBL_VAL_3_VAL3_SIZE, ptdata->val[3]); - gsw_w32(cdev, (PMAC_TBL_VAL_2_VAL2_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_2_VAL2_SHIFT, - PMAC_TBL_VAL_2_VAL2_SIZE, ptdata->val[2]); - gsw_w32(cdev, (PMAC_TBL_VAL_1_VAL1_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_1_VAL1_SHIFT, - PMAC_TBL_VAL_1_VAL1_SIZE, ptdata->val[1]); - gsw_w32(cdev, (PMAC_TBL_VAL_0_VAL0_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_VAL_0_VAL0_SHIFT, - PMAC_TBL_VAL_0_VAL0_SIZE, ptdata->val[0]); - gsw_w32(cdev, (PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT, - PMAC_TBL_CTRL_BAS_SIZE, 1); - CHECK_BUSY((PMAC_TBL_CTRL_BAS_OFFSET + (ptdata->pmacId * 0x80)), - PMAC_TBL_CTRL_BAS_SHIFT,PMAC_TBL_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); - - return 0; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 regval; + u32 pmac_ctrl0, pmac_ctrl1, pmac_ctrl2, pmac_ctrl3, pmac_ctrl4; + u32 pmac_ctrl0_off, + pmac_ctrl1_off, + pmac_ctrl2_off, + pmac_ctrl3_off, + pmac_ctrl4_off, + pmac_bsl1_off, + pmac_bsl2_off, + pmac_bsl3_off; + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + pmac_ctrl0_off = pmac_addr_off(PMAC_CTRL_0_PADEN_OFFSET, parm->nPmacId); + pmac_ctrl1_off = pmac_addr_off(PMAC_CTRL_1_MLEN_OFFSET, parm->nPmacId); + pmac_ctrl2_off = pmac_addr_off(PMAC_CTRL_2_LCHKL_OFFSET, parm->nPmacId); + pmac_ctrl3_off = pmac_addr_off(PMAC_CTRL_3_JUMBO_OFFSET, parm->nPmacId); + pmac_ctrl4_off = pmac_addr_off(PMAC_CTRL_4_FLAGEN_OFFSET, parm->nPmacId); + + pmac_bsl1_off = pmac_addr_off(PMAC_BSL_LEN0_OFFSET, parm->nPmacId); + pmac_bsl2_off = pmac_addr_off(PMAC_BSL_LEN1_OFFSET, parm->nPmacId); + pmac_bsl3_off = pmac_addr_off(PMAC_BSL_LEN2_OFFSET, parm->nPmacId); + + + gsw_r32_raw(cdev, pmac_ctrl0_off, &pmac_ctrl0); + + if (IS_VRSN_31(gswdev->gipver)) + gsw_r32_raw(cdev, pmac_ctrl1_off, &pmac_ctrl1); + + gsw_r32_raw(cdev, pmac_ctrl2_off, &pmac_ctrl2); + gsw_r32_raw(cdev, pmac_ctrl3_off, &pmac_ctrl3); + gsw_r32_raw(cdev, pmac_ctrl4_off, &pmac_ctrl4); + + + if (IS_VRSN_30_31(gswdev->gipver)) { + + parm->bAPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_APADEN_SHIFT, + PMAC_CTRL_0_APADEN_SIZE); + parm->bPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_PADEN_SHIFT, + PMAC_CTRL_0_PADEN_SIZE); + parm->bVPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_VPADEN_SHIFT, + PMAC_CTRL_0_VPADEN_SIZE); + parm->bSVPadEna = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_VPAD2EN_SHIFT, + PMAC_CTRL_0_VPAD2EN_SIZE); + parm->bTxFCSDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_FCS_SHIFT, + PMAC_CTRL_0_FCS_SIZE); + + if (IS_VRSN_31(gswdev->gipver)) { + parm->bRxFCSDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_FCSEN_SHIFT, + PMAC_CTRL_0_FCSEN_SIZE); + } + + if (gswdev->gipver == LTQ_GSWIP_3_0) { + parm->bIPTransChkRegDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_CHKREG_SHIFT, + PMAC_CTRL_0_CHKREG_SIZE); + parm->bIPTransChkVerDis = gsw_field_r32(pmac_ctrl0, PMAC_CTRL_0_CHKVER_SHIFT, + PMAC_CTRL_0_CHKVER_SIZE); + parm->bProcFlagsEgCfgEna = gsw_field_r32(pmac_ctrl4, PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_FLAGEN_SIZE); + regval = gsw_field_r32(pmac_ctrl3, PMAC_CTRL_3_JUMBO_SHIFT, + PMAC_CTRL_3_JUMBO_SIZE); + parm->nMaxJumboLen = regval; + } + + parm->bJumboEna = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_MLEN_SHIFT, + PMAC_CTRL_2_MLEN_SIZE); + parm->bLongFrmChkDis = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_LCHKL_SHIFT, + PMAC_CTRL_2_LCHKL_SIZE); + regval = gsw_field_r32(pmac_ctrl2, PMAC_CTRL_2_LCHKS_SHIFT, + PMAC_CTRL_2_LCHKS_SIZE); + parm->eShortFrmChkType = regval; + + + if (IS_VRSN_31(gswdev->gipver)) { + gsw_r32_raw(cdev, pmac_ctrl1_off, ®val); + + parm->nMaxJumboLen = regval; + + parm->eProcFlagsEgCfg = gsw_field_r32(pmac_ctrl4, + PMAC_CTRL_4_FLAGEN_SHIFT, + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE); + + gsw_r32(cdev, + pmac_bsl1_off, + PMAC_BSL_LEN0_SHIFT, + PMAC_BSL_LEN0_SIZE, + &parm->nBslThreshold[0]); + + gsw_r32(cdev, + pmac_bsl2_off, + PMAC_BSL_LEN1_SHIFT, + PMAC_BSL_LEN1_SIZE, + &parm->nBslThreshold[1]); + + gsw_r32(cdev, + pmac_bsl3_off, + PMAC_BSL_LEN2_SHIFT, + PMAC_BSL_LEN2_SIZE, + &parm->nBslThreshold[2]); + } + } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; } + /* Back pressure mapping Table */ int GSW_PMAC_BM_CfgSet(void *cdev, GSW_PMAC_BM_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); - - if(gswdev->gipver == LTQ_GSWIP_3_0) + + if (gswdev->gipver == LTQ_GSWIP_3_0) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x0F); - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x1F); pmtbl.pmacId = parm->nPmacId; @@ -12521,32 +16157,45 @@ int GSW_PMAC_BM_CfgSet(void *cdev, GSW_PMAC_BM_Cfg_t *parm) /* TX Queue Congestion Mask (bit 31:16) */ pmtbl.val[2] = ((parm->txQMask >> 16) & 0xFFFF); pmtbl.ptcaddr = PMAC_BPMAP_INDEX; - + xwayflow_pmac_table_write(cdev, &pmtbl); } - return 0; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; + } int GSW_PMAC_BM_CfgGet(void *cdev, GSW_PMAC_BM_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); - if(gswdev->gipver == LTQ_GSWIP_3_0) + if (gswdev->gipver == LTQ_GSWIP_3_0) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x0F); - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x1F); pmtbl.pmacId = parm->nPmacId; - + pmtbl.ptcaddr = PMAC_BPMAP_INDEX; xwayflow_pmac_table_read(cdev, &pmtbl); @@ -12558,37 +16207,49 @@ int GSW_PMAC_BM_CfgGet(void *cdev, GSW_PMAC_BM_Cfg_t *parm) parm->txQMask |= (pmtbl.val[2]) << 16; } - return 0; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; } int GSW_PMAC_IG_CfgSet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); pmtbl.pmacId = parm->nPmacId; - - if(gswdev->gipver == LTQ_GSWIP_3_0) + + if (gswdev->gipver == LTQ_GSWIP_3_0) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x0F); - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x1F); /* Default PMAC Header Bytes */ pmtbl.val[0] = (((parm->defPmacHdr[0] & 0xFF) << 8) - | (parm->defPmacHdr[1] & 0xFF)); + | (parm->defPmacHdr[1] & 0xFF)); pmtbl.val[1] = (((parm->defPmacHdr[2] & 0xFF) << 8) - | (parm->defPmacHdr[3] & 0xFF)); + | (parm->defPmacHdr[3] & 0xFF)); pmtbl.val[2] = (((parm->defPmacHdr[4] & 0xFF) << 8) - | (parm->defPmacHdr[5] & 0xFF)); + | (parm->defPmacHdr[5] & 0xFF)); pmtbl.val[3] = (((parm->defPmacHdr[6] & 0xFF) << 8) - | (parm->defPmacHdr[7] & 0xFF)); + | (parm->defPmacHdr[7] & 0xFF)); /* Packet has PMAC header or not */ if (parm->bPmacPresent) @@ -12621,14 +16282,15 @@ int GSW_PMAC_IG_CfgSet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) if (parm->bClassEna) pmtbl.val[4] |= (1 << 3); - if(gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { /* Port Map Enable info from default PMAC header */ if (parm->bPmapEna) pmtbl.val[4] |= (1 << 4); - /* Port Map info from default PMAC header */ - if (parm->bPmapDefault) - pmtbl.val[4] |= (1 << 6); - } + + /* Port Map info from default PMAC header */ + if (parm->bPmapDefault) + pmtbl.val[4] |= (1 << 6); + } /* Class Info from default PMAC header */ if (parm->bClassDefault) @@ -12643,7 +16305,13 @@ int GSW_PMAC_IG_CfgSet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) xwayflow_pmac_table_write(cdev, &pmtbl); } - return 0; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; + } @@ -12651,20 +16319,27 @@ int GSW_PMAC_IG_CfgGet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; - u32 SubidMode; + u32 SubidMode; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); pmtbl.pmacId = parm->nPmacId; - - if(gswdev->gipver == LTQ_GSWIP_3_0) + + if (gswdev->gipver == LTQ_GSWIP_3_0) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x0F); - if(gswdev->gipver == LTQ_GSWIP_3_1) + + if (IS_VRSN_31(gswdev->gipver)) pmtbl.ptaddr = (parm->nTxDmaChanId & 0x1F); pmtbl.ptcaddr = PMAC_IGCFG_INDEX; @@ -12690,10 +16365,11 @@ int GSW_PMAC_IG_CfgGet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) /* Sub_Interface Id Info */ SubidMode = ((pmtbl.val[4] >> 2) & 0x1); + if (SubidMode == 0) { parm->eSubId = GSW_PMAC_IG_CFG_SRC_DMA_DESC; } else { - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { parm->eSubId = GSW_PMAC_IG_CFG_SRC_DEF_PMAC; } else { parm->eSubId = GSW_PMAC_IG_CFG_SRC_PMAC; @@ -12704,14 +16380,15 @@ int GSW_PMAC_IG_CfgGet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) if ((pmtbl.val[4] >> 3) & 0x1) parm->bClassEna = 1; - if(gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { /* Port Map Enable info from default PMAC header */ if ((pmtbl.val[4] >> 4) & 0x1) parm->bPmapEna = 1; - /* Port Map info from default PMAC header */ - if ((pmtbl.val[4] >> 6) & 0x1) - parm->bPmapDefault = 1; - } + + /* Port Map info from default PMAC header */ + if ((pmtbl.val[4] >> 6) & 0x1) + parm->bPmapDefault = 1; + } /* Class Info from default PMAC header */ if ((pmtbl.val[4] >> 5) & 0x1) @@ -12721,107 +16398,132 @@ int GSW_PMAC_IG_CfgGet(void *cdev, GSW_PMAC_Ig_Cfg_t *parm) if ((pmtbl.val[4] >> 7) & 0x1) parm->bErrPktsDisc = 1; } - return 0; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; } int GSW_PMAC_EG_CfgSet(void *cdev, GSW_PMAC_Eg_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; - u32 regval; + u32 regval, pmac_ctrl4_off; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + pmac_ctrl4_off = pmac_addr_off(PMAC_CTRL_4_FLAGEN_OFFSET, parm->nPmacId); + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); pmtbl.pmacId = parm->nPmacId; - + pmtbl.ptaddr = parm->nDestPortId & 0x0F; pmtbl.ptaddr |= (parm->nFlowIDMsb & 0x03) << 8; - + if (gswdev->gipver == LTQ_GSWIP_3_0) { - gsw_r32(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)) , + gsw_r32(cdev, pmac_ctrl4_off, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_FLAGEN_SIZE, ®val); - } - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_r32(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), + PMAC_CTRL_4_FLAGEN_SIZE, + ®val); + } + + if (IS_VRSN_31(gswdev->gipver)) { + gsw_r32(cdev, pmac_ctrl4_off, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, ®val); - } + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, + ®val); + } /*if (parm->bTCEnable == 1) { */ if ((parm->bProcFlagsSelect == 0) && (regval == 0)) { - /*regval 00 tc use traffic class as part of the adress - (bit 7 to bit 4)*/ - + /*regval 00 tc use traffic class as part of the adress + (bit 7 to bit 4)*/ + pmtbl.ptaddr |= (parm->nTrafficClass & 0x0F) << 4; } else if ((parm->bProcFlagsSelect == 1) && (regval == 1)) { - /* regval 01 Flag use processing flags as part of the address - (bit 7 to bit 4)*/ - + /* regval 01 Flag use processing flags as part of the address + (bit 7 to bit 4)*/ + /* MPE-1 Marked Flag */ if (parm->bMpe1Flag) pmtbl.ptaddr |= (1 << 4); + /* MPE-2 Marked Flag */ if (parm->bMpe2Flag) pmtbl.ptaddr |= (1 << 5); + /* Cryptography Encryption Action Flag */ if (parm->bEncFlag) pmtbl.ptaddr |= (1 << 6); + /* Cryptography Decryption Action Flag */ if (parm->bDecFlag) pmtbl.ptaddr |= (1 << 7); } else if ((parm->bProcFlagsSelect == 1) && (regval == 2) && - (gswdev->gipver == LTQ_GSWIP_3_1)) { - /*regval 10 Mixed use MPE flags as part of the address (bit 5 to 4) - and reduced traffic class as part of the address - (bit 7 to bit 6)*/ - + (IS_VRSN_31(gswdev->gipver))) { + /*regval 10 Mixed use MPE flags as part of the address (bit 5 to 4) + and reduced traffic class as part of the address + (bit 7 to bit 6)*/ + pmtbl.ptaddr |= (parm->nTrafficClass & 0x3) << 6; - /* MPE-1 Marked Flag */ + + /* MPE-1 Marked Flag */ if (parm->bMpe1Flag) pmtbl.ptaddr |= (1 << 4); - /* MPE-2 Marked Flag */ + + /* MPE-2 Marked Flag */ if (parm->bMpe2Flag) pmtbl.ptaddr |= (1 << 5); - } else { - return GSW_statusNoSupport; + } else { + ret = GSW_statusNoSupport; + goto UNLOCK_AND_RETURN; } - + if (gswdev->gipver == LTQ_GSWIP_3_0) { /*nRes2DW0 -- DW0 (bit 14 to 13),*/ /*nRes1DW0 -- DW0 (bit 31 to 29), nResDW1 -- DW1 (bit 7 to 4)*/ - pmtbl.val[0] = ((parm->nRes2DW0 & 0x3) | ((parm->nRes1DW0 & 0x3) << 2) - | ((parm->nResDW1 & 0x0F) << 5)); - } - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - if(parm->bRes1DW0Enable) { - /*nRes1DW0 -- DW0 (bit 31 to 29)*/ - pmtbl.val[0] &= ~(0x7 << 2); + pmtbl.val[0] = ((parm->nRes2DW0 & 0x3) | + ((parm->nRes1DW0 & 0x3) << 2) | + ((parm->nResDW1 & 0x0F) << 5)); + } + + if (IS_VRSN_31(gswdev->gipver)) { + /*DES RES DW) Bit 31 (For Redir bit set) BIT 4 of VAL 0*/ + if (parm->bRedirEnable) + pmtbl.val[0] |= (1 << 4); + + /* Redirection bit can be overwritten by nRes1DW0 */ + if (parm->bRes1DW0Enable) { + /*nRes1DW0 -- DW0 (bit 31 to 29)*/ + pmtbl.val[0] &= ~(0x7 << 2); pmtbl.val[0] |= ((parm->nRes1DW0 & 0x7) << 2); - } else { - if(parm->bRedirEnable) - /*DES RES DW) Bit 31 (For Redir bit set) BIT 4 of VAL 0*/ - pmtbl.val[0] |= (1 << 4); - } - - if(parm->bRes2DW0Enable) { - /*nRes2DW0 -- DW0 (bit 14 to 13),*/ - pmtbl.val[0] &= ~(0x3); + } + + if (parm->bRes2DW0Enable) { + /*nRes2DW0 -- DW0 (bit 14 to 13),*/ + pmtbl.val[0] &= ~(0x3); pmtbl.val[0] |= (parm->nRes2DW0 & 0x3); } - /*BSL Bit 2 to 0 -- VLA 0 BIT 7:5*/ + + /*BSL Bit 2 to 0 -- VLA 0 BIT 7:5*/ pmtbl.val[0] |= ((parm->nBslTrafficClass & 0x3) << 5); - pmtbl.val[0] |= (parm->bBslSegmentDisable << 7); - } - + pmtbl.val[0] |= (parm->bBslSegmentDisable << 7); + } + /* Receive DMA Channel Identifier (0..7) */ pmtbl.val[1] = (parm->nRxDmaChanId & 0x0F); @@ -12836,94 +16538,123 @@ int GSW_PMAC_EG_CfgSet(void *cdev, GSW_PMAC_Eg_Cfg_t *parm) /* To remove L2 header & additional bytes */ if (parm->bRemL2Hdr == 1) { pmtbl.val[2] |= (1 << 2); - /* No. of bytes to be removed after Layer-2 Header,*/ + /* No. of bytes to be removed after Layer-2 Header,*/ /*valid when bRemL2Hdr is set */ pmtbl.val[2] |= ((parm->numBytesRem & 0xFF) << 8); } + pmtbl.ptcaddr = PMAC_EGCFG_INDEX; xwayflow_pmac_table_write(cdev, &pmtbl); } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; + } int GSW_PMAC_EG_CfgGet(void *cdev, GSW_PMAC_Eg_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pmtbl_prog_t pmtbl; - u32 regval; + u32 regval, pmac_ctrl4_off; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + + pmac_ctrl4_off = pmac_addr_off(PMAC_CTRL_4_FLAGEN_OFFSET, parm->nPmacId); + + if (IS_VRSN_30_31(gswdev->gipver)) { memset(&pmtbl, 0, sizeof(pmtbl)); pmtbl.pmacId = parm->nPmacId; - + pmtbl.ptaddr = parm->nDestPortId & 0x0F; pmtbl.ptaddr |= (parm->nFlowIDMsb & 0x03) << 8; - if (gswdev->gipver == LTQ_GSWIP_3_0) { - gsw_r32(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), + if (gswdev->gipver == LTQ_GSWIP_3_0) { + gsw_r32(cdev, pmac_ctrl4_off, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_FLAGEN_SIZE, ®val); - } - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_r32(cdev, (PMAC_CTRL_4_FLAGEN_OFFSET + (parm->nPmacId * 0x80)), + PMAC_CTRL_4_FLAGEN_SIZE, + ®val); + } + + if (IS_VRSN_31(gswdev->gipver)) { + gsw_r32(cdev, pmac_ctrl4_off, PMAC_CTRL_4_FLAGEN_SHIFT, - PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, ®val); - } - - -/* if (parm->bTCEnable == 1) { */ + PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE, + ®val); + } + + + /* if (parm->bTCEnable == 1) { */ if ((parm->bProcFlagsSelect == 0) && (regval == 0)) { pmtbl.ptaddr |= (parm->nTrafficClass & 0x0F) << 4; } else if ((parm->bProcFlagsSelect == 1) && (regval == 1)) { /* MPE-1 Marked Flag */ if (parm->bMpe1Flag) pmtbl.ptaddr |= (1 << 4); + /* MPE-2 Marked Flag */ if (parm->bMpe2Flag) pmtbl.ptaddr |= (1 << 5); + /* Cryptography Encryption Action Flag */ if (parm->bEncFlag) pmtbl.ptaddr |= (1 << 6); + /* Cryptography Decryption Action Flag */ if (parm->bDecFlag) pmtbl.ptaddr |= (1 << 7); } else if ((parm->bProcFlagsSelect == 1) && (regval == 2) && - (gswdev->gipver == LTQ_GSWIP_3_1)) { - pmtbl.ptaddr |= (parm->nTrafficClass & 0x3) << 6; - /* MPE-1 Marked Flag */ + (IS_VRSN_31(gswdev->gipver))) { + pmtbl.ptaddr |= (parm->nTrafficClass & 0x3) << 6; + + /* MPE-1 Marked Flag */ if (parm->bMpe1Flag) pmtbl.ptaddr |= (1 << 4); - /* MPE-2 Marked Flag */ + + /* MPE-2 Marked Flag */ if (parm->bMpe2Flag) pmtbl.ptaddr |= (1 << 5); - } else { - return GSW_statusNoSupport; + } else { + ret = GSW_statusNoSupport; + goto UNLOCK_AND_RETURN; } + pmtbl.ptcaddr = PMAC_EGCFG_INDEX; xwayflow_pmac_table_read(cdev, &pmtbl); + /* nRes2DW0 -- DW0 (bit 14 to 13),*/ /*nRes1DW0 -- DW0 (bit 31 to 29), nResDW1 -- DW1 (bit 7 to 4)*/ if (gswdev->gipver == LTQ_GSWIP_3_0) { - parm->nRes2DW0 = pmtbl.val[0] & 0x3; - parm->nRes1DW0 = (pmtbl.val[0] >> 2) & 0x3; + parm->nRes2DW0 = pmtbl.val[0] & 0x3; + parm->nRes1DW0 = (pmtbl.val[0] >> 2) & 0x3; parm->nResDW1 = (pmtbl.val[0] >> 5) & 0x0F; } - if(gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_31(gswdev->gipver)) { /*Redir bit set*/ - parm->nRes2DW0 = pmtbl.val[0] & 0x3; - parm->nRes1DW0 = ((pmtbl.val[0] >> 2) & 0x7); - parm->bRedirEnable = ((pmtbl.val[0] & 0x10) >> 4); - - parm->nBslTrafficClass= ((pmtbl.val[0] & 0x60) >> 5); - parm->bBslSegmentDisable= ((pmtbl.val[0] & 0x80) >> 7); - } - + parm->nRes2DW0 = pmtbl.val[0] & 0x3; + parm->nRes1DW0 = ((pmtbl.val[0] >> 2) & 0x7); + parm->bRedirEnable = ((pmtbl.val[0] & 0x10) >> 4); + + parm->nBslTrafficClass = ((pmtbl.val[0] & 0x60) >> 5); + parm->bBslSegmentDisable = ((pmtbl.val[0] & 0x80) >> 7); + } + /* Receive DMA Channel Identifier (0..7) */ parm->nRxDmaChanId = (pmtbl.val[1] & 0x0F); @@ -12938,12 +16669,20 @@ int GSW_PMAC_EG_CfgGet(void *cdev, GSW_PMAC_Eg_Cfg_t *parm) /* To remove L2 header & additional bytes */ if ((pmtbl.val[2] >> 2) & 0x1) { parm->bRemL2Hdr = 1; - /* No. of bytes to be removed after Layer-2 Header */ - /* valid when bRemL2Hdr is set */ + /* No. of bytes to be removed after Layer-2 Header */ + /* valid when bRemL2Hdr is set */ parm->numBytesRem = ((pmtbl.val[2] >> 8) & 0xFF); } } - return 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + return ret; } #if defined(CONFIG_LTQ_8021X) && CONFIG_LTQ_8021X @@ -12951,26 +16690,42 @@ GSW_return_t GSW_8021X_EAPOL_RuleGet(void *cdev, GSW_8021X_EAPOL_Rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); stp8021x_t *scfg = &gswdev->stpconfig; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif parm->eForwardPort = scfg->sfport; parm->nForwardPortId = scfg->fpid8021x; - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_8021X_EAPOL_RuleSet(void *cdev, GSW_8021X_EAPOL_Rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); stp8021x_t *scfg = &gswdev->stpconfig; - GSW_PCE_rule_t pcrule; + static GSW_PCE_rule_t pcrule; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + scfg->sfport = parm->eForwardPort; scfg->fpid8021x = parm->nForwardPortId; memset(&pcrule, 0, sizeof(GSW_PCE_rule_t)); @@ -12987,106 +16742,175 @@ GSW_return_t GSW_8021X_EAPOL_RuleSet(void *cdev, GSW_8021X_EAPOL_Rule_t *parm) pcrule.pattern.bEtherTypeEnable = 1; pcrule.pattern.nEtherType = 0x888E; pcrule.action.eCrossStateAction = GSW_PCE_ACTION_CROSS_STATE_CROSS; + if ((scfg->sfport < 4) && (scfg->sfport > 0)) pcrule.action.ePortMapAction = scfg->sfport + 1; else pr_err("(Incorrect forward port action) %s:%s:%d\n", - __FILE__, __func__, __LINE__); - /*TODO*/ + __FILE__, __func__, __LINE__); + + /*TODO*/ //Govind - Can occur out of array bounds problem. - pcrule.action.nForwardPortMap[0]= (1 << parm->nForwardPortId); - + pcrule.action.nForwardPortMap[0] = (1 << parm->nForwardPortId); + /* We prepare everything and write into PCE Table */ - if (0 != pce_rule_write(cdev, &gswdev->phandler, &pcrule)) - return GSW_statusErr; - return GSW_statusOk; + if (0 != pce_rule_write(cdev, &gswdev->phandler, &pcrule)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } GSW_return_t GSW_8021X_PortCfgGet(void *cdev, GSW_8021X_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; port_config_t *pcfg; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - - pcfg = &gswdev->pconfig[parm->nPortId]; - parm->eState = pcfg->p8021xs; - } - if(gswdev->gipver == LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->num_of_bridge_port) - return GSW_statusErr; - /*If Bridge Port ID is valid,Check whether it is InUSE - if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) - return GSW_statusErr; - - parm->eState = gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState; - } - return GSW_statusOk; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + pcfg = &gswdev->pconfig[parm->nPortId]; + parm->eState = pcfg->p8021xs; + } + + if (IS_VRSN_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->num_of_bridge_port) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If Bridge Port ID is valid,Check whether it is InUSE + if not InUse,return ERROR*/ + if (!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + parm->eState = gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState; + } + + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + + } GSW_return_t GSW_8021X_PortCfgSet(void *cdev, GSW_8021X_portCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 StpState,P8021xState; + u8 StpState, P8021xState; + u32 ret; port_config_t *pcfg; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(gswdev->gipver != LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; - - pcfg = &gswdev->pconfig[parm->nPortId]; - pcfg->p8021xs = parm->eState; - set_port_state(cdev, parm->nPortId, pcfg->pcstate, - pcfg->p8021xs); - } - - if(gswdev->gipver == LTQ_GSWIP_3_1) { - if (parm->nPortId >= gswdev->num_of_bridge_port) - return GSW_statusErr; - /*If Bridge Port ID is valid,Check whether it is InUSE - if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) - return GSW_statusErr; - - P8021xState = parm->eState; - StpState = gswdev->brdgeportconfig_idx[parm->nPortId].StpState; - gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState=P8021xState; - - /* Config the Table */ - set_port_state(cdev, parm->nPortId, StpState, P8021xState); - } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif - return GSW_statusOk; -} + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } -#endif /*CONFIG_LTQ_8021X */ -GSW_return_t GSW_CPU_PortCfgGet(void *cdev, GSW_CPU_PortCfg_t *parm) -{ - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 pidx = parm->nPortId; + pcfg = &gswdev->pconfig[parm->nPortId]; + pcfg->p8021xs = parm->eState; + set_port_state(cdev, parm->nPortId, pcfg->pcstate, + pcfg->p8021xs); + } + + if (IS_VRSN_31(gswdev->gipver)) { + if (parm->nPortId >= gswdev->num_of_bridge_port) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If Bridge Port ID is valid,Check whether it is InUSE + if not InUse,return ERROR*/ + if (!(gswdev->brdgeportconfig_idx[parm->nPortId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + P8021xState = parm->eState; + StpState = gswdev->brdgeportconfig_idx[parm->nPortId].StpState; + gswdev->brdgeportconfig_idx[parm->nPortId].P8021xState = P8021xState; + + /* Config the Table */ + set_port_state(cdev, parm->nPortId, StpState, P8021xState); + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} + +#endif /*CONFIG_LTQ_8021X */ +GSW_return_t GSW_CPU_PortCfgGet(void *cdev, GSW_CPU_PortCfg_t *parm) +{ + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u8 pidx = parm->nPortId; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (pidx == gswdev->cport) parm->bCPU_PortValid = 1; else parm->bCPU_PortValid = 0; + /* Special Tag Egress*/ gsw_r32(cdev, (FDMA_PCTRL_STEN_OFFSET + (0x6 * pidx)), FDMA_PCTRL_STEN_SHIFT, FDMA_PCTRL_STEN_SIZE, &value); @@ -13100,30 +16924,32 @@ GSW_return_t GSW_CPU_PortCfgGet(void *cdev, GSW_CPU_PortCfg_t *parm) SDMA_PCTRL_FCSIGN_SHIFT, SDMA_PCTRL_FCSIGN_SIZE, &value); parm->bFcsCheck = value; + /* FCS Generate */ - if (gswdev->gipver == LTQ_GSWIP_3_0 - || gswdev->gipver == LTQ_GSWIP_3_1) { - - if(gswdev->gipver == LTQ_GSWIP_3_0) { + if (IS_VRSN_30_31(gswdev->gipver)) { + + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (pidx != 0) { gsw_r32(cdev, (MAC_CTRL_0_FCS_OFFSET + (0xC * (pidx - 1))), MAC_CTRL_0_FCS_SHIFT, MAC_CTRL_0_FCS_SIZE, &value); parm->bFcsGenerate = value; } } - - if(gswdev->gipver == LTQ_GSWIP_3_1 ) - { - if((1<pidx) && (pidx<5)) - { + + if (IS_VRSN_31(gswdev->gipver)) { + if ((1 < pidx) && (pidx < 5)) { +#if defined(CONFIG_MAC) && CONFIG_MAC /* MAC API's to set FCS Generation */ struct mac_ops *ops = get_mac_ops(gswdev, pidx); - if(!ops) - { - pr_err("MAC %d is not initialized\n",pidx); - return GSW_statusErr; + + if (!ops) { + pr_err("MAC %d is not initialized\n", pidx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + parm->bFcsGenerate = ops->get_fcsgen(ops); +#endif } } @@ -13144,12 +16970,23 @@ GSW_return_t GSW_CPU_PortCfgGet(void *cdev, GSW_CPU_PortCfg_t *parm) MAC_CTRL_0_FCS_SHIFT, MAC_CTRL_0_FCS_SIZE, &value); parm->bFcsGenerate = value; } + if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_r32(cdev, (FDMA_PCTRL_ST_TYPE_OFFSET + (0x6 * pidx)), FDMA_PCTRL_ST_TYPE_SHIFT, FDMA_PCTRL_ST_TYPE_SIZE, &value); } + parm->bSpecialTagEthType = value; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + + } GSW_return_t GSW_CPU_PortCfgSet(void *cdev, GSW_CPU_PortCfg_t *parm) @@ -13157,44 +16994,63 @@ GSW_return_t GSW_CPU_PortCfgSet(void *cdev, GSW_CPU_PortCfg_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; u32 RST, AS, AST, RXSH; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (pidx == gswdev->cport) parm->bCPU_PortValid = 1; else parm->bCPU_PortValid = 0; + gswdev->mpnum = pidx; /* Special Tag Egress*/ gsw_w32(cdev, (FDMA_PCTRL_STEN_OFFSET + (0x6 * pidx)), FDMA_PCTRL_STEN_SHIFT, FDMA_PCTRL_STEN_SIZE, parm->bSpecialTagEgress); + /* xRX CPU port */ if ((pidx == gswdev->cport) && !(gswdev->gipver == LTQ_GSWIP_3_0)) { if (parm->bSpecialTagEgress == 0) { - RST = 1; AS = 0; + RST = 1; + AS = 0; } else { - RST = 0; AS = 1; + RST = 0; + AS = 1; } + gsw_w32(cdev, (PMAC_HD_CTL_RST_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_RST_SHIFT, PMAC_HD_CTL_RST_SIZE, RST); gsw_w32(cdev, (PMAC_HD_CTL_AS_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_AS_SHIFT, PMAC_HD_CTL_AS_SIZE, AS); } + /* Special Tag Igress*/ gsw_w32(cdev, (PCE_PCTRL_0_IGSTEN_OFFSET + (0xa * pidx)), PCE_PCTRL_0_IGSTEN_SHIFT, PCE_PCTRL_0_IGSTEN_SIZE, parm->bSpecialTagIngress); + if ((pidx == gswdev->cport) && !(gswdev->gipver == LTQ_GSWIP_3_0)) { if (parm->bSpecialTagIngress == 0) { - AST = 0; RXSH = 0; + AST = 0; + RXSH = 0; } else { - AST = 1; RXSH = 1; + AST = 1; + RXSH = 1; } + gsw_w32(cdev, (PMAC_HD_CTL_AST_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_AST_SHIFT, PMAC_HD_CTL_AST_SIZE, AST); gsw_w32(cdev, (PMAC_HD_CTL_RXSH_OFFSET + GSW_TREG_OFFSET), @@ -13203,106 +17059,127 @@ GSW_return_t GSW_CPU_PortCfgSet(void *cdev, GSW_CPU_PortCfg_t *parm) gsw_w32(cdev, (MAC_CTRL_0_FCS_OFFSET + (0xC * pidx)), MAC_CTRL_0_FCS_SHIFT, MAC_CTRL_0_FCS_SIZE, parm->bFcsGenerate); } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { + + if (IS_VRSN_30_31(gswdev->gipver)) { /* FCS Generate */ - if (gswdev->gipver == LTQ_GSWIP_3_0 ) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (pidx != 0) { gsw_w32(cdev, (MAC_CTRL_0_FCS_OFFSET + (0xC * (pidx - 1))), - MAC_CTRL_0_FCS_SHIFT, MAC_CTRL_0_FCS_SIZE, parm->bFcsGenerate); + MAC_CTRL_0_FCS_SHIFT, MAC_CTRL_0_FCS_SIZE, parm->bFcsGenerate); } } - if (gswdev->gipver == LTQ_GSWIP_3_1) { - if((1<pidx) && (pidx<5)) - { + if (IS_VRSN_31(gswdev->gipver)) { + if ((1 < pidx) && (pidx < 5)) { +#if defined(CONFIG_MAC) && CONFIG_MAC /* MAC API's to set FCS Generation */ struct mac_ops *ops = get_mac_ops(gswdev, pidx); - if(!ops) - { - pr_err("MAC %d is not initialized\n",pidx); - return GSW_statusErr; + + if (!ops) { + pr_err("MAC %d is not initialized\n", pidx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - ops->set_fcsgen(ops, 1); + + ops->set_fcsgen(ops, 1); +#endif } } - switch(parm->eNoMPEParserCfg) { + + switch (parm->eNoMPEParserCfg) { case GSW_CPU_PARSER_NIL: gsw_w32(cdev, FDMA_PASR_CPU_OFFSET, FDMA_PASR_CPU_SHIFT, FDMA_PASR_CPU_SIZE, 0); break; + case GSW_CPU_PARSER_FLAGS: gsw_w32(cdev, FDMA_PASR_CPU_OFFSET, FDMA_PASR_CPU_SHIFT, FDMA_PASR_CPU_SIZE, 1); break; + case GSW_CPU_PARSER_OFFSETS_FLAGS: gsw_w32(cdev, FDMA_PASR_CPU_OFFSET, FDMA_PASR_CPU_SHIFT, FDMA_PASR_CPU_SIZE, 2); break; + case GSW_CPU_PARSER_RESERVED: gsw_w32(cdev, FDMA_PASR_CPU_OFFSET, FDMA_PASR_CPU_SHIFT, FDMA_PASR_CPU_SIZE, 3); break; } - switch(parm->eMPE1ParserCfg) { + + switch (parm->eMPE1ParserCfg) { case GSW_CPU_PARSER_NIL: gsw_w32(cdev, FDMA_PASR_MPE1_OFFSET, FDMA_PASR_MPE1_SHIFT, FDMA_PASR_MPE1_SIZE, 0); break; + case GSW_CPU_PARSER_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE1_OFFSET, FDMA_PASR_MPE1_SHIFT, FDMA_PASR_MPE1_SIZE, 1); break; + case GSW_CPU_PARSER_OFFSETS_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE1_OFFSET, FDMA_PASR_MPE1_SHIFT, FDMA_PASR_MPE1_SIZE, 2); break; + case GSW_CPU_PARSER_RESERVED: gsw_w32(cdev, FDMA_PASR_MPE1_OFFSET, FDMA_PASR_MPE1_SHIFT, FDMA_PASR_MPE1_SIZE, 3); break; } - switch(parm->eMPE2ParserCfg) { + + switch (parm->eMPE2ParserCfg) { case GSW_CPU_PARSER_NIL: gsw_w32(cdev, FDMA_PASR_MPE2_OFFSET, FDMA_PASR_MPE2_SHIFT, FDMA_PASR_MPE2_SIZE, 0); break; + case GSW_CPU_PARSER_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE2_OFFSET, FDMA_PASR_MPE2_SHIFT, FDMA_PASR_MPE2_SIZE, 1); break; + case GSW_CPU_PARSER_OFFSETS_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE2_OFFSET, FDMA_PASR_MPE2_SHIFT, FDMA_PASR_MPE2_SIZE, 2); break; + case GSW_CPU_PARSER_RESERVED: gsw_w32(cdev, FDMA_PASR_MPE2_OFFSET, FDMA_PASR_MPE2_SHIFT, FDMA_PASR_MPE2_SIZE, 3); break; } - switch(parm->eMPE1MPE2ParserCfg) { + + switch (parm->eMPE1MPE2ParserCfg) { case GSW_CPU_PARSER_NIL: gsw_w32(cdev, FDMA_PASR_MPE3_OFFSET, FDMA_PASR_MPE3_SHIFT, FDMA_PASR_MPE3_SIZE, 0); break; + case GSW_CPU_PARSER_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE3_OFFSET, FDMA_PASR_MPE3_SHIFT, FDMA_PASR_MPE3_SIZE, 1); break; + case GSW_CPU_PARSER_OFFSETS_FLAGS: gsw_w32(cdev, FDMA_PASR_MPE3_OFFSET, FDMA_PASR_MPE3_SHIFT, FDMA_PASR_MPE3_SIZE, 2); break; + case GSW_CPU_PARSER_RESERVED: gsw_w32(cdev, FDMA_PASR_MPE3_OFFSET, FDMA_PASR_MPE3_SHIFT, FDMA_PASR_MPE3_SIZE, 3); break; } } + /* FCS Check */ gsw_w32(cdev, (SDMA_PCTRL_FCSIGN_OFFSET + (0x6 * pidx)), SDMA_PCTRL_FCSIGN_SHIFT, SDMA_PCTRL_FCSIGN_SIZE, parm->bFcsCheck); + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (parm->bSpecialTagEthType == GSW_CPU_ETHTYPE_FLOWID) { gsw_w32(cdev, (FDMA_PCTRL_ST_TYPE_OFFSET + (0x6 * pidx)), @@ -13312,20 +17189,35 @@ GSW_return_t GSW_CPU_PortCfgSet(void *cdev, GSW_CPU_PortCfg_t *parm) FDMA_PCTRL_ST_TYPE_SHIFT, FDMA_PCTRL_ST_TYPE_SIZE, 0); } } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) { u32 value, value_add, value_vlan; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) { - return GSW_statusOk; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } else { gsw_r32(cdev, (PMAC_HD_CTL_ADD_OFFSET + GSW_TREG_OFFSET), @@ -13336,6 +17228,7 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) PMAC_HD_CTL_TAG_SHIFT, PMAC_HD_CTL_TAG_SIZE, &value_vlan); } + if (value_add == 0 && value_vlan == 0) parm->eHeaderAdd = 0; else if (value_add == 1 && value_vlan == 0) @@ -13344,10 +17237,12 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) parm->eHeaderAdd = 2; else parm->eHeaderAdd = 0; + gsw_r32(cdev, (PMAC_HD_CTL_RL2_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_RL2_SHIFT, PMAC_HD_CTL_RL2_SIZE, &value); parm->bHeaderRemove = value; memset(&parm->sHeader, 0, sizeof(GSW_CPU_Header_t)); + if (value_add == 1) { /* Output the Src MAC */ gsw_r32(cdev, @@ -13392,6 +17287,7 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) PMAC_TL_TYPE_LEN_SHIFT, PMAC_TL_TYPE_LEN_SIZE, &value); parm->sHeader.nEthertype = value; } + if (value_vlan == 1) { gsw_r32(cdev, (PMAC_VLAN_PRI_OFFSET + GSW_TREG_OFFSET), PMAC_VLAN_PRI_SHIFT, PMAC_VLAN_PRI_SIZE, &value); @@ -13405,6 +17301,7 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) PMAC_VLAN_VLAN_ID_SIZE, &value); parm->sHeader.nVLAN_ID = value; } + gsw_r32(cdev, (PMAC_HD_CTL_FC_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_FC_SHIFT, PMAC_HD_CTL_FC_SIZE, &value); parm->ePauseCtrl = value; @@ -13414,80 +17311,106 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) gsw_r32(cdev, (PMAC_EWAN_EWAN_OFFSET + GSW_TREG_OFFSET), PMAC_EWAN_EWAN_SHIFT, PMAC_EWAN_EWAN_SIZE, &value); parm->nWAN_Ports = value; - return GSW_statusOk; + ret = GSW_statusOk; + + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_CPU_PortExtendCfgSet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) { u32 value_add = 0, value_vlan = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (gswdev->gipver == LTQ_GSWIP_3_0 || - gswdev->gipver == LTQ_GSWIP_3_1) - return GSW_statusOk; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (IS_VRSN_30_31(gswdev->gipver)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + switch (parm->eHeaderAdd) { case GSW_CPU_HEADER_NO: - value_add = 0; value_vlan = 0; + value_add = 0; + value_vlan = 0; break; + case GSW_CPU_HEADER_MAC: - value_add = 1; value_vlan = 0; + value_add = 1; + value_vlan = 0; break; + case GSW_CPU_HEADER_VLAN: - value_add = 1; value_vlan = 1; + value_add = 1; + value_vlan = 1; break; } + if ((parm->bHeaderRemove == 1) - && (parm->eHeaderAdd != GSW_CPU_HEADER_NO)) { + && (parm->eHeaderAdd != GSW_CPU_HEADER_NO)) { pr_err("The Header Can't be remove because the Header Add parameter is not 0"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } else { gsw_w32(cdev, (PMAC_HD_CTL_RL2_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_RL2_SHIFT, PMAC_HD_CTL_RL2_SIZE, parm->bHeaderRemove); } + gsw_w32(cdev, (PMAC_HD_CTL_ADD_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_ADD_SHIFT, PMAC_HD_CTL_ADD_SIZE, value_add); gsw_w32(cdev, (PMAC_HD_CTL_TAG_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_TAG_SHIFT, PMAC_HD_CTL_TAG_SIZE, value_vlan); + if (parm->eHeaderAdd == GSW_CPU_HEADER_MAC) { u32 macdata; /* Input the Src MAC */ macdata = ((parm->sHeader.nMAC_Src[0]) - | (parm->sHeader.nMAC_Src[1] << 8)); + | (parm->sHeader.nMAC_Src[1] << 8)); gsw_w32(cdev, (PMAC_SA3_SA_15_0_OFFSET + GSW_TREG_OFFSET), PMAC_SA3_SA_15_0_SHIFT, PMAC_SA3_SA_15_0_SIZE, macdata); macdata = (parm->sHeader.nMAC_Src[2] - | parm->sHeader.nMAC_Src[3] << 8); + | parm->sHeader.nMAC_Src[3] << 8); gsw_w32(cdev, (PMAC_SA2_SA_31_16_OFFSET + GSW_TREG_OFFSET), PMAC_SA2_SA_31_16_SHIFT, PMAC_SA2_SA_31_16_SIZE, macdata); macdata = (parm->sHeader.nMAC_Src[4] - | parm->sHeader.nMAC_Src[5] << 8); + | parm->sHeader.nMAC_Src[5] << 8); gsw_w32(cdev, (PMAC_SA1_SA_47_32_OFFSET + GSW_TREG_OFFSET), PMAC_SA1_SA_47_32_SHIFT, PMAC_SA1_SA_47_32_SIZE, macdata); /* Input the Dst MAC */ macdata = (parm->sHeader.nMAC_Dst[0] - | parm->sHeader.nMAC_Dst[1] << 8); + | parm->sHeader.nMAC_Dst[1] << 8); gsw_w32(cdev, (PMAC_DA3_DA_15_0_OFFSET + GSW_TREG_OFFSET), PMAC_DA3_DA_15_0_SHIFT, PMAC_DA3_DA_15_0_SIZE, macdata); macdata = (parm->sHeader.nMAC_Dst[2] - | parm->sHeader.nMAC_Dst[3] << 8); + | parm->sHeader.nMAC_Dst[3] << 8); gsw_w32(cdev, (PMAC_DA2_DA_31_16_OFFSET + GSW_TREG_OFFSET), PMAC_DA2_DA_31_16_SHIFT, PMAC_DA2_DA_31_16_SIZE, macdata); macdata = ((parm->sHeader.nMAC_Dst[4]) - | (parm->sHeader.nMAC_Dst[5] << 8)); + | (parm->sHeader.nMAC_Dst[5] << 8)); gsw_w32(cdev, (PMAC_DA1_SA_47_32_OFFSET + GSW_TREG_OFFSET), PMAC_DA1_SA_47_32_SHIFT, @@ -13498,24 +17421,35 @@ GSW_return_t GSW_CPU_PortExtendCfgSet(void *cdev, GSW_CPU_PortExtendCfg_t *parm) PMAC_TL_TYPE_LEN_SHIFT, PMAC_TL_TYPE_LEN_SIZE, parm->sHeader.nEthertype); } + if (parm->eHeaderAdd == GSW_CPU_HEADER_VLAN) { gsw_w32(cdev, (PMAC_VLAN_PRI_OFFSET + GSW_TREG_OFFSET), PMAC_VLAN_PRI_SHIFT, PMAC_VLAN_PRI_SIZE, parm->sHeader.nVLAN_Prio); - gsw_w32(cdev, (PMAC_VLAN_CFI_OFFSET + GSW_TREG_OFFSET), - PMAC_VLAN_CFI_SHIFT, - PMAC_VLAN_CFI_SIZE, parm->sHeader.nVLAN_CFI); - gsw_w32(cdev, (PMAC_VLAN_VLAN_ID_OFFSET + GSW_TREG_OFFSET), - PMAC_VLAN_VLAN_ID_SHIFT, - PMAC_VLAN_VLAN_ID_SIZE, parm->sHeader.nVLAN_ID); + gsw_w32(cdev, (PMAC_VLAN_CFI_OFFSET + GSW_TREG_OFFSET), + PMAC_VLAN_CFI_SHIFT, + PMAC_VLAN_CFI_SIZE, parm->sHeader.nVLAN_CFI); + gsw_w32(cdev, (PMAC_VLAN_VLAN_ID_OFFSET + GSW_TREG_OFFSET), + PMAC_VLAN_VLAN_ID_SHIFT, + PMAC_VLAN_VLAN_ID_SIZE, parm->sHeader.nVLAN_ID); } + gsw_w32(cdev, (PMAC_HD_CTL_FC_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_FC_SHIFT, PMAC_HD_CTL_FC_SIZE, parm->ePauseCtrl); gsw_w32(cdev, (PMAC_HD_CTL_RC_OFFSET + GSW_TREG_OFFSET), PMAC_HD_CTL_RC_SHIFT, PMAC_HD_CTL_RC_SIZE, parm->bFcsRemove); gsw_w32(cdev, (PMAC_EWAN_EWAN_OFFSET + GSW_TREG_OFFSET), PMAC_EWAN_EWAN_SHIFT, PMAC_EWAN_EWAN_SIZE, parm->nWAN_Ports); - return GSW_statusOk; + ret = GSW_statusOk; + + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } #if defined(CONFIG_LTQ_WOL) && CONFIG_LTQ_WOL @@ -13523,10 +17457,17 @@ GSW_return_t GSW_WoL_CfgGet(void *cdev, GSW_WoL_Cfg_t *parm) { u32 value; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + gsw_r32(cdev, WOL_GLB_CTRL_PASSEN_OFFSET, WOL_GLB_CTRL_PASSEN_SHIFT, WOL_GLB_CTRL_PASSEN_SIZE, &value); parm->bWolPasswordEnable = value; @@ -13554,115 +17495,218 @@ GSW_return_t GSW_WoL_CfgGet(void *cdev, GSW_WoL_Cfg_t *parm) WOL_PW_0_PW0_SIZE, &value); parm->nWolPassword[4] = (value >> 8 & 0xFF); parm->nWolPassword[5] = (value & 0xFF); - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_WoL_CfgSet(void *cdev, GSW_WoL_Cfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + gsw_w32(cdev, WOL_GLB_CTRL_PASSEN_OFFSET, WOL_GLB_CTRL_PASSEN_SHIFT, WOL_GLB_CTRL_PASSEN_SIZE, parm->bWolPasswordEnable); gsw_w32(cdev, WOL_DA_2_DA2_OFFSET, WOL_DA_2_DA2_SHIFT, WOL_DA_2_DA2_SIZE, (((parm->nWolMAC[0] & 0xFF) << 8) - | (parm->nWolMAC[1] & 0xFF))); + | (parm->nWolMAC[1] & 0xFF))); gsw_w32(cdev, WOL_DA_1_DA1_OFFSET, WOL_DA_1_DA1_SHIFT, WOL_DA_1_DA1_SIZE, (((parm->nWolMAC[2] & 0xFF) << 8) - | (parm->nWolMAC[3] & 0xFF))); + | (parm->nWolMAC[3] & 0xFF))); gsw_w32(cdev, WOL_DA_0_DA0_OFFSET, WOL_DA_0_DA0_SHIFT, WOL_DA_0_DA0_SIZE, (((parm->nWolMAC[4] & 0xFF) << 8) - | (parm->nWolMAC[5] & 0xFF))); + | (parm->nWolMAC[5] & 0xFF))); gsw_w32(cdev, WOL_PW_2_PW2_OFFSET, WOL_PW_2_PW2_SHIFT, WOL_PW_2_PW2_SIZE, (((parm->nWolPassword[0] & 0xFF) << 8) - | (parm->nWolPassword[1] & 0xFF))); + | (parm->nWolPassword[1] & 0xFF))); gsw_w32(cdev, WOL_PW_1_PW1_OFFSET, WOL_PW_1_PW1_SHIFT, WOL_PW_1_PW1_SIZE, (((parm->nWolPassword[2] & 0xFF) << 8) - | (parm->nWolPassword[3] & 0xFF))); + | (parm->nWolPassword[3] & 0xFF))); gsw_w32(cdev, WOL_PW_0_PW0_OFFSET, WOL_PW_0_PW0_SHIFT, WOL_PW_0_PW0_SIZE, (((parm->nWolPassword[4] & 0xFF) << 8) - | (parm->nWolPassword[5] & 0xFF))); - return GSW_statusOk; + | (parm->nWolPassword[5] & 0xFF))); + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_WoL_PortCfgGet(void *cdev, GSW_WoL_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_r32(cdev, (WOL_CTRL_PORT_OFFSET + (0xA * parm->nPortId)), WOL_CTRL_PORT_SHIFT, WOL_CTRL_PORT_SIZE, &value); parm->bWakeOnLAN_Enable = value; - if(gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (IS_VRSN_31(gswdev->gipver)) { gsw_r32(cdev, (WOL_CTRL_ADDRDIS_OFFSET + (0xA * parm->nPortId)), WOL_CTRL_ADDRDIS_SHIFT, WOL_CTRL_ADDRDIS_SIZE, &value); parm->bIgnoreAdrCheck = value; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_WoL_PortCfgSet(void *cdev, GSW_WoL_PortCfg_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + gsw_w32(cdev, (WOL_CTRL_PORT_OFFSET + (0xA * parm->nPortId)), WOL_CTRL_PORT_SHIFT, WOL_CTRL_PORT_SIZE, parm->bWakeOnLAN_Enable); - if(gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (IS_VRSN_31(gswdev->gipver)) { gsw_w32(cdev, (WOL_CTRL_ADDRDIS_OFFSET + (0xA * parm->nPortId)), WOL_CTRL_ADDRDIS_SHIFT, WOL_CTRL_ADDRDIS_SIZE, parm->bIgnoreAdrCheck); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } #endif /* CONFIG_LTQ_WOL */ GSW_return_t GSW_RegisterGet(void *cdev, GSW_register_t *parm) { u32 rvalue, raddr = parm->nRegAddr; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + gsw_r32(cdev, raddr, 0, 16, &rvalue); parm->nData = rvalue; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return GSW_statusOk; } GSW_return_t GSW_RegisterSet(void *cdev, GSW_register_t *parm) { u32 rvalue = parm->nData, raddr = parm->nRegAddr; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + gsw_w32(cdev, raddr, 0, 16, rvalue); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return GSW_statusOk; } GSW_return_t GSW_IrqGet(void *cdev, GSW_irq_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /* ToDo: Require future clarify for how to display */ - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_IrqMaskGet(void *cdev, GSW_irq_t *parm) @@ -13670,12 +17714,22 @@ GSW_return_t GSW_IrqMaskGet(void *cdev, GSW_irq_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (parm->eIrqSrc == GSW_IRQ_WOL) { gsw_r32(cdev, (PCE_PIER_WOL_OFFSET + (0xA * pidx)), PCE_PIER_WOL_SHIFT, PCE_PIER_WOL_SIZE, &value); @@ -13686,20 +17740,38 @@ GSW_return_t GSW_IrqMaskGet(void *cdev, GSW_irq_t *parm) gsw_r32(cdev, (PCE_PIER_LIM_OFFSET + (0xA * pidx)), PCE_PIER_LIM_SHIFT, PCE_PIER_LIM_SIZE, &value); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_IrqMaskSet(void *cdev, GSW_irq_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (parm->eIrqSrc == GSW_IRQ_WOL) { gsw_w32(cdev, (PCE_PIER_WOL_OFFSET + (0xA * pidx)), PCE_PIER_WOL_SHIFT, PCE_PIER_WOL_SIZE, 1); @@ -13710,7 +17782,15 @@ GSW_return_t GSW_IrqMaskSet(void *cdev, GSW_irq_t *parm) gsw_w32(cdev, (PCE_PIER_LIM_OFFSET + (0xA * pidx)), PCE_PIER_LIM_SHIFT, PCE_PIER_LIM_SIZE, 1); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_IrqStatusClear(void *cdev, GSW_irq_t *parm) @@ -13722,239 +17802,367 @@ GSW_return_t GSW_IrqStatusClear(void *cdev, GSW_irq_t *parm) GSW_return_t GSW_PceRuleRead(void *cdev, GSW_PCE_rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } - if (0 != pce_rule_read(cdev, &gswdev->phandler, parm)) - return GSW_statusErr; - return GSW_statusOk; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (0 != pce_rule_read(cdev, &gswdev->phandler, parm)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_PceRuleWrite(void *cdev, GSW_PCE_rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (0 != pce_rule_write(cdev, &gswdev->phandler, parm)) - return GSW_statusErr; - return GSW_statusOk; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (0 != pce_rule_write(cdev, &gswdev->phandler, parm)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_PceRuleDelete(void *cdev, GSW_PCE_ruleDelete_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 index; //Traffic-Flow table index. + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + index = parm->nIndex; - if (0 != pce_pattern_delete(cdev, &gswdev->phandler, index)) - return GSW_statusErr; - return GSW_statusOk; -} + if (0 != pce_pattern_delete(cdev, &gswdev->phandler, index)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } -/*Applicable only for GSWIP 3.1*/ -static u8 GSW_SearchContiguousCtp(ethsw_api_dev_t *gswdev,u32 ctp,u32 NumberOfEntries) -{ + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} + + +/*Applicable only for GSWIP 3.1*/ +static u8 GSW_SearchContiguousCtp(ethsw_api_dev_t *gswdev, u32 ctp, u32 NumberOfEntries) +{ u32 i; - for(i=ctp;i < (ctp + NumberOfEntries);i++) - { + + for (i = ctp; i < (ctp + NumberOfEntries); i++) { if (gswdev->ctpportconfig_idx[i].IndexInUse) return 0; } + return 1; } -GSW_return_t GSW_CTP_PortAssignmentAlloc(void *cdev, GSW_CTP_portAssignment_t *parm) +GSW_return_t GSW_CTP_PortAssignmentAlloc(void *cdev, GSW_CTP_portAssignment_t *parm) { - GSW_CTP_portConfig_t CtpConfig; + static GSW_CTP_portConfig_t CtpConfig; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 i,ret,ctp; + u32 i, ret, ctp; u8 ContiguousCtpFound = 0; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if(!(gswdev->brdgeportconfig_idx[parm->nBridgePortId].IndexInUse)) { - pr_err("ERROR :BridgePortId %d index not in use,Please allocate the BridgePortId\n",parm->nBridgePortId); - return GSW_statusErr; - } - +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + if (!(gswdev->brdgeportconfig_idx[parm->nBridgePortId].IndexInUse)) { + pr_err("ERROR :BridgePortId %d index not in use,Please allocate the BridgePortId\n", parm->nBridgePortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*CTP 0 is for special use, so allocation search will start from CTP 1 to CTP 287*/ - for(ctp=1;ctp < gswdev->num_of_ctp && !ContiguousCtpFound;ctp++) - { + for (ctp = 1; ctp < gswdev->num_of_ctp && !ContiguousCtpFound; ctp++) { /*If CTP Index not in use*/ - if (!gswdev->ctpportconfig_idx[ctp].IndexInUse) - { + if (!gswdev->ctpportconfig_idx[ctp].IndexInUse) { /*Note: CTP allocation should be contiguous as per the requested nNumberOfCtpPort*/ - ContiguousCtpFound=GSW_SearchContiguousCtp(gswdev,ctp,parm->nNumberOfCtpPort); + ContiguousCtpFound = GSW_SearchContiguousCtp(gswdev, ctp, parm->nNumberOfCtpPort); } /*Contiguous CTP indexes which is not in use is found*/ - if(ContiguousCtpFound) - { - parm->nFirstCtpPortId=ctp; + if (ContiguousCtpFound) { + parm->nFirstCtpPortId = ctp; + /*Mark the contiguous ctp indexes as InUse and tag it with the logical port*/ - for(i=parm->nFirstCtpPortId;i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort);i++) - { - gswdev->ctpportconfig_idx[i].IndexInUse=1; - gswdev->ctpportconfig_idx[i].AssociatedLogicalPort=parm->nLogicalPortId; + for (i = parm->nFirstCtpPortId; i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort); i++) { + gswdev->ctpportconfig_idx[i].IndexInUse = 1; + gswdev->ctpportconfig_idx[i].AssociatedLogicalPort = parm->nLogicalPortId; } } } /*Contiguous CTP indexes not found*/ - if(!ContiguousCtpFound) { + if (!ContiguousCtpFound) { pr_err("ERROR:No Contiguous CTP indexes Found as per the requested nNumberOfCtpPort\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - /*Configure CTP StartIdx,EndIdx and Mode to the + + /*Configure CTP StartIdx,EndIdx and Mode to the corresponding logical port*/ - ret=GSW_CTP_PortAssignmentSet(cdev,parm); - if(ret==GSW_statusErr) { + ret = GSW_CTP_PortAssignmentSet(cdev, parm); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentSet returns ERROR\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - + memset(&CtpConfig, 0, sizeof(GSW_CTP_portConfig_t)); - CtpConfig.eMask=GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID; + CtpConfig.eMask = GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID; /*Associate the bridge port to the allocated CTP*/ - CtpConfig.nBridgePortId=parm->nBridgePortId; + CtpConfig.nBridgePortId = parm->nBridgePortId; /*Logical Port and SubInterfaceID will fetch the CTP index in GSW_CtpPortConfigSet */ - CtpConfig.nLogicalPortId=parm->nLogicalPortId; - CtpConfig.nSubIfIdGroup=0; - for(i=parm->nFirstCtpPortId;i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort);i++) - { - ret=GSW_CtpPortConfigSet(cdev,&CtpConfig); - if(ret==GSW_statusErr) { + CtpConfig.nLogicalPortId = parm->nLogicalPortId; + CtpConfig.nSubIfIdGroup = 0; + + for (i = parm->nFirstCtpPortId; i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort); i++) { + ret = GSW_CtpPortConfigSet(cdev, &CtpConfig); + + if (ret == GSW_statusErr) { pr_err("GSW_CtpPortConfigSet returns ERROR\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + CtpConfig.nSubIfIdGroup++; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /*Enable SDMA for the corresponding logical port*/ gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (parm->nLogicalPortId * 0x6)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 1); + SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 1); - return GSW_statusOk; +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; } -GSW_return_t GSW_CTP_PortAssignmentFree(void *cdev, GSW_CTP_portAssignment_t *parm) +GSW_return_t GSW_CTP_PortAssignmentFree(void *cdev, GSW_CTP_portAssignment_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 i,ret; + u32 i, ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - ret=GSW_CTP_PortAssignmentGet(cdev,parm); - if(ret==GSW_statusErr) { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + ret = GSW_CTP_PortAssignmentGet(cdev, parm); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentGet returns ERROR\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /*Set Index not in-Use to the CTPs assoicated with this logical port*/ - for(i=parm->nFirstCtpPortId;i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort);i++) - gswdev->ctpportconfig_idx[i].IndexInUse=0; + for (i = parm->nFirstCtpPortId; i < (parm->nFirstCtpPortId + parm->nNumberOfCtpPort); i++) + gswdev->ctpportconfig_idx[i].IndexInUse = 0; + /*Disable the SDMA for this logical port*/ gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (parm->nLogicalPortId * 0x6)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); - return GSW_statusOk; + SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_CTP_PortAssignmentSet(void *cdev, GSW_CTP_portAssignment_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /*Checking based on number of logical port */ if (parm->nLogicalPortId >= gswdev->tpnum) { - pr_err("ERROR: logical port id %d >= than gswdev->tpnum %d\n", - parm->nLogicalPortId,gswdev->tpnum); - return GSW_statusErr; - } + pr_err("ERROR: logical port id %d >= than gswdev->tpnum %d\n", + parm->nLogicalPortId, gswdev->tpnum); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + if (parm->nFirstCtpPortId >= gswdev->num_of_ctp) { - pr_err("ERROR: nFirstCtpPortId %d >= than gswdev->num_of_ctp %d\n", - parm->nFirstCtpPortId,gswdev->num_of_ctp); - return GSW_statusErr; - } + pr_err("ERROR: nFirstCtpPortId %d >= than gswdev->num_of_ctp %d\n", + parm->nFirstCtpPortId, gswdev->num_of_ctp); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - if ((parm->nFirstCtpPortId + (parm->nNumberOfCtpPort-1)) >= gswdev->num_of_ctp) { - pr_err("ERROR: nNumberOfCtpPort %d >= than gswdev->num_of_ctp %d\n", - (parm->nFirstCtpPortId + parm->nNumberOfCtpPort),gswdev->num_of_ctp); - return GSW_statusErr; - } - switch(parm->eMode) { + if ((parm->nFirstCtpPortId + (parm->nNumberOfCtpPort - 1)) >= gswdev->num_of_ctp) { + pr_err("ERROR: nNumberOfCtpPort %d >= than gswdev->num_of_ctp %d\n", + (parm->nFirstCtpPortId + parm->nNumberOfCtpPort), gswdev->num_of_ctp); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + switch (parm->eMode) { case GSW_LOGICAL_PORT_8BIT_WLAN: gsw_w32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE,0); + ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE, 0); break; + case GSW_LOGICAL_PORT_9BIT_WLAN: gsw_w32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE,1); + ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE, 1); break; + default: gsw_w32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE,2); + ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE, 2); } gsw_w32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_SHIFT, ETHSW_CTP_STARTID_SIZE,parm->nFirstCtpPortId); + ETHSW_CTP_STARTID_SHIFT, ETHSW_CTP_STARTID_SIZE, parm->nFirstCtpPortId); gsw_w32(cdev, ETHSW_CTP_ENDID_GET(parm->nLogicalPortId), - ETHSW_CTP_ENDID_SHIFT, ETHSW_CTP_ENDID_SIZE, (parm->nFirstCtpPortId+parm->nNumberOfCtpPort-1)); + ETHSW_CTP_ENDID_SHIFT, ETHSW_CTP_ENDID_SIZE, (parm->nFirstCtpPortId + parm->nNumberOfCtpPort - 1)); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_CTP_PortAssignmentGet(void *cdev, GSW_CTP_portAssignment_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /*Checking based on number of logical port*/ if (parm->nLogicalPortId >= gswdev->tpnum) { - pr_err("ERROR: logical port id %u >= than gswdev->tpnum %u\n", - parm->nLogicalPortId,gswdev->tpnum); - return GSW_statusErr; - } + pr_err("ERROR: logical port id %u >= than gswdev->tpnum %u\n", + parm->nLogicalPortId, gswdev->tpnum); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } gsw_r32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE,&value); + ETHSW_CTP_STARTID_MD_SHIFT, ETHSW_CTP_STARTID_MD_SIZE, &value); parm->eMode = value; gsw_r32(cdev, ETHSW_CTP_STARTID_GET(parm->nLogicalPortId), - ETHSW_CTP_STARTID_SHIFT, ETHSW_CTP_STARTID_SIZE,&value); + ETHSW_CTP_STARTID_SHIFT, ETHSW_CTP_STARTID_SIZE, &value); parm->nFirstCtpPortId = value; gsw_r32(cdev, ETHSW_CTP_ENDID_GET(parm->nLogicalPortId), - ETHSW_CTP_ENDID_SHIFT, ETHSW_CTP_ENDID_SIZE,&value); - if (parm->nFirstCtpPortId<value) - parm->nNumberOfCtpPort = value-parm->nFirstCtpPortId+1; + ETHSW_CTP_ENDID_SHIFT, ETHSW_CTP_ENDID_SIZE, &value); + + if (parm->nFirstCtpPortId < value) + parm->nNumberOfCtpPort = value - parm->nFirstCtpPortId + 1; else if (parm->nFirstCtpPortId == value) parm->nNumberOfCtpPort = 1; else parm->nNumberOfCtpPort = 0; - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } @@ -13962,469 +18170,578 @@ GSW_return_t GSW_QOS_ColorMarkingTableSet(void *cdev, GSW_QoS_colorMarkingEntry_ { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 pcp,dscp,tbl_index; + u8 pcp, dscp, tbl_index; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_MAMRK_INDEX; - switch(parm->eMode) { - case GSW_MARKING_ALL_GREEN: - break; - case GSW_MARKING_INTERNAL_MARKING: - break; - case GSW_MARKING_DEI: - break; - case GSW_MARKING_PCP_8P0D: - /* For mode 3 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 0 to 15 */ - case GSW_MARKING_PCP_7P1D: - /* For mode 4 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 16 to 31 */ - case GSW_MARKING_PCP_6P2D: - /* For mode 5 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 32 to 47 */ - case GSW_MARKING_PCP_5P3D: - /* For mode 6 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 48 to 63 */ - tbl_index=(((parm->eMode) - GSW_MARKING_PCP_8P0D) << 4); - - for(pcp=0;pcp<=15;pcp++,tbl_index++) { - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set Color Marking Mode Entry address in PCE_TBL_ADDR 2:0*/ - /*Set DEI Entry address in PCE_TBL_ADDR (bit 4 set to 0)*/ - /*Set PCP Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (pcp << 4); - /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - - /*Set PCE_TBL_VAL 0*/ - CLEAR_U16(tbl_prog.val[0]); - /*Set Priority in PCE_TBL_VAL 0 (bit 6:4)*/ - tbl_prog.val[0] |= ((parm->nPriority[tbl_index] & 0x7) << 4); - /*Set Color in PCE_TBL_VAL 0 (bit 8:7)*/ - tbl_prog.val[0] |= ((parm->nColor[tbl_index] & 0x3) << 7); - /*Address-based write*/ - gsw_pce_table_write(cdev, &tbl_prog); - } - break; - case GSW_MARKING_DSCP_AF: - /* For mode 7 there are 64 entries corresponding to DSCP - Table Entry index from 64 to 127 */ - tbl_index=0; - for(dscp=0;dscp<=63;dscp++,tbl_index++) { - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set DSCP Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (dscp << 4); - /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= GSW_MARKING_DSCP_AF; - - /*Set PCE_TBL_VAL 0*/ - CLEAR_U16(tbl_prog.val[0]); - /*Set Priority in PCE_TBL_VAL 0 (bit 6:4)*/ - tbl_prog.val[0] |= ((parm->nPriority[tbl_index] & 0x7) << 4); - /*Set Color in PCE_TBL_VAL 0 (bit 8:7)*/ - tbl_prog.val[0] |= ((parm->nColor[tbl_index] & 0x3) << 7); - /*Address-based write*/ - gsw_pce_table_write(cdev, &tbl_prog); - } - break; + + switch (parm->eMode) { + case GSW_MARKING_ALL_GREEN: + break; + + case GSW_MARKING_INTERNAL_MARKING: + break; + + case GSW_MARKING_DEI: + break; + + case GSW_MARKING_PCP_8P0D: + + /* For mode 3 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 0 to 15 */ + case GSW_MARKING_PCP_7P1D: + + /* For mode 4 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 16 to 31 */ + case GSW_MARKING_PCP_6P2D: + + /* For mode 5 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 32 to 47 */ + case GSW_MARKING_PCP_5P3D: + /* For mode 6 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 48 to 63 */ + tbl_index = (((parm->eMode) - GSW_MARKING_PCP_8P0D) << 4); + + for (pcp = 0; pcp <= 15; pcp++, tbl_index++) { + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set Color Marking Mode Entry address in PCE_TBL_ADDR 2:0*/ + /*Set DEI Entry address in PCE_TBL_ADDR (bit 4 set to 0)*/ + /*Set PCP Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (pcp << 4); + /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + + /*Set PCE_TBL_VAL 0*/ + CLEAR_U16(tbl_prog.val[0]); + /*Set Priority in PCE_TBL_VAL 0 (bit 6:4)*/ + tbl_prog.val[0] |= ((parm->nPriority[tbl_index] & 0x7) << 4); + /*Set Color in PCE_TBL_VAL 0 (bit 8:7)*/ + tbl_prog.val[0] |= ((parm->nColor[tbl_index] & 0x3) << 7); + /*Address-based write*/ + gsw_pce_table_write(cdev, &tbl_prog); + } + + break; + + case GSW_MARKING_DSCP_AF: + /* For mode 7 there are 64 entries corresponding to DSCP + Table Entry index from 64 to 127 */ + tbl_index = 0; + + for (dscp = 0; dscp <= 63; dscp++, tbl_index++) { + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set DSCP Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (dscp << 4); + /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= GSW_MARKING_DSCP_AF; + + /*Set PCE_TBL_VAL 0*/ + CLEAR_U16(tbl_prog.val[0]); + /*Set Priority in PCE_TBL_VAL 0 (bit 6:4)*/ + tbl_prog.val[0] |= ((parm->nPriority[tbl_index] & 0x7) << 4); + /*Set Color in PCE_TBL_VAL 0 (bit 8:7)*/ + tbl_prog.val[0] |= ((parm->nColor[tbl_index] & 0x3) << 7); + /*Address-based write*/ + gsw_pce_table_write(cdev, &tbl_prog); + } + + break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_QOS_ColorMarkingTableGet(void *cdev, GSW_QoS_colorMarkingEntry_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 pcp,dscp,tbl_index; + u8 pcp, dscp, tbl_index; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_MAMRK_INDEX; - switch(parm->eMode) { - case GSW_MARKING_ALL_GREEN: - break; - case GSW_MARKING_INTERNAL_MARKING: - break; - case GSW_MARKING_DEI: - break; - case GSW_MARKING_PCP_8P0D: - /* For mode 3 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 0 to 15 */ - case GSW_MARKING_PCP_7P1D: - /* For mode 4 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 16 to 31 */ - case GSW_MARKING_PCP_6P2D: - /* For mode 5 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 32 to 47 */ - case GSW_MARKING_PCP_5P3D: - /* For mode 6 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) - Table Entry index from 48 to 63 */ - tbl_index=(((parm->eMode) - GSW_MARKING_PCP_8P0D) << 4); - - for(pcp=0;pcp<=15;pcp++,tbl_index++) { - tbl_prog.table = PCE_MAMRK_INDEX; - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set PCP Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (pcp << 4); - /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - /*Address-based read*/ - gsw_pce_table_read(cdev, &tbl_prog); - - /*Get PCE_TBL_VAL 0*/ - /*Get Priority in PCE_TBL_VAL 0 (bit 6:4)*/ - parm->nPriority[tbl_index] = ((tbl_prog.val[0] & 0x70) >> 4); - /*Get Color in PCE_TBL_VAL 0 (bit 8:7)*/ - parm->nColor[tbl_index] |= ((tbl_prog.val[0] & 0x180) >> 7); - } - break; - case GSW_MARKING_DSCP_AF: - /* For mode 7 there are 64 entries corresponding to DSCP - Table Entry index from 64 to 127 */ - tbl_index=0; - for(dscp=0;dscp<=63;dscp++,tbl_index++) { - tbl_prog.table = PCE_MAMRK_INDEX; - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set DSCP Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (dscp << 4); - /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= GSW_MARKING_DSCP_AF; - /*Address-based read*/ - gsw_pce_table_read(cdev, &tbl_prog); - - /*Get PCE_TBL_VAL 0*/ - /*Get Priority in PCE_TBL_VAL 0 (bit 6:4)*/ - parm->nPriority[tbl_index] = ((tbl_prog.val[0] & 0x70) >> 4); - /*Get Color in PCE_TBL_VAL 0 (bit 8:7)*/ - parm->nColor[tbl_index] |= ((tbl_prog.val[0] & 0x180) >> 7); - } - break; + + switch (parm->eMode) { + case GSW_MARKING_ALL_GREEN: + break; + + case GSW_MARKING_INTERNAL_MARKING: + break; + + case GSW_MARKING_DEI: + break; + + case GSW_MARKING_PCP_8P0D: + + /* For mode 3 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 0 to 15 */ + case GSW_MARKING_PCP_7P1D: + + /* For mode 4 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 16 to 31 */ + case GSW_MARKING_PCP_6P2D: + + /* For mode 5 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 32 to 47 */ + case GSW_MARKING_PCP_5P3D: + /* For mode 6 there are 16 entries corresponding to PCP (bit3 to 1) + DEI (bit 0) + Table Entry index from 48 to 63 */ + tbl_index = (((parm->eMode) - GSW_MARKING_PCP_8P0D) << 4); + + for (pcp = 0; pcp <= 15; pcp++, tbl_index++) { + tbl_prog.table = PCE_MAMRK_INDEX; + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set PCP Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (pcp << 4); + /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + /*Address-based read*/ + gsw_pce_table_read(cdev, &tbl_prog); + + /*Get PCE_TBL_VAL 0*/ + /*Get Priority in PCE_TBL_VAL 0 (bit 6:4)*/ + parm->nPriority[tbl_index] = ((tbl_prog.val[0] & 0x70) >> 4); + /*Get Color in PCE_TBL_VAL 0 (bit 8:7)*/ + parm->nColor[tbl_index] |= ((tbl_prog.val[0] & 0x180) >> 7); + } + + break; + + case GSW_MARKING_DSCP_AF: + /* For mode 7 there are 64 entries corresponding to DSCP + Table Entry index from 64 to 127 */ + tbl_index = 0; + + for (dscp = 0; dscp <= 63; dscp++, tbl_index++) { + tbl_prog.table = PCE_MAMRK_INDEX; + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set DSCP Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (dscp << 4); + /*Set Color Marking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= GSW_MARKING_DSCP_AF; + /*Address-based read*/ + gsw_pce_table_read(cdev, &tbl_prog); + + /*Get PCE_TBL_VAL 0*/ + /*Get Priority in PCE_TBL_VAL 0 (bit 6:4)*/ + parm->nPriority[tbl_index] = ((tbl_prog.val[0] & 0x70) >> 4); + /*Get Color in PCE_TBL_VAL 0 (bit 8:7)*/ + parm->nColor[tbl_index] |= ((tbl_prog.val[0] & 0x180) >> 7); + } + + break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_QOS_ColorReMarkingTableSet(void *cdev, GSW_QoS_colorRemarkingEntry_t *parm) +GSW_return_t GSW_QOS_ColorReMarkingTableSet(void *cdev, GSW_QoS_colorRemarkingEntry_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 priority,traffic_class,index; + u8 priority, traffic_class, index; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_REMARK_INDEX; - switch(parm->eMode) { - case GSW_REMARKING_NONE: - break; - case GSW_REMARKING_DEI: - break; - case GSW_REMARKING_PCP_8P0D: - /* For mode 3 there are 16 entries corresponding to Priority + Color Bit*/ - case GSW_REMARKING_PCP_7P1D: - /* For mode 4 there are 16 entries corresponding to Priority + Color Bit*/ - case GSW_REMARKING_PCP_6P2D: - /* For mode 5 there are 16 entries corresponding to Priority + Color Bit*/ - case GSW_REMARKING_PCP_5P3D: - /* For mode 6 there are 16 entries corresponding to Priority + Color Bit*/ - - index=0; - /*Set Color Bit 0's entries from 0 t0 7 - Color Bit 1's entries from 8 t0 15*/ - for(priority=0;priority<=15;priority++,index++) { - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set Priority Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (priority << 4); - /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - - /*Set PCE_TBL_VAL 0*/ - CLEAR_U16(tbl_prog.val[0]); - /*Set New DEI in PCE_TBL_VAL 0 (bit 0)*/ - tbl_prog.val[0] |= (parm->nVal[index] & 0x1); - /*Set New PCP in PCE_TBL_VAL 0 (bit 3:1)*/ - tbl_prog.val[0] |= (parm->nVal[index] & 0xE); - - /*Address-based write*/ - gsw_pce_table_write(cdev, &tbl_prog); - } - break; - case GSW_REMARKING_DSCP_AF: - /* For mode 7 there are 16 entries corresponding to Traffic Class + Color Bit - Table Entry index from 64 to 79*/ - index=0; - /*Set Color Bit 0's entries from 0 t0 7 - Color Bit 1's entries from 8 t0 15*/ - for(traffic_class=0;traffic_class<=15;traffic_class++,index++) { - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set Traffic Class Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (traffic_class << 4); - /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - - /*Set PCE_TBL_VAL 0*/ - CLEAR_U16(tbl_prog.val[0]); - /*Set New DSCP in PCE_TBL_VAL 0 (bit 5:0)*/ - tbl_prog.val[0] |= (parm->nVal[index] & 0x3F); - - /*Address-based write*/ - gsw_pce_table_write(cdev, &tbl_prog); - } - break; + + switch (parm->eMode) { + case GSW_REMARKING_NONE: + break; + + case GSW_REMARKING_DEI: + break; + + case GSW_REMARKING_PCP_8P0D: + + /* For mode 3 there are 16 entries corresponding to Priority + Color Bit*/ + case GSW_REMARKING_PCP_7P1D: + + /* For mode 4 there are 16 entries corresponding to Priority + Color Bit*/ + case GSW_REMARKING_PCP_6P2D: + + /* For mode 5 there are 16 entries corresponding to Priority + Color Bit*/ + case GSW_REMARKING_PCP_5P3D: + /* For mode 6 there are 16 entries corresponding to Priority + Color Bit*/ + + index = 0; + + /*Set Color Bit 0's entries from 0 t0 7 + Color Bit 1's entries from 8 t0 15*/ + for (priority = 0; priority <= 15; priority++, index++) { + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set Priority Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (priority << 4); + /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + + /*Set PCE_TBL_VAL 0*/ + CLEAR_U16(tbl_prog.val[0]); + /*Set New DEI in PCE_TBL_VAL 0 (bit 0)*/ + tbl_prog.val[0] |= (parm->nVal[index] & 0x1); + /*Set New PCP in PCE_TBL_VAL 0 (bit 3:1)*/ + tbl_prog.val[0] |= (parm->nVal[index] & 0xE); + + /*Address-based write*/ + gsw_pce_table_write(cdev, &tbl_prog); } - return GSW_statusOk; -} -GSW_return_t GSW_QOS_ColorReMarkingTableGet(void *cdev, GSW_QoS_colorRemarkingEntry_t *parm) -{ - pctbl_prog_t tbl_prog; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 priority,traffic_class,index; + break; - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } + case GSW_REMARKING_DSCP_AF: + /* For mode 7 there are 16 entries corresponding to Traffic Class + Color Bit + Table Entry index from 64 to 79*/ + index = 0; - memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); - switch(parm->eMode) { - case GSW_REMARKING_NONE: - break; - case GSW_REMARKING_DEI: - break; - case GSW_REMARKING_PCP_8P0D: - /* For mode 3 there are 16 entries corresponding to Priority + Color Bit - Table Entry index from 0 to 15 */ - case GSW_REMARKING_PCP_7P1D: - /* For mode 4 there are 16 entries corresponding to Priority + Color Bit - Table Entry index from 16 to 31 */ - case GSW_REMARKING_PCP_6P2D: - /* For mode 5 there are 16 entries corresponding to Priority + Color Bit - Table Entry index from 32 to 47 */ - case GSW_REMARKING_PCP_5P3D: - /* For mode 6 there are 16 entries corresponding to Priority + Color Bit - Table Entry index from 48 to 63 */ - index=0; - /*Get Color Bit 0's entries from 0 t0 7 - Color Bit 1's entries from 8 t0 15*/ - for(priority=0;priority<=15;priority++,index++) { - tbl_prog.table = PCE_REMARK_INDEX; - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set Priority Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (priority << 4); - /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - /*Address-based read*/ - gsw_pce_table_read(cdev, &tbl_prog); - - /*Get New DEI in PCE_TBL_VAL 0 (bit 0)*/ - parm->nVal[index] |= (tbl_prog.val[0] & 0x1); - /*Get New PCP in PCE_TBL_VAL 0 (bit 3:1)*/ - parm->nVal[index] |= (tbl_prog.val[0] & 0xE); - } - break; - case GSW_REMARKING_DSCP_AF: - /* For mode 7 there are 16 entries corresponding to Traffic Class + Color Bit - Table Entry index from 64 to 79*/ - index=0; - /*Get Color Bit 0's entries from 0 t0 7 - Color Bit 1's entries from 8 t0 15*/ - for(traffic_class=0;traffic_class<=15;traffic_class++,index++) { - tbl_prog.table = PCE_REMARK_INDEX; - /*Set Table Entry Index*/ - CLEAR_U16(tbl_prog.pcindex); - /*Set Traffic Class Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (traffic_class << 4); - /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= parm->eMode; - - /*Address-based read*/ - gsw_pce_table_read(cdev, &tbl_prog); - - /*Get New DSCP in PCE_TBL_VAL 0 (bit 3:1)*/ - parm->nVal[index] = (tbl_prog.val[0] & 0x3F); - } - break; + /*Set Color Bit 0's entries from 0 t0 7 + Color Bit 1's entries from 8 t0 15*/ + for (traffic_class = 0; traffic_class <= 15; traffic_class++, index++) { + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set Traffic Class Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (traffic_class << 4); + /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + + /*Set PCE_TBL_VAL 0*/ + CLEAR_U16(tbl_prog.val[0]); + /*Set New DSCP in PCE_TBL_VAL 0 (bit 5:0)*/ + tbl_prog.val[0] |= (parm->nVal[index] & 0x3F); + + /*Address-based write*/ + gsw_pce_table_write(cdev, &tbl_prog); } - return GSW_statusOk; + + break; + } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_QOS_Dscp2PcpTableSet(void *cdev, GSW_DSCP2PCP_map_t *parm) +GSW_return_t GSW_QOS_ColorReMarkingTableGet(void *cdev, GSW_QoS_colorRemarkingEntry_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 reg_index,dscp,bitshift; + u8 priority, traffic_class, index; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nIndex > 7) { - return GSW_statusErr; - } - +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); - tbl_prog.table = PCE_DSCP2PCP_INDEX; - switch(parm->nIndex) { - case 0: - reg_index=0; - bitshift=0; - break; - case 1: - reg_index=0; - bitshift=4; - break; - case 2: - reg_index=0; - bitshift=8; - break; - case 3: - reg_index=0; - bitshift=12; - break; - case 4: - reg_index=1; - bitshift=0; - break; - case 5: - reg_index=1; - bitshift=4; - break; - case 6: - reg_index=1; - bitshift=8; - break; - case 7: - reg_index=1; - bitshift=12; - break; - } - for(dscp=0;dscp<64;dscp++) { + + switch (parm->eMode) { + case GSW_REMARKING_NONE: + break; + + case GSW_REMARKING_DEI: + break; + + case GSW_REMARKING_PCP_8P0D: + + /* For mode 3 there are 16 entries corresponding to Priority + Color Bit + Table Entry index from 0 to 15 */ + case GSW_REMARKING_PCP_7P1D: + + /* For mode 4 there are 16 entries corresponding to Priority + Color Bit + Table Entry index from 16 to 31 */ + case GSW_REMARKING_PCP_6P2D: + + /* For mode 5 there are 16 entries corresponding to Priority + Color Bit + Table Entry index from 32 to 47 */ + case GSW_REMARKING_PCP_5P3D: + /* For mode 6 there are 16 entries corresponding to Priority + Color Bit + Table Entry index from 48 to 63 */ + index = 0; + + /*Get Color Bit 0's entries from 0 t0 7 + Color Bit 1's entries from 8 t0 15*/ + for (priority = 0; priority <= 15; priority++, index++) { + tbl_prog.table = PCE_REMARK_INDEX; + /*Set Table Entry Index*/ CLEAR_U16(tbl_prog.pcindex); - /*Table Entry address (DSCP value)*/ - tbl_prog.pcindex |= (dscp & 0x3F); - /*Address-based read - make sure the other pointer values are not disturbed*/ - tbl_prog.table = PCE_DSCP2PCP_INDEX; + /*Set Priority Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (priority << 4); + /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); - /*Set map DSCP value to PCP value in PCE_TBL_VAL 0 or PCE_TBL_VAL 1 - based on DSCP2PCP pointer index*/ - tbl_prog.val[reg_index] |= ((parm->nMap[dscp] & 0x7) << bitshift); - /*Address-based write*/ - tbl_prog.table = PCE_DSCP2PCP_INDEX; - gsw_pce_table_write(cdev, &tbl_prog); + + /*Get New DEI in PCE_TBL_VAL 0 (bit 0)*/ + parm->nVal[index] |= (tbl_prog.val[0] & 0x1); + /*Get New PCP in PCE_TBL_VAL 0 (bit 3:1)*/ + parm->nVal[index] |= (tbl_prog.val[0] & 0xE); + } + + break; + + case GSW_REMARKING_DSCP_AF: + /* For mode 7 there are 16 entries corresponding to Traffic Class + Color Bit + Table Entry index from 64 to 79*/ + index = 0; + + /*Get Color Bit 0's entries from 0 t0 7 + Color Bit 1's entries from 8 t0 15*/ + for (traffic_class = 0; traffic_class <= 15; traffic_class++, index++) { + tbl_prog.table = PCE_REMARK_INDEX; + /*Set Table Entry Index*/ + CLEAR_U16(tbl_prog.pcindex); + /*Set Traffic Class Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (traffic_class << 4); + /*Set Color ReMarking Mode Entry address in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= parm->eMode; + + /*Address-based read*/ + gsw_pce_table_read(cdev, &tbl_prog); + + /*Get New DSCP in PCE_TBL_VAL 0 (bit 3:1)*/ + parm->nVal[index] = (tbl_prog.val[0] & 0x3F); } + + break; + } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} + +GSW_return_t GSW_QOS_Dscp2PcpTableSet(void *cdev, GSW_DSCP2PCP_map_t *parm) +{ + pctbl_prog_t tbl_prog; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u8 reg_index, dscp, bitshift; + + /*This API is used internally,so no spin lock needed*/ + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (parm->nIndex > 7) { + return GSW_statusErr; + } + + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); + tbl_prog.table = PCE_DSCP2PCP_INDEX; + + switch (parm->nIndex) { + case 0: + reg_index = 0; + bitshift = 0; + break; + + case 1: + reg_index = 0; + bitshift = 4; + break; + + case 2: + reg_index = 0; + bitshift = 8; + break; + + case 3: + reg_index = 0; + bitshift = 12; + break; + + case 4: + reg_index = 1; + bitshift = 0; + break; + + case 5: + reg_index = 1; + bitshift = 4; + break; + + case 6: + reg_index = 1; + bitshift = 8; + break; + + case 7: + reg_index = 1; + bitshift = 12; + break; + } + + for (dscp = 0; dscp < 64; dscp++) { + CLEAR_U16(tbl_prog.pcindex); + /*Table Entry address (DSCP value)*/ + tbl_prog.pcindex |= (dscp & 0x3F); + /*Address-based read - make sure the other pointer values are not disturbed*/ + tbl_prog.table = PCE_DSCP2PCP_INDEX; + gsw_pce_table_read(cdev, &tbl_prog); + /*Set map DSCP value to PCP value in PCE_TBL_VAL 0 or PCE_TBL_VAL 1 + based on DSCP2PCP pointer index*/ + tbl_prog.val[reg_index] |= ((parm->nMap[dscp] & 0x7) << bitshift); + /*Address-based write*/ + tbl_prog.table = PCE_DSCP2PCP_INDEX; + gsw_pce_table_write(cdev, &tbl_prog); + } + return GSW_statusOk; } -GSW_return_t GSW_QOS_Dscp2PcpTableGet(void *cdev, GSW_DSCP2PCP_map_t *parm) +GSW_return_t GSW_QOS_Dscp2PcpTableGet(void *cdev, GSW_DSCP2PCP_map_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 reg_index,dscp,bitshift; + u8 reg_index, dscp, bitshift; + /*This API is used internally,so no spin lock needed*/ if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - + if (parm->nIndex > 7) { return GSW_statusErr; } memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); - switch(parm->nIndex) { - case 0: - reg_index=0; - bitshift=0; - break; - case 1: - reg_index=0; - bitshift=4; - break; - case 2: - reg_index=0; - bitshift=8; - break; - case 3: - reg_index=0; - bitshift=12; - break; - case 4: - reg_index=1; - bitshift=0; - break; - case 5: - reg_index=1; - bitshift=4; - break; - case 6: - reg_index=1; - bitshift=8; - break; - case 7: - reg_index=1; - bitshift=12; - break; - } - for(dscp=0;dscp<64;dscp++) { - tbl_prog.table = PCE_DSCP2PCP_INDEX; - CLEAR_U16(tbl_prog.pcindex); - /*Table Entry address (DSCP value) Bit 5:0 in PCE_TBL_ADDR*/ - tbl_prog.pcindex |= (dscp & 0x3F); - /*Address-based read*/ - gsw_pce_table_read(cdev, &tbl_prog); - /*Get Mapped PCP value from PCE_TBL_VAL 0 or PCE_TBL_VAL 1 - based on DSCP2PCP pointer index*/ - parm->nMap[dscp] = ((tbl_prog.val[reg_index] >> bitshift) & 0x7); - } + switch (parm->nIndex) { + case 0: + reg_index = 0; + bitshift = 0; + break; + + case 1: + reg_index = 0; + bitshift = 4; + break; + + case 2: + reg_index = 0; + bitshift = 8; + break; + + case 3: + reg_index = 0; + bitshift = 12; + break; + + case 4: + reg_index = 1; + bitshift = 0; + break; + + case 5: + reg_index = 1; + bitshift = 4; + break; + + case 6: + reg_index = 1; + bitshift = 8; + break; + + case 7: + reg_index = 1; + bitshift = 12; + break; + } + + for (dscp = 0; dscp < 64; dscp++) { + tbl_prog.table = PCE_DSCP2PCP_INDEX; + CLEAR_U16(tbl_prog.pcindex); + /*Table Entry address (DSCP value) Bit 5:0 in PCE_TBL_ADDR*/ + tbl_prog.pcindex |= (dscp & 0x3F); + /*Address-based read*/ + gsw_pce_table_read(cdev, &tbl_prog); + + /*Get Mapped PCP value from PCE_TBL_VAL 0 or PCE_TBL_VAL 1 + based on DSCP2PCP pointer index*/ + parm->nMap[dscp] = ((tbl_prog.val[reg_index] >> bitshift) & 0x7); + } + return GSW_statusOk; } -GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) +GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 pcp,dscp,entry_index; - u32 idx,freeidxfound = 0; + u8 pcp, dscp, entry_index; + u32 idx, freeidxfound = 0; + /*This API is used internally,so no spin lock needed*/ if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } /*If P-Mapper ID is invalid ,find a free P-Mapper table index and allocate New P-Mapper configuration table index*/ - if (parm->nPmapperId == PMAPPER_ENTRY_INVALID) - { - for (idx=0;idx < gswdev->num_of_pmapper && !freeidxfound;idx++) - { - if(!gswdev->pmapper_idx[idx].IndexInUse) - { - gswdev->pmapper_idx[idx].IndexInUse=1; - parm->nPmapperId=idx; - freeidxfound=1; + if (parm->nPmapperId == PMAPPER_ENTRY_INVALID) { + for (idx = 0; idx < gswdev->num_of_pmapper && !freeidxfound; idx++) { + if (!gswdev->pmapper_idx[idx].IndexInUse) { + gswdev->pmapper_idx[idx].IndexInUse = 1; + parm->nPmapperId = idx; + freeidxfound = 1; } } + /*No free Slot return Error*/ if (!freeidxfound) { pr_err("No P-mapper slot found\n"); @@ -14436,19 +18753,21 @@ GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) pr_err("parm->nPmapperId >= gswdev->num_of_pmapper\n"); return GSW_statusErr; } + /*If P-Mapper ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!gswdev->pmapper_idx[parm->nPmapperId].IndexInUse) { - pr_err("gswdev->pmapper_idx[parm->nPmapperId].IndexInUse not in use\n"); + if (!gswdev->pmapper_idx[parm->nPmapperId].IndexInUse) { + pr_err("gswdev->pmapper_idx[parm->nPmapperId].IndexInUse not in use\n"); return GSW_statusErr; - } + } + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_PMAP_INDEX; /*P-mapper MODE 00:The First Entry of each P-mapper index is for Non-IP and Non-VLAN tagging packets BIT 7:2 in PCE_TBL_ADDR is 0 and BIT 1:0 is 0 for MODE 00 */ - entry_index=0; + entry_index = 0; CLEAR_U16(tbl_prog.pcindex); /*Index of P-mapper. */ tbl_prog.pcindex |= ((parm->nPmapperId & 0x3f) << 8) ; @@ -14462,8 +18781,9 @@ GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) applies to VLAN tagging packet whenP-mapper mapping mode is PCP BIT 4:2 in PCE_TBL_ADDR is for MODE 01 */ - entry_index=1; - for(pcp=0;entry_index<=8;pcp++,entry_index++) { + entry_index = 1; + + for (pcp = 0; entry_index <= 8; pcp++, entry_index++) { CLEAR_U16(tbl_prog.pcindex); /*P-mapper Mode- PCP mapping 01*/ tbl_prog.pcindex |= 1 ; @@ -14482,9 +18802,10 @@ GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) applies to IP packets without VLAN tag or IP packet with VLAN BIT 7:2 in PCE_TBL_ADDR is for MODE 10 */ - entry_index=9; + entry_index = 9; + /* TODO: use dscp as for loop index */ - for(dscp=0;entry_index<=72;dscp++,entry_index++) { + for (dscp = 0; entry_index <= 72; dscp++, entry_index++) { CLEAR_U16(tbl_prog.pcindex); /*P-mapper Mode- DSCP mapping 10*/ tbl_prog.pcindex |= 2 ; @@ -14498,33 +18819,35 @@ GSW_return_t GSW_QOS_PmapperTableSet(void *cdev, GSW_PMAPPER_t *parm) /*Address-based write*/ gsw_pce_table_write(cdev, &tbl_prog); } + return GSW_statusOk; } -GSW_return_t GSW_QOS_PmapperTableGet(void *cdev, GSW_PMAPPER_t *parm) +GSW_return_t GSW_QOS_PmapperTableGet(void *cdev, GSW_PMAPPER_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 pcp,dscp,entry_index; + u8 pcp, dscp, entry_index; + /*This API is used internally,so no spin lock needed*/ if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } /*If P-Mapper ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!gswdev->pmapper_idx[parm->nPmapperId].IndexInUse) { - pr_err("gswdev->pmapper_idx[parm->nPmapperId].IndexInUse not in use\n"); + if (!gswdev->pmapper_idx[parm->nPmapperId].IndexInUse) { + pr_err("gswdev->pmapper_idx[parm->nPmapperId].IndexInUse not in use\n"); return GSW_statusErr; } - + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); /*P-mapper MODE 00:The First Entry of each P-mapper index is for Non-IP and Non-VLAN tagging packets BIT 7:2 in PCE_TBL_ADDR is 0 and BIT 1:0 is 0 for MODE 00 */ - entry_index=0; + entry_index = 0; CLEAR_U16(tbl_prog.pcindex); tbl_prog.table = PCE_PMAP_INDEX; /*Index of P-mapper. */ @@ -14533,15 +18856,16 @@ GSW_return_t GSW_QOS_PmapperTableGet(void *cdev, GSW_PMAPPER_t *parm) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); /*Get Destination sub-interface ID group field in PCE_TBL_VAL 0 (Bit 7:0)*/ - parm->nDestSubIfIdGroup[entry_index] = ( tbl_prog.val[0] & 0xFF); + parm->nDestSubIfIdGroup[entry_index] = (tbl_prog.val[0] & 0xFF); /*P-mapper MODE 01:The Entry 8 to 1 of each P-mapper index is for PCP mapping entries applies to VLAN tagging packet whenP-mapper mapping mode is PCP BIT 4:2 in PCE_TBL_ADDR is for MODE 01 */ - entry_index=1; - for(pcp=0;entry_index<=8;pcp++,entry_index++) { - tbl_prog.table = PCE_PMAP_INDEX; + entry_index = 1; + + for (pcp = 0; entry_index <= 8; pcp++, entry_index++) { + tbl_prog.table = PCE_PMAP_INDEX; CLEAR_U16(tbl_prog.pcindex); /*P-mapper Mode- PCP mapping 01*/ tbl_prog.pcindex |= 1 ; @@ -14552,16 +18876,17 @@ GSW_return_t GSW_QOS_PmapperTableGet(void *cdev, GSW_PMAPPER_t *parm) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); /*Get Destination sub-interface ID group field in PCE_TBL_VAL 0 (Bit 7:0)*/ - parm->nDestSubIfIdGroup[entry_index] = ( tbl_prog.val[0] & 0xFF); + parm->nDestSubIfIdGroup[entry_index] = (tbl_prog.val[0] & 0xFF); } /*P-mapper MODE 10:The Entry 72 to 9 of each P-mapper index is for DSCP mapping entries applies to IP packets without VLAN tag or IP packet with VLAN BIT 7:2 in PCE_TBL_ADDR is for MODE 10 */ - entry_index=9; - for(dscp=0;entry_index<=72;dscp++,entry_index++) { - tbl_prog.table = PCE_PMAP_INDEX; + entry_index = 9; + + for (dscp = 0; entry_index <= 72; dscp++, entry_index++) { + tbl_prog.table = PCE_PMAP_INDEX; CLEAR_U16(tbl_prog.pcindex); /*P-mapper Mode- DSCP mapping 10*/ tbl_prog.pcindex |= 2 ; @@ -14572,111 +18897,134 @@ GSW_return_t GSW_QOS_PmapperTableGet(void *cdev, GSW_PMAPPER_t *parm) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); /*Get Destination sub-interface ID group field in PCE_TBL_VAL 0 (Bit 7:0)*/ - parm->nDestSubIfIdGroup[entry_index] = ( tbl_prog.val[0] & 0xFF); + parm->nDestSubIfIdGroup[entry_index] = (tbl_prog.val[0] & 0xFF); } + return GSW_statusOk; } -static u8 GSW_SearchExVlanContiguousBlock(ethsw_api_dev_t *gswdev,u32 BlockId,u32 NumberOfEntries) +static u8 GSW_SearchExVlanContiguousBlock(ethsw_api_dev_t *gswdev, u32 BlockId, u32 NumberOfEntries) { u32 i; - for(i=BlockId;i <=(BlockId + NumberOfEntries);i++) - { + + for (i = BlockId; i <= (BlockId + NumberOfEntries); i++) { if (gswdev->extendvlan_idx.vlan_idx[i].IndexInUse) return 0; } + return 1; } -GSW_return_t GSW_ExtendedVlanAlloc(void *cdev, GSW_EXTENDEDVLAN_alloc_t *parm) +GSW_return_t GSW_ExtendedVlanAlloc(void *cdev, GSW_EXTENDEDVLAN_alloc_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u16 ExVlanIndex=0; - u8 ContiguousBlockFound=0; - u32 i; + u16 ExVlanIndex = 0; + u8 ContiguousBlockFound = 0; + u32 i, ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - /* +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + /* Allocate New Block as per the number of table Entries requested The Block must be allocated with contiguous table index */ - if (parm->nNumberOfEntries > (gswdev->num_of_extendvlan - gswdev->extendvlan_idx.nUsedEntry)) - return GSW_statusErr; + if (parm->nNumberOfEntries > (gswdev->num_of_extendvlan - gswdev->extendvlan_idx.nUsedEntry)) { + pr_err(" nNumberOfEntries requested is more than Exvlan index limit %s:%s:%d", + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - for(ExVlanIndex=0;ExVlanIndex < gswdev->num_of_extendvlan && !ContiguousBlockFound;ExVlanIndex++) - { + for (ExVlanIndex = 0; ExVlanIndex < gswdev->num_of_extendvlan && !ContiguousBlockFound; ExVlanIndex++) { /*Table Index not in use*/ - if (!gswdev->extendvlan_idx.vlan_idx[ExVlanIndex].IndexInUse) - { - ContiguousBlockFound=GSW_SearchExVlanContiguousBlock(gswdev,ExVlanIndex,parm->nNumberOfEntries); + if (!gswdev->extendvlan_idx.vlan_idx[ExVlanIndex].IndexInUse) { + ContiguousBlockFound = GSW_SearchExVlanContiguousBlock(gswdev, ExVlanIndex, parm->nNumberOfEntries); } /*Contiguous block found in the table*/ - if(ContiguousBlockFound) - { - parm->nExtendedVlanBlockId=ExVlanIndex; + if (ContiguousBlockFound) { + parm->nExtendedVlanBlockId = ExVlanIndex; + /*Mark the contiguous table indexes as InUse and tag it with block id*/ - for(i=parm->nExtendedVlanBlockId;i < (parm->nExtendedVlanBlockId + parm->nNumberOfEntries);i++) - { - gswdev->extendvlan_idx.vlan_idx[i].IndexInUse=1; - gswdev->extendvlan_idx.vlan_idx[i].VlanBlockId=parm->nExtendedVlanBlockId; + for (i = parm->nExtendedVlanBlockId; i < (parm->nExtendedVlanBlockId + parm->nNumberOfEntries); i++) { + gswdev->extendvlan_idx.vlan_idx[i].IndexInUse = 1; + gswdev->extendvlan_idx.vlan_idx[i].VlanBlockId = parm->nExtendedVlanBlockId; gswdev->extendvlan_idx.nUsedEntry++; } } } + /*Contiguous block not found in the table*/ - if(!ContiguousBlockFound) { - pr_err("No ContiguousBlockFound\n"); - return GSW_statusErr; + if (!ContiguousBlockFound) { + pr_err(" ContiguousBlockFound %s:%s:%d", __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; } -GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) +GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) { - pctbl_prog_t tbl_prog; + static pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u8 ret,all_entry_match=0; - u8 dscp2pcpmatch_found=0; - u32 idx=0,dscp2pcp_pointer=0,dscp=0,meterid=0; - u32 empty_dscp2pcptblslot_found=0,bDscp2PcpMapEnable=0; - GSW_DSCP2PCP_map_t dscp2pcp_get,dscp2pcp_set; + u8 ret, all_entry_match = 0; + u8 dscp2pcpmatch_found = 0; + u32 idx = 0, dscp2pcp_pointer = 0, dscp = 0, meterid = 0; + u32 empty_dscp2pcptblslot_found = 0, bDscp2PcpMapEnable = 0; + static GSW_DSCP2PCP_map_t dscp2pcp_get, dscp2pcp_set; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif -/* Once the New blk allocated,param->nEntryIndex will decide which index with in this block - has to be set.only one index will be set at a time. - It is users responsibility to set all the index with in this block - by calling GSW_ExtendedVlanSet as many times as required (i.e) param->nNumberOfEntries*/ - idx=parm->nExtendedVlanBlockId + parm->nEntryIndex; + /* Once the New blk allocated,param->nEntryIndex will decide which index with in this block + has to be set.only one index will be set at a time. + It is users responsibility to set all the index with in this block + by calling GSW_ExtendedVlanSet as many times as required (i.e) param->nNumberOfEntries*/ + idx = parm->nExtendedVlanBlockId + parm->nEntryIndex; - if (idx >= gswdev->num_of_extendvlan) - { - pr_err("ERROR : idx %d >= gswdev->num_of_extendvlan \n",idx); - return GSW_statusErr; - } - if(gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != parm->nExtendedVlanBlockId) - { - pr_err("ERROR : VlanBlockId %d != parm->nExtendedVlanBlockId %d \n", - gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId,parm->nExtendedVlanBlockId); - return GSW_statusErr; - } - if (!gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse) - { - pr_err("ERROR : idx %d not in Use \n",idx); - return GSW_statusErr; + if (idx >= gswdev->num_of_extendvlan) { + pr_err("ERROR : idx %d >= gswdev->num_of_extendvlan \n", idx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != parm->nExtendedVlanBlockId) { + pr_err("ERROR : VlanBlockId %d != parm->nExtendedVlanBlockId %d \n", + gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId, parm->nExtendedVlanBlockId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (!gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse) { + pr_err("ERROR : idx %d not in Use \n", idx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_EXTVLAN_INDEX; CLEAR_U16(tbl_prog.pcindex); @@ -14685,361 +19033,404 @@ GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) /** Extended VLAN Table Filter **/ /*Program Outer VLAN Filter*/ - switch(parm->sFilter.sOuterVlan.eType) { - /** There is tag and criteria applies. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL: - CLEAR_U16(tbl_prog.key[1]); - CLEAR_U16(tbl_prog.key[0]); - if (parm->sFilter.sOuterVlan.bPriorityEnable) - { - /*Filter on outer priority - PCP value key 1 BIT 15:12*/ - tbl_prog.key[1] |= ((parm->sFilter.sOuterVlan.nPriorityVal & 0x7) << 12); - } else { - /*Do not filter on outer priority - Filter Outer PCP key 1 BIT 15:12 set to 8 */ - tbl_prog.key[1] |= (8 << 12); - } - - if (parm->sFilter.sOuterVlan.bVidEnable) - { - /*Do filter on outer VID - Filter Outer VID (Total 13 bits) - key 0 BIT 15 - key 1 BIT 11:0 - Set nVidVal - */ - tbl_prog.key[0] |= ((parm->sFilter.sOuterVlan.nVidVal & 0x1) << 15); - tbl_prog.key[1] |= ((parm->sFilter.sOuterVlan.nVidVal & 0x1FFE) >> 1); - } else { - /*Do not filter on outer VID - Filter Outer VID (Total 13 bits) - key 0 BIT 15 - key 1 BIT 11:0 - Set 4096 - */ - tbl_prog.key[0] |= ((4096 & 0x1) << 15); - tbl_prog.key[1] |= ((4096 & 0x1FFE) >> 1); - } - - /*Filter out outer TPID/DEI*/ - switch(parm->sFilter.sOuterVlan.eTpid) { - /** Do not filter TPID. */ - case GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER: - /*Do not filter on outer TPID - Filter Outer TPID key 0 BIT 14:12 set to 0 */ - tbl_prog.key[0] &= ~(7 << 12); - break; - /** TPID is 0x8100. key 0 BIT 14:12 set 4*/ - case GSW_EXTENDEDVLAN_FILTER_TPID_8021Q: - tbl_prog.key[0] |= (4 << 12); - break; - /** TPID is global configured value. */ - case GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE: - switch(parm->sFilter.sOuterVlan.eDei) { - /** Do not filter (don't care) key 0 BIT 14:12 set 5 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER: - tbl_prog.key[0] |= (5 << 12); - break; - /** DEI=0 key 0 BIT 14:12 set 6 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_0: - tbl_prog.key[0] |= (6 << 12); - break; - /** DEI=1 key 0 BIT 14:12 set 7 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_1: - tbl_prog.key[0] |= (7 << 12); - break; - } - break; - } - break; - /** There is tag but no criteria. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER: - CLEAR_U16(tbl_prog.key[1]); - CLEAR_U16(tbl_prog.key[0]); - - /*Do not filter on outer priority - Filter Outer PCP key 1 BIT 15:12 set to 8 */ - tbl_prog.key[1] |= (8 << 12); - - /*Do not filter on outer VID - Filter Outer VID (Total 13 bits) - key 0 BIT 15 - key 1 BIT 11:0 - Set 4096 - */ - tbl_prog.key[0] |= ((4096 & 0x1) << 15); - tbl_prog.key[1] |= ((4096 & 0x1FFE) >> 1); - - /*Do not filter on outer TPID - Filter Outer PCP key 0 BIT 14:12 set to 0 */ - tbl_prog.key[0] &= ~(7 << 12); - break; - /** Default entry if no other rule applies. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT: - CLEAR_U16(tbl_prog.key[1]); - /*Default entry if no other rule applies - Filter Outer PCP key 1 BIT 15:12 set to 14 */ - tbl_prog.key[1] |= (14 << 12); - break; - /** There is no tag. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG: - CLEAR_U16(tbl_prog.key[1]); - /*No Outer Tag - Filter Outer PCP key 1 BIT 15:12 set to 15 */ - tbl_prog.key[1] |= (15 << 12); - break; - case GSW_EXTENDEDVLAN_BLOCK_INVALID: - CLEAR_U16(tbl_prog.key[1]); - /*SET BLOCK INVALID - should be set only on outer priority filter - Filter Outer PCP key 1 BIT 15:12 set to 13 */ - tbl_prog.key[1] |= (13 << 12); - break; - default: - break; - } - - /*Program inner VLAN Filter*/ - switch(parm->sFilter.sInnerVlan.eType) { - /** There is tag and criteria applies. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL: - CLEAR_U16(tbl_prog.key[3]); - CLEAR_U16(tbl_prog.key[2]); - if (parm->sFilter.sInnerVlan.bPriorityEnable) - { - /*Filter on inner priority - PCP value key 3 BIT 15:12*/ - tbl_prog.key[3] |= ((parm->sFilter.sInnerVlan.nPriorityVal & 0x7) << 12); - } else { - /*Do not filter on inner priority - Filter inner PCP key 3 BIT 15:12 set to 8 */ - tbl_prog.key[3] |= (8 << 12); - } - - if (parm->sFilter.sInnerVlan.bVidEnable) - { - /*Do not filter on inner VID - Filter inner VID (Total 13 bits) - key 2 BIT 15 - key 3 BIT 11:0 - Set nVidVal - */ - tbl_prog.key[2] |= ((parm->sFilter.sInnerVlan.nVidVal & 0x1) << 15); - tbl_prog.key[3] |= ((parm->sFilter.sInnerVlan.nVidVal & 0x1FFE) >> 1); - } else { - /*Do not filter on inner VID - Filter inner VID (Total 13 bits) - key 2 BIT 15 - key 3 BIT 11:0 - Set 4096 - */ - tbl_prog.key[2] |= ((4096 & 0x1) << 15); - tbl_prog.key[3] |= ((4096 & 0x1FFE) >> 1); - } - - /*Filter out inner TPID/DEI*/ - switch(parm->sFilter.sInnerVlan.eTpid) { - /** Do not filter TPID. */ - case GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER: - /*Do not filter on inner TPID - Filter inner TPID key 2 BIT 14:12 set to 0 */ - tbl_prog.key[2] &= ~(7 << 12); - break; - /** TPID is 0x8100. key 2 BIT 14:12 set 4*/ - case GSW_EXTENDEDVLAN_FILTER_TPID_8021Q: - tbl_prog.key[2] |= (4 << 12); - break; - /** TPID is global configured value. */ - case GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE: - switch(parm->sFilter.sInnerVlan.eDei) { - /** Do not filter (don't care) key 2 BIT 14:12 set 5 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER: - tbl_prog.key[2] |= (5 << 12); - break; - /** DEI=0 key 2 BIT 14:12 set 6 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_0: - tbl_prog.key[2] |= (6 << 12); - break; - /** DEI=1 key 2 BIT 14:12 set 7 */ - case GSW_EXTENDEDVLAN_FILTER_DEI_1: - tbl_prog.key[2] |= (7 << 12); - break; - } - break; - } - break; - /** There is tag but no criteria. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER: - CLEAR_U16(tbl_prog.key[3]); - CLEAR_U16(tbl_prog.key[2]); - - /*Do not filter on inner priority - Filter inner PCP key 3 BIT 15:12 set to 8 */ - tbl_prog.key[3] |= (8 << 12); - - /*Do not filter on inner VID - Filter inner VID (Total 13 bits) - key 2 BIT 15 - key 3 BIT 11:0 - Set 4096 - */ - tbl_prog.key[2] |= ((4096 & 0x1) << 15); - tbl_prog.key[3] |= ((4096 & 0x1FFE) >> 1); - - /*Do not filter on inner TPID - Filter inner PCP key 2 BIT 14:12 set to 0 */ - tbl_prog.key[2] &= ~(7 << 12); - break; - /** Default entry if no other rule applies. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT: - CLEAR_U16(tbl_prog.key[3]); - - /*Default entry if no other rule applies - Filter inner PCP key 3 BIT 15:12 set to 14 */ - tbl_prog.key[3] |= (14 << 12); - break; - /** There is no tag. */ - case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG: - CLEAR_U16(tbl_prog.key[3]); - /*No inner Tag - Filter inner PCP key 3 BIT 15:12 set to 15 */ - tbl_prog.key[3] |= (15 << 12); - break; - default: - break; - } + switch (parm->sFilter.sOuterVlan.eType) { + /** There is tag and criteria applies. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL: + CLEAR_U16(tbl_prog.key[1]); + CLEAR_U16(tbl_prog.key[0]); + + if (parm->sFilter.sOuterVlan.bPriorityEnable) { + /*Filter on outer priority + PCP value key 1 BIT 15:12*/ + tbl_prog.key[1] |= ((parm->sFilter.sOuterVlan.nPriorityVal & 0x7) << 12); + } else { + /*Do not filter on outer priority + Filter Outer PCP key 1 BIT 15:12 set to 8 */ + tbl_prog.key[1] |= (8 << 12); + } - /*Filter Ether type key 2 BIT 4:0*/ - tbl_prog.key[2] &= ~(0x1F); - switch(parm->sFilter.eEtherType) { - /** Do not filter Ether Type*/ - case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER: - tbl_prog.key[2] |= 0; - break; - /** IPoE frame (Ethertyp is 0x0800). */ - case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE: - tbl_prog.key[2] |= 1; - break; - /** PPPoE frame (Ethertyp is 0x8863 or 0x8864). */ - case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE: - tbl_prog.key[2] |= 2; + if (parm->sFilter.sOuterVlan.bVidEnable) { + /*Do filter on outer VID + Filter Outer VID (Total 13 bits) + key 0 BIT 15 + key 1 BIT 11:0 + Set nVidVal + */ + tbl_prog.key[0] |= ((parm->sFilter.sOuterVlan.nVidVal & 0x1) << 15); + tbl_prog.key[1] |= ((parm->sFilter.sOuterVlan.nVidVal & 0x1FFE) >> 1); + } else { + /*Do not filter on outer VID + Filter Outer VID (Total 13 bits) + key 0 BIT 15 + key 1 BIT 11:0 + Set 4096 + */ + tbl_prog.key[0] |= ((4096 & 0x1) << 15); + tbl_prog.key[1] |= ((4096 & 0x1FFE) >> 1); + } + + /*Filter out outer TPID/DEI*/ + switch (parm->sFilter.sOuterVlan.eTpid) { + /** Do not filter TPID. */ + case GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER: + /*Do not filter on outer TPID + Filter Outer TPID key 0 BIT 14:12 set to 0 */ + tbl_prog.key[0] &= ~(7 << 12); break; - /** ARP frame (Ethertyp is 0x0806). */ - case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP: - tbl_prog.key[2] |= 3; + + /** TPID is 0x8100. key 0 BIT 14:12 set 4*/ + case GSW_EXTENDEDVLAN_FILTER_TPID_8021Q: + tbl_prog.key[0] |= (4 << 12); break; - /** IPv6 IPoE frame (Ethertyp is 0x86DD). */ - case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE: - tbl_prog.key[2] |= 4; + + /** TPID is global configured value. */ + case GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE: + switch (parm->sFilter.sOuterVlan.eDei) { + /** Do not filter (don't care) key 0 BIT 14:12 set 5 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER: + tbl_prog.key[0] |= (5 << 12); + break; + + /** DEI=0 key 0 BIT 14:12 set 6 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_0: + tbl_prog.key[0] |= (6 << 12); + break; + + /** DEI=1 key 0 BIT 14:12 set 7 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_1: + tbl_prog.key[0] |= (7 << 12); + break; + } + break; + } + + break; + + /** There is tag but no criteria. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER: + CLEAR_U16(tbl_prog.key[1]); + CLEAR_U16(tbl_prog.key[0]); + + /*Do not filter on outer priority + Filter Outer PCP key 1 BIT 15:12 set to 8 */ + tbl_prog.key[1] |= (8 << 12); + + /*Do not filter on outer VID + Filter Outer VID (Total 13 bits) + key 0 BIT 15 + key 1 BIT 11:0 + Set 4096 + */ + tbl_prog.key[0] |= ((4096 & 0x1) << 15); + tbl_prog.key[1] |= ((4096 & 0x1FFE) >> 1); + + /*Do not filter on outer TPID + Filter Outer PCP key 0 BIT 14:12 set to 0 */ + tbl_prog.key[0] &= ~(7 << 12); + break; + + /** Default entry if no other rule applies. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT: + CLEAR_U16(tbl_prog.key[1]); + /*Default entry if no other rule applies + Filter Outer PCP key 1 BIT 15:12 set to 14 */ + tbl_prog.key[1] |= (14 << 12); + break; + + /** There is no tag. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG: + CLEAR_U16(tbl_prog.key[1]); + /*No Outer Tag + Filter Outer PCP key 1 BIT 15:12 set to 15 */ + tbl_prog.key[1] |= (15 << 12); + break; + + case GSW_EXTENDEDVLAN_BLOCK_INVALID: + CLEAR_U16(tbl_prog.key[1]); + /*SET BLOCK INVALID - should be set only on outer priority filter + Filter Outer PCP key 1 BIT 15:12 set to 13 */ + tbl_prog.key[1] |= (13 << 12); + break; + + default: + break; } - - - /** Extended VLAN Table Treatment **/ - - /** Number of VLAN tag to remove. val 1 BIT 15:14*/ - tbl_prog.val[1] &= ~(0xC000); - switch(parm->sTreatment.eRemoveTag) { - /* Do not remove VLAN tag. set 0 */ - case GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG: - tbl_prog.val[1] &= ~(0xC000); - break; - /* Remove 1 VLAN tag following DA/SA. set 1*/ - case GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG: - tbl_prog.val[1] |= (1 << 14); - break; - /* Remove 2 VLAN tag following DA/SA. set 2*/ - case GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG: - tbl_prog.val[1] |= (2 << 14); + /*Program inner VLAN Filter*/ + switch (parm->sFilter.sInnerVlan.eType) { + /** There is tag and criteria applies. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL: + CLEAR_U16(tbl_prog.key[3]); + CLEAR_U16(tbl_prog.key[2]); + + if (parm->sFilter.sInnerVlan.bPriorityEnable) { + /*Filter on inner priority + PCP value key 3 BIT 15:12*/ + tbl_prog.key[3] |= ((parm->sFilter.sInnerVlan.nPriorityVal & 0x7) << 12); + } else { + /*Do not filter on inner priority + Filter inner PCP key 3 BIT 15:12 set to 8 */ + tbl_prog.key[3] |= (8 << 12); + } + + if (parm->sFilter.sInnerVlan.bVidEnable) { + /*Do not filter on inner VID + Filter inner VID (Total 13 bits) + key 2 BIT 15 + key 3 BIT 11:0 + Set nVidVal + */ + tbl_prog.key[2] |= ((parm->sFilter.sInnerVlan.nVidVal & 0x1) << 15); + tbl_prog.key[3] |= ((parm->sFilter.sInnerVlan.nVidVal & 0x1FFE) >> 1); + } else { + /*Do not filter on inner VID + Filter inner VID (Total 13 bits) + key 2 BIT 15 + key 3 BIT 11:0 + Set 4096 + */ + tbl_prog.key[2] |= ((4096 & 0x1) << 15); + tbl_prog.key[3] |= ((4096 & 0x1FFE) >> 1); + } + + /*Filter out inner TPID/DEI*/ + switch (parm->sFilter.sInnerVlan.eTpid) { + /** Do not filter TPID. */ + case GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER: + /*Do not filter on inner TPID + Filter inner TPID key 2 BIT 14:12 set to 0 */ + tbl_prog.key[2] &= ~(7 << 12); break; - /* Discard upstream traffic. set 3*/ - case GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM: - tbl_prog.val[1] |= (3 << 14); + + /** TPID is 0x8100. key 2 BIT 14:12 set 4*/ + case GSW_EXTENDEDVLAN_FILTER_TPID_8021Q: + tbl_prog.key[2] |= (4 << 12); break; - } - /** Enable outer VLAN tag add/modification. */ - if(parm->sTreatment.bAddOuterVlan) { - /*Treatment for outer Priority val 1 BIT 3:0*/ - tbl_prog.val[1] &= ~(0xF); - switch(parm->sTreatment.sOuterVlan.ePriorityMode) { - /* Add an Outer Tag and set priority with given value. */ - case GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL: - tbl_prog.val[1] |= (parm->sTreatment.sOuterVlan.ePriorityVal & 0x7); - break; - /* Add an Outer Tag and Priority value is copied from inner VLAN tag of received packet. set 8*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY: - tbl_prog.val[1] |= 8; + /** TPID is global configured value. */ + case GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE: + switch (parm->sFilter.sInnerVlan.eDei) { + /** Do not filter (don't care) key 2 BIT 14:12 set 5 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER: + tbl_prog.key[2] |= (5 << 12); break; - /*Add an Outer Tag and Priority value is copied from outer VLAN tag of received packet. set 9 */ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY: - tbl_prog.val[1] |= 9; + + /** DEI=0 key 2 BIT 14:12 set 6 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_0: + tbl_prog.key[2] |= (6 << 12); break; - /* Add an Outer Tag and Priority value is derived from DSCP field of received packet. set 10 - Priority Value is set as per DSCP to PCP mapping attribute*/ - case GSW_EXTENDEDVLAN_TREATMENT_DSCP: - tbl_prog.val[1] |= 10; - bDscp2PcpMapEnable = 1; + + /** DEI=1 key 2 BIT 14:12 set 7 */ + case GSW_EXTENDEDVLAN_FILTER_DEI_1: + tbl_prog.key[2] |= (7 << 12); break; + } + + break; } - - /*Treatment for outer VID val 0 BIT 15:3*/ - tbl_prog.val[0] &= ~(0xFFF8); - switch(parm->sTreatment.sOuterVlan.eVidMode) { - /* Set VID with given value. */ - case GSW_EXTENDEDVLAN_TREATMENT_VID_VAL: - tbl_prog.val[0] |= ((parm->sTreatment.sOuterVlan.eVidVal & 0xFFF) << 3); - break; - /* VID is copied from inner VLAN tag of received packet. set 4096*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_VID: - tbl_prog.val[0] |= (4096 << 3); - break; - /* VID is copied from outer VLAN tag of received packet.set 4097 */ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID: - tbl_prog.val[0] |= (4097 << 3); - break; + + break; + + /** There is tag but no criteria. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER: + CLEAR_U16(tbl_prog.key[3]); + CLEAR_U16(tbl_prog.key[2]); + + /*Do not filter on inner priority + Filter inner PCP key 3 BIT 15:12 set to 8 */ + tbl_prog.key[3] |= (8 << 12); + + /*Do not filter on inner VID + Filter inner VID (Total 13 bits) + key 2 BIT 15 + key 3 BIT 11:0 + Set 4096 + */ + tbl_prog.key[2] |= ((4096 & 0x1) << 15); + tbl_prog.key[3] |= ((4096 & 0x1FFE) >> 1); + + /*Do not filter on inner TPID + Filter inner PCP key 2 BIT 14:12 set to 0 */ + tbl_prog.key[2] &= ~(7 << 12); + break; + + /** Default entry if no other rule applies. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT: + CLEAR_U16(tbl_prog.key[3]); + + /*Default entry if no other rule applies + Filter inner PCP key 3 BIT 15:12 set to 14 */ + tbl_prog.key[3] |= (14 << 12); + break; + + /** There is no tag. */ + case GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG: + CLEAR_U16(tbl_prog.key[3]); + /*No inner Tag + Filter inner PCP key 3 BIT 15:12 set to 15 */ + tbl_prog.key[3] |= (15 << 12); + break; + + default: + break; + } + + /*Filter Ether type key 2 BIT 4:0*/ + tbl_prog.key[2] &= ~(0x1F); + + switch (parm->sFilter.eEtherType) { + /** Do not filter Ether Type*/ + case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER: + tbl_prog.key[2] |= 0; + break; + + /** IPoE frame (Ethertyp is 0x0800). */ + case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE: + tbl_prog.key[2] |= 1; + break; + + /** PPPoE frame (Ethertyp is 0x8863 or 0x8864). */ + case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE: + tbl_prog.key[2] |= 2; + break; + + /** ARP frame (Ethertyp is 0x0806). */ + case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP: + tbl_prog.key[2] |= 3; + break; + + /** IPv6 IPoE frame (Ethertyp is 0x86DD). */ + case GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE: + tbl_prog.key[2] |= 4; + break; + } + + + + /** Extended VLAN Table Treatment **/ + + /** Number of VLAN tag to remove. val 1 BIT 15:14*/ + tbl_prog.val[1] &= ~(0xC000); + + switch (parm->sTreatment.eRemoveTag) { + /* Do not remove VLAN tag. set 0 */ + case GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG: + tbl_prog.val[1] &= ~(0xC000); + break; + + /* Remove 1 VLAN tag following DA/SA. set 1*/ + case GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG: + tbl_prog.val[1] |= (1 << 14); + break; + + /* Remove 2 VLAN tag following DA/SA. set 2*/ + case GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG: + tbl_prog.val[1] |= (2 << 14); + break; + + /* Discard upstream traffic. set 3*/ + case GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM: + tbl_prog.val[1] |= (3 << 14); + break; + } + + /** Enable outer VLAN tag add/modification. */ + if (parm->sTreatment.bAddOuterVlan) { + /*Treatment for outer Priority val 1 BIT 3:0*/ + tbl_prog.val[1] &= ~(0xF); + + switch (parm->sTreatment.sOuterVlan.ePriorityMode) { + /* Add an Outer Tag and set priority with given value. */ + case GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL: + tbl_prog.val[1] |= (parm->sTreatment.sOuterVlan.ePriorityVal & 0x7); + break; + + /* Add an Outer Tag and Priority value is copied from inner VLAN tag of received packet. set 8*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY: + tbl_prog.val[1] |= 8; + break; + + /*Add an Outer Tag and Priority value is copied from outer VLAN tag of received packet. set 9 */ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY: + tbl_prog.val[1] |= 9; + break; + + /* Add an Outer Tag and Priority value is derived from DSCP field of received packet. set 10 + Priority Value is set as per DSCP to PCP mapping attribute*/ + case GSW_EXTENDEDVLAN_TREATMENT_DSCP: + tbl_prog.val[1] |= 10; + bDscp2PcpMapEnable = 1; + break; + } + + /*Treatment for outer VID val 0 BIT 15:3*/ + tbl_prog.val[0] &= ~(0xFFF8); + + switch (parm->sTreatment.sOuterVlan.eVidMode) { + /* Set VID with given value. */ + case GSW_EXTENDEDVLAN_TREATMENT_VID_VAL: + tbl_prog.val[0] |= ((parm->sTreatment.sOuterVlan.eVidVal & 0xFFF) << 3); + break; + + /* VID is copied from inner VLAN tag of received packet. set 4096*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_VID: + tbl_prog.val[0] |= (4096 << 3); + break; + + /* VID is copied from outer VLAN tag of received packet.set 4097 */ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID: + tbl_prog.val[0] |= (4097 << 3); + break; } - + /*Treatment for outer TPID/DEI val 0 BIT 2:0*/ tbl_prog.val[0] &= ~(0x7); - switch(parm->sTreatment.sOuterVlan.eTpid) { - /* TPID is copied from inner VLAN tag of received packet.set 0 */ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID: - tbl_prog.val[0] &= ~(0x7); + + switch (parm->sTreatment.sOuterVlan.eTpid) { + /* TPID is copied from inner VLAN tag of received packet.set 0 */ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID: + tbl_prog.val[0] &= ~(0x7); + break; + + /* TPID is copied from outer VLAN tag of received packet. set 1*/ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID: + tbl_prog.val[0] |= 1; + break; + + /* TPID is 0x8100. */ + case GSW_EXTENDEDVLAN_TREATMENT_8021Q: + tbl_prog.val[0] |= 4; + break; + + /* TPID is global configured value. */ + case GSW_EXTENDEDVLAN_TREATMENT_VTETYPE: + switch (parm->sTreatment.sOuterVlan.eDei) { + /* DEI (if applicable) is copied from inner VLAN tag of received packet. set 2*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI: + tbl_prog.val[0] |= 2; break; - /* TPID is copied from outer VLAN tag of received packet. set 1*/ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID: - tbl_prog.val[0] |= 1; + + /* DEI (if applicable) is copied from outer VLAN tag of received packet. set 3*/ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI: + tbl_prog.val[0] |= 3; break; - /* TPID is 0x8100. */ - case GSW_EXTENDEDVLAN_TREATMENT_8021Q: - tbl_prog.val[0] |= 4; + + /* DEI is 0. set 6*/ + case GSW_EXTENDEDVLAN_TREATMENT_DEI_0: + tbl_prog.val[0] |= 6; break; - /* TPID is global configured value. */ - case GSW_EXTENDEDVLAN_TREATMENT_VTETYPE: - switch(parm->sTreatment.sOuterVlan.eDei) { - /* DEI (if applicable) is copied from inner VLAN tag of received packet. set 2*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI: - tbl_prog.val[0] |= 2; - break; - /* DEI (if applicable) is copied from outer VLAN tag of received packet. set 3*/ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI: - tbl_prog.val[0] |= 3; - break; - /* DEI is 0. set 6*/ - case GSW_EXTENDEDVLAN_TREATMENT_DEI_0: - tbl_prog.val[0] |= 6; - break; - /* DEI is 1. set 7*/ - case GSW_EXTENDEDVLAN_TREATMENT_DEI_1: - tbl_prog.val[0] |= 7; - break; - } + + /* DEI is 1. set 7*/ + case GSW_EXTENDEDVLAN_TREATMENT_DEI_1: + tbl_prog.val[0] |= 7; break; + } + + break; } - - /* }*/ + + /* }*/ } else { /*DO Not Add an Outer Tag. val 1 BIT 3:0 set 15*/ tbl_prog.val[1] &= ~(0xF); @@ -15047,85 +19438,100 @@ GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) } /** Enable inner VLAN tag add/modification. */ - if(parm->sTreatment.bAddInnerVlan) { + if (parm->sTreatment.bAddInnerVlan) { /*Treatment for inner Priority val 3 BIT 3:0*/ tbl_prog.val[3] &= ~(0xF); - switch(parm->sTreatment.sInnerVlan.ePriorityMode) { - /* Add an inner Tag and set priority with given value. */ - case GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL: - tbl_prog.val[3] |= (parm->sTreatment.sInnerVlan.ePriorityVal & 0x7); - break; - /* Add an inner Tag and Priority value is copied from inner VLAN tag of received packet. set 8*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY: - tbl_prog.val[3] |= 8; - break; - /*Add an inner Tag and Priority value is copied from outer VLAN tag of received packet. set 9 */ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY: - tbl_prog.val[3] |= 9; - break; - /* Add an inner Tag and Priority value is derived from DSCP field of received packet. set 10 - Priority Value is set as per DSCP to PCP mapping attribute*/ - case GSW_EXTENDEDVLAN_TREATMENT_DSCP: - tbl_prog.val[3] |= 10; - bDscp2PcpMapEnable = 1; - break; + + switch (parm->sTreatment.sInnerVlan.ePriorityMode) { + /* Add an inner Tag and set priority with given value. */ + case GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL: + tbl_prog.val[3] |= (parm->sTreatment.sInnerVlan.ePriorityVal & 0x7); + break; + + /* Add an inner Tag and Priority value is copied from inner VLAN tag of received packet. set 8*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY: + tbl_prog.val[3] |= 8; + break; + + /*Add an inner Tag and Priority value is copied from outer VLAN tag of received packet. set 9 */ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY: + tbl_prog.val[3] |= 9; + break; + + /* Add an inner Tag and Priority value is derived from DSCP field of received packet. set 10 + Priority Value is set as per DSCP to PCP mapping attribute*/ + case GSW_EXTENDEDVLAN_TREATMENT_DSCP: + tbl_prog.val[3] |= 10; + bDscp2PcpMapEnable = 1; + break; } - + /*Treatment for inner VID val 2 BIT 15:3*/ tbl_prog.val[2] &= ~(0xFFF8); - switch(parm->sTreatment.sInnerVlan.eVidMode) { - /* Set VID with given value. */ - case GSW_EXTENDEDVLAN_TREATMENT_VID_VAL: - tbl_prog.val[2] |= ((parm->sTreatment.sInnerVlan.eVidVal & 0xFFF) << 3); - break; - /* VID is copied from inner VLAN tag of received packet. set 4096*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_VID: - tbl_prog.val[2] |= (4096 << 3); - break; - /* VID is copied from outer VLAN tag of received packet.set 4097 */ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID: - tbl_prog.val[2] |= (4097 << 3); - break; + + switch (parm->sTreatment.sInnerVlan.eVidMode) { + /* Set VID with given value. */ + case GSW_EXTENDEDVLAN_TREATMENT_VID_VAL: + tbl_prog.val[2] |= ((parm->sTreatment.sInnerVlan.eVidVal & 0xFFF) << 3); + break; + + /* VID is copied from inner VLAN tag of received packet. set 4096*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_VID: + tbl_prog.val[2] |= (4096 << 3); + break; + + /* VID is copied from outer VLAN tag of received packet.set 4097 */ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID: + tbl_prog.val[2] |= (4097 << 3); + break; } - + /*Treatment for inner TPID/DEI val 2 BIT 2:0*/ tbl_prog.val[2] &= ~(0x7); - switch(parm->sTreatment.sInnerVlan.eTpid) { - /* TPID is copied from inner VLAN tag of received packet.set 0 */ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID: - tbl_prog.val[2] &= ~(0x7); + + switch (parm->sTreatment.sInnerVlan.eTpid) { + /* TPID is copied from inner VLAN tag of received packet.set 0 */ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID: + tbl_prog.val[2] &= ~(0x7); + break; + + /* TPID is copied from outer VLAN tag of received packet. set 1*/ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID: + tbl_prog.val[2] |= 1; + break; + + /* TPID is 0x8100. */ + case GSW_EXTENDEDVLAN_TREATMENT_8021Q: + tbl_prog.val[2] |= 4; + break; + + /* TPID is global configured value. */ + case GSW_EXTENDEDVLAN_TREATMENT_VTETYPE: + switch (parm->sTreatment.sInnerVlan.eDei) { + /* DEI (if applicable) is copied from inner VLAN tag of received packet. set 2*/ + case GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI: + tbl_prog.val[2] |= 2; break; - /* TPID is copied from outer VLAN tag of received packet. set 1*/ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID: - tbl_prog.val[2] |= 1; + + /* DEI (if applicable) is copied from outer VLAN tag of received packet. set 3*/ + case GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI: + tbl_prog.val[2] |= 3; break; - /* TPID is 0x8100. */ - case GSW_EXTENDEDVLAN_TREATMENT_8021Q: - tbl_prog.val[2] |= 4; + + /* DEI is 0. set 6*/ + case GSW_EXTENDEDVLAN_TREATMENT_DEI_0: + tbl_prog.val[2] |= 6; break; - /* TPID is global configured value. */ - case GSW_EXTENDEDVLAN_TREATMENT_VTETYPE: - switch(parm->sTreatment.sInnerVlan.eDei) { - /* DEI (if applicable) is copied from inner VLAN tag of received packet. set 2*/ - case GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI: - tbl_prog.val[2] |= 2; - break; - /* DEI (if applicable) is copied from outer VLAN tag of received packet. set 3*/ - case GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI: - tbl_prog.val[2] |= 3; - break; - /* DEI is 0. set 6*/ - case GSW_EXTENDEDVLAN_TREATMENT_DEI_0: - tbl_prog.val[2] |= 6; - break; - /* DEI is 1. set 7*/ - case GSW_EXTENDEDVLAN_TREATMENT_DEI_1: - tbl_prog.val[2] |= 7; - break; - } + + /* DEI is 1. set 7*/ + case GSW_EXTENDEDVLAN_TREATMENT_DEI_1: + tbl_prog.val[2] |= 7; break; + } + + break; } - + /*}*/ } else { /*DO Not Add an inner Tag. val 3 BIT 3:0 set 15*/ @@ -15133,203 +19539,206 @@ GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) tbl_prog.val[3] |= 15; } - /** Treatment Bridge port + /** Treatment Bridge port val 4 BIT 8 to enable new bridge port treatment - val 4 BIT 7:0 for new bridge port id + val 4 BIT 7:0 for new bridge port id **/ tbl_prog.val[4] &= ~(0x1FF); + /*(0..127 no action and 128..255 re-assign bridge port id*/ - if(parm->sTreatment.bReassignBridgePort) - { + if (parm->sTreatment.bReassignBridgePort) { tbl_prog.val[4] |= (1 << 8); tbl_prog.val[4] |= (parm->sTreatment.nNewBridgePortId & 0xFF); } - /** Treatment DSCP + /** Treatment DSCP val 4 BIT 15 to enable new DSCP treatment val 4 BIT 14:9 for new DSCP value **/ tbl_prog.val[4] &= ~(0xFE00); + /*(0..63 no action and 64..127 New DSCP in bit 5 to 0*/ - if(parm->sTreatment.bNewDscpEnable) - { + if (parm->sTreatment.bNewDscpEnable) { tbl_prog.val[4] |= (1 << 15); tbl_prog.val[4] |= ((parm->sTreatment.nNewDscp & 0x3F) << 9); } - /** Treatment Traffic Class + /** Treatment Traffic Class val 5 BIT 13 to enable new Traffic class treatment val 5 BIT 12:9 for new Traffic class value **/ tbl_prog.val[5] &= ~(0x3E00); + /*(0..15 no action and 16..31 New Traffic class in bit 3 to 0*/ - if(parm->sTreatment.bNewTrafficClassEnable) - { + if (parm->sTreatment.bNewTrafficClassEnable) { tbl_prog.val[5] |= (1 << 13); tbl_prog.val[5] |= ((parm->sTreatment.nNewTrafficClass & 0xF) << 9); } - /** Treatment Metering + /** Treatment Metering val 5 BIT 8 to enable Metering val 5 BIT 7:0 for New Meter ID **/ tbl_prog.val[5] &= ~(0x1FF); + /* New meter ID TODO - KEEP CHECK on METERID. - Meter should be allocated with \ref GSW_QOS_METER_ALLOC before extended - VLAN treatment is added. If this extended VLAN treatment is deleted, - this meter should be released with \ref GSW_QOS_METER_FREE. + Meter should be allocated with \ref GSW_QOS_METER_ALLOC before extended + VLAN treatment is added. If this extended VLAN treatment is deleted, + this meter should be released with \ref GSW_QOS_METER_FREE. */ - if(parm->sTreatment.bNewMeterEnable) - { - meterid=parm->sTreatment.sNewTrafficMeterId; - /*This below field enable indicates that this meter id is - already assigned and it's idx recorded for this Exvlan tbl. - If next time the user update this meter field with different meter idx !! - or wanted to allocate a new meter idx ??!! may happen by mistake ??!! - the previous meter idx must be released from this Exvlan tbl*/ - - if(gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) - { - if(gswdev->extendvlan_idx.vlan_idx[idx].MeterId != - meterid) - { - /*release the usage of previous meter idx*/ - gswdev->meter_idx[gswdev->extendvlan_idx.vlan_idx[idx].MeterId].IndexInUsageCnt--; - gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned=0; - gswdev->extendvlan_idx.vlan_idx[idx].MeterId=0; - } + if (parm->sTreatment.bNewMeterEnable) { + meterid = parm->sTreatment.sNewTrafficMeterId; + /*This below field enable indicates that this meter id is + already assigned and it's idx recorded for this Exvlan tbl. + If next time the user update this meter field with different meter idx !! + or wanted to allocate a new meter idx ??!! may happen by mistake ??!! + the previous meter idx must be released from this Exvlan tbl*/ + + if (gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) { + if (gswdev->extendvlan_idx.vlan_idx[idx].MeterId != + meterid) { + /*release the usage of previous meter idx*/ + gswdev->meter_idx[gswdev->extendvlan_idx.vlan_idx[idx].MeterId].IndexInUsageCnt--; + gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned = 0; + gswdev->extendvlan_idx.vlan_idx[idx].MeterId = 0; + } + } + + /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated + before calling Exvlan configuration + If not in use return ERROR + */ + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment + for this Exvlan id*/ + if (!gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) { + gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned = 1; + gswdev->extendvlan_idx.vlan_idx[idx].MeterId + = meterid; + /*Since this meter id can be shared,Increment the it's usage count*/ + gswdev->meter_idx[meterid].IndexInUsageCnt++; } - /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling Exvlan configuration - If not in use return ERROR - */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment - for this Exvlan id*/ - if(!gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) - { - gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned=1; - gswdev->extendvlan_idx.vlan_idx[idx].MeterId - =meterid; - /*Since this meter id can be shared,Increment the it's usage count*/ - gswdev->meter_idx[meterid].IndexInUsageCnt++; - } - tbl_prog.val[5] |= (1 << 8); - tbl_prog.val[5] |= (parm->sTreatment.sNewTrafficMeterId & 0xFF); - } else { - pr_err("ERROR :Meter Id %d not alocated,Call Meter Alloc before Exvlan configuration\n",meterid); - return GSW_statusErr; - } - } - + tbl_prog.val[5] |= (1 << 8); + tbl_prog.val[5] |= (parm->sTreatment.sNewTrafficMeterId & 0xFF); + } else { + pr_err("ERROR :Meter Id %d not alocated,Call Meter Alloc before Exvlan configuration\n", meterid); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + + } + } + /** Enable loopback. val 5 BIT 14*/ tbl_prog.val[5] &= ~(0x4000); - if(parm->sTreatment.bLoopbackEnable) + + if (parm->sTreatment.bLoopbackEnable) tbl_prog.val[5] |= (1 << 14); - + /** Enable destination/source MAC address swap. val 5 BIT 15*/ tbl_prog.val[5] &= ~(0x8000); - if(parm->sTreatment.bDaSaSwapEnable) + + if (parm->sTreatment.bDaSaSwapEnable) tbl_prog.val[5] |= (1 << 15); /** Enable traffic mirrored to the monitoring port. val 3 BIT 15 */ tbl_prog.val[3] &= ~(0x8000); - if(parm->sTreatment.bMirrorEnable) + + if (parm->sTreatment.bMirrorEnable) tbl_prog.val[3] |= (1 << 15); - + /** Treatment for DSCP2PCP **/ - if(bDscp2PcpMapEnable) - { + if (bDscp2PcpMapEnable) { /* Check for match in DSCP2PCP Map for each index - 0 to 7 DSCP2PCP pointers*/ - dscp2pcpmatch_found =0; - for(idx=0;idx <=7 && !dscp2pcpmatch_found;idx++) - { + dscp2pcpmatch_found = 0; + + for (idx = 0; idx <= 7 && !dscp2pcpmatch_found; idx++) { /*Check only the dscp2pcp pointer which is in InUse*/ - if (gswdev->dscp2pcp_idx[idx].IndexInUse && - gswdev->dscp2pcp_idx[idx].IndexInUsageCnt) - { + if (gswdev->dscp2pcp_idx[idx].IndexInUse && + gswdev->dscp2pcp_idx[idx].IndexInUsageCnt) { memset(&dscp2pcp_get, 0, sizeof(GSW_DSCP2PCP_map_t)); - dscp2pcp_get.nIndex=idx; - ret=GSW_QOS_Dscp2PcpTableGet(cdev, &dscp2pcp_get); - if(ret==GSW_statusErr) { + dscp2pcp_get.nIndex = idx; + ret = GSW_QOS_Dscp2PcpTableGet(cdev, &dscp2pcp_get); + + if (ret == GSW_statusErr) { pr_err("ERROR: GSW_QOS_Dscp2PcpTableGet"); - return ret; + goto UNLOCK_AND_RETURN; } + /*check and compare DSCP 0 to 63 entry address's pcp value*/ - all_entry_match=1; - for(dscp=0;dscp<64 && all_entry_match;dscp++) { + all_entry_match = 1; + + for (dscp = 0; dscp < 64 && all_entry_match; dscp++) { if (parm->sTreatment.nDscp2PcpMap[dscp] != dscp2pcp_get.nMap[dscp]) - all_entry_match=0; + all_entry_match = 0; } + /*All dscp 0 to 63 entry address's pcp value match for this pointer/idx Record this dscp2pcp pointer*/ - if(all_entry_match) - { - dscp2pcp_pointer=idx; - dscp2pcpmatch_found=1; - pr_err("dscp2pcpmatch_found : dscp2pcp_pointer = %d\n",dscp2pcp_pointer); + if (all_entry_match) { + dscp2pcp_pointer = idx; + dscp2pcpmatch_found = 1; + pr_err("dscp2pcpmatch_found : dscp2pcp_pointer = %d\n", dscp2pcp_pointer); } } } - - if(!dscp2pcpmatch_found) - { + + if (!dscp2pcpmatch_found) { /*If no match found in the dscp2pcp table,search for an empty slot*/ - for(idx=0;idx <=7 && !empty_dscp2pcptblslot_found;idx++) - { - if (!gswdev->dscp2pcp_idx[idx].IndexInUse && - gswdev->dscp2pcp_idx[idx].IndexInUsageCnt == 0) - { - empty_dscp2pcptblslot_found=1; - dscp2pcp_pointer=idx; + for (idx = 0; idx <= 7 && !empty_dscp2pcptblslot_found; idx++) { + if (!gswdev->dscp2pcp_idx[idx].IndexInUse && + gswdev->dscp2pcp_idx[idx].IndexInUsageCnt == 0) { + empty_dscp2pcptblslot_found = 1; + dscp2pcp_pointer = idx; } } + /*If the empty slot found,allocate and set the sTreatment.nDscp2PcpMap[64] to corresponding dscp2pcp table index */ - if(empty_dscp2pcptblslot_found) - { - pr_err("empty_dscp2pcptblslot_found : dscp2pcp_pointer = %d\n",dscp2pcp_pointer); - memcpy(dscp2pcp_set.nMap,parm->sTreatment.nDscp2PcpMap, (sizeof(u8) * 64)); - dscp2pcp_set.nIndex=dscp2pcp_pointer; - ret=GSW_QOS_Dscp2PcpTableSet(cdev, &dscp2pcp_set); - if(ret==GSW_statusErr) { + if (empty_dscp2pcptblslot_found) { + pr_err("empty_dscp2pcptblslot_found : dscp2pcp_pointer = %d\n", dscp2pcp_pointer); + memcpy(dscp2pcp_set.nMap, parm->sTreatment.nDscp2PcpMap, (sizeof(u8) * 64)); + dscp2pcp_set.nIndex = dscp2pcp_pointer; + ret = GSW_QOS_Dscp2PcpTableSet(cdev, &dscp2pcp_set); + + if (ret == GSW_statusErr) { pr_err("ERROR: GSW_QOS_Dscp2PcpTableSet\n"); - return ret; + goto UNLOCK_AND_RETURN; } } else { pr_err("dscp2pcp table full\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } - - /*This below field enable indicates that this dscp2pcp pointer is + + /*This below field enable indicates that this dscp2pcp pointer is already assigned and it's idx recorded for this Extended Vlan index. - If next time user calls EXVlanAdd again for same idx with different + If next time user calls EXVlanAdd again for same idx with different nDscp2PcpMap array value!! - may happen by mistake ??!! + may happen by mistake ??!! the search may give different pointer or allocate new pointer ??!! - so the previous dscp2pcp pointer must be released from this + so the previous dscp2pcp pointer must be released from this Extended VLAN idx*/ - idx=parm->nExtendedVlanBlockId + parm->nEntryIndex; - if(gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) - { + idx = parm->nExtendedVlanBlockId + parm->nEntryIndex; + + if (gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) { int old_dscp2pcp_pointer; - if(gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer != - dscp2pcp_pointer) - { - old_dscp2pcp_pointer=gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer; + + if (gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer != + dscp2pcp_pointer) { + old_dscp2pcp_pointer = gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer; /*release the usage of previous DSCP2PCP pointer*/ gswdev->dscp2pcp_idx[old_dscp2pcp_pointer].IndexInUsageCnt--; - if(gswdev->dscp2pcp_idx[old_dscp2pcp_pointer].IndexInUsageCnt - == 0) - { - gswdev->dscp2pcp_idx[old_dscp2pcp_pointer].IndexInUse=0; + + if (gswdev->dscp2pcp_idx[old_dscp2pcp_pointer].IndexInUsageCnt + == 0) { + gswdev->dscp2pcp_idx[old_dscp2pcp_pointer].IndexInUse = 0; } - gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned=0; - gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer=0; + + gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned = 0; + gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer = 0; } } @@ -15337,53 +19746,71 @@ GSW_return_t GSW_ExtendedVlanSet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) Set the recorded 0..7 dscp2pcp pointer*/ tbl_prog.val[3] &= ~(0x70); tbl_prog.val[3] |= ((dscp2pcp_pointer & 0x7) << 4); - + /* dscp2pcp pointer usage count can be incremented only once for this vlan idx*/ - if(!gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) - { - gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned=1; + if (!gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) { + gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned = 1; gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer - =dscp2pcp_pointer; + = dscp2pcp_pointer; /*Since this DSCP2PCP can be shared,Increment the it's usage count*/ - gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse=1; + gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse = 1; gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUsageCnt++; } - } + } + /*Address-based write*/ gsw_pce_table_write(cdev, &tbl_prog); - return GSW_statusOk; + ret = GSW_statusOk; +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } -GSW_return_t GSW_ExtendedVlanGet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) +GSW_return_t GSW_ExtendedVlanGet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 ret; - u32 idx=0,dscp2pcp_pointer,tpid_dei,ethtype,removetag; + u32 idx = 0, dscp2pcp_pointer, tpid_dei, ethtype, removetag; u32 bDscp2PcpMapEnable = 0; GSW_DSCP2PCP_map_t dscp2pcp_get; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - idx=parm->nExtendedVlanBlockId + parm->nEntryIndex; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + idx = parm->nExtendedVlanBlockId + parm->nEntryIndex; + if (idx >= gswdev->num_of_extendvlan) { - pr_err("ERROR : idx %d >= gswdev->num_of_extendvlan \n",idx); - return GSW_statusErr; - } + pr_err("ERROR : idx %d >= gswdev->num_of_extendvlan \n", idx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Index does not belongs to this ExtendedVlanBlock*/ - if(gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != parm->nExtendedVlanBlockId) { - pr_err("ERROR : VlanBlockId %d != parm->nExtendedVlanBlockId %d \n", - gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId,parm->nExtendedVlanBlockId); - return GSW_statusErr; - } + if (gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != parm->nExtendedVlanBlockId) { + pr_err("ERROR : VlanBlockId %d != parm->nExtendedVlanBlockId %d \n", + gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId, parm->nExtendedVlanBlockId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Index is not in USE*/ if (!gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse) { - pr_err("ERROR : idx %d not in Use \n",idx); - return GSW_statusErr; + pr_err("ERROR : idx %d not in Use \n", idx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_EXTVLAN_INDEX; CLEAR_U16(tbl_prog.pcindex); @@ -15393,403 +19820,467 @@ GSW_return_t GSW_ExtendedVlanGet(void *cdev, GSW_EXTENDEDVLAN_config_t *parm) gsw_pce_table_read(cdev, &tbl_prog); /*Get Outer VLAn Filter*/ - parm->sFilter.sOuterVlan.nPriorityVal= ((tbl_prog.key[1] >> 12) & 0xf); + parm->sFilter.sOuterVlan.nPriorityVal = ((tbl_prog.key[1] >> 12) & 0xf); parm->sFilter.sOuterVlan.nVidVal |= ((tbl_prog.key[0] & 0x8000) >> 15); parm->sFilter.sOuterVlan.nVidVal |= ((tbl_prog.key[1] & 0xFFF) << 1); tpid_dei = ((tbl_prog.key[0] & 0x7000) >> 12); - if(parm->sFilter.sOuterVlan.nPriorityVal == 8 && - parm->sFilter.sOuterVlan.nVidVal == 4096 && - tpid_dei == 0) - { - parm->sFilter.sOuterVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER; - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sOuterVlan.bVidEnable=0; - parm->sFilter.sOuterVlan.bPriorityEnable=0; - } else if (parm->sFilter.sOuterVlan.nPriorityVal == 14) - { - parm->sFilter.sOuterVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT; - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sOuterVlan.bVidEnable=0; - parm->sFilter.sOuterVlan.bPriorityEnable=0; - } else if (parm->sFilter.sOuterVlan.nPriorityVal == 15) - { - parm->sFilter.sOuterVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG; - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sOuterVlan.bVidEnable=0; - parm->sFilter.sOuterVlan.bPriorityEnable=0; - } else if (parm->sFilter.sOuterVlan.nPriorityVal == 13) - { - parm->sFilter.sOuterVlan.eType=GSW_EXTENDEDVLAN_BLOCK_INVALID; - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sOuterVlan.bVidEnable=0; - parm->sFilter.sOuterVlan.bPriorityEnable=0; - } else - { - parm->sFilter.sOuterVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL; - if(parm->sFilter.sOuterVlan.nPriorityVal != 8) - parm->sFilter.sOuterVlan.bPriorityEnable=1; + if (parm->sFilter.sOuterVlan.nPriorityVal == 8 && + parm->sFilter.sOuterVlan.nVidVal == 4096 && + tpid_dei == 0) { + parm->sFilter.sOuterVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER; + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sOuterVlan.bVidEnable = 0; + parm->sFilter.sOuterVlan.bPriorityEnable = 0; + } else if (parm->sFilter.sOuterVlan.nPriorityVal == 14) { + parm->sFilter.sOuterVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT; + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sOuterVlan.bVidEnable = 0; + parm->sFilter.sOuterVlan.bPriorityEnable = 0; + } else if (parm->sFilter.sOuterVlan.nPriorityVal == 15) { + parm->sFilter.sOuterVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG; + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sOuterVlan.bVidEnable = 0; + parm->sFilter.sOuterVlan.bPriorityEnable = 0; + } else if (parm->sFilter.sOuterVlan.nPriorityVal == 13) { + parm->sFilter.sOuterVlan.eType = GSW_EXTENDEDVLAN_BLOCK_INVALID; + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sOuterVlan.bVidEnable = 0; + parm->sFilter.sOuterVlan.bPriorityEnable = 0; + } else { + parm->sFilter.sOuterVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL; + + if (parm->sFilter.sOuterVlan.nPriorityVal != 8) + parm->sFilter.sOuterVlan.bPriorityEnable = 1; else - parm->sFilter.sOuterVlan.bPriorityEnable=0; - if(parm->sFilter.sOuterVlan.nVidVal != 4096) - parm->sFilter.sOuterVlan.bVidEnable=1; + parm->sFilter.sOuterVlan.bPriorityEnable = 0; + + if (parm->sFilter.sOuterVlan.nVidVal != 4096) + parm->sFilter.sOuterVlan.bVidEnable = 1; else - parm->sFilter.sOuterVlan.bVidEnable=0; + parm->sFilter.sOuterVlan.bVidEnable = 0; - switch(tpid_dei) { - case 0: - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 4: - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_8021Q; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 5: - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 6: - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_0; - break; - case 7: - parm->sFilter.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sOuterVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_1; - break; - } + switch (tpid_dei) { + case 0: + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + break; + + case 4: + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_8021Q; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + break; + + case 5: + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + break; + + case 6: + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_0; + break; + + case 7: + parm->sFilter.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sOuterVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_1; + break; + } } - + /*Get Inner VLAn Filter*/ - parm->sFilter.sInnerVlan.nPriorityVal= ((tbl_prog.key[3] >> 12) & 0xf); + parm->sFilter.sInnerVlan.nPriorityVal = ((tbl_prog.key[3] >> 12) & 0xf); parm->sFilter.sInnerVlan.nVidVal |= ((tbl_prog.key[2] & 0x8000) >> 15); parm->sFilter.sInnerVlan.nVidVal |= ((tbl_prog.key[3] & 0xFFF) << 1); tpid_dei = ((tbl_prog.key[2] & 0x7000) >> 12); - - if(parm->sFilter.sInnerVlan.nPriorityVal == 8 && - parm->sFilter.sInnerVlan.nVidVal == 4096 && - tpid_dei == 0) - { - parm->sFilter.sInnerVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER; - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sInnerVlan.bVidEnable=0; - parm->sFilter.sInnerVlan.bPriorityEnable=0; - } else if (parm->sFilter.sInnerVlan.nPriorityVal == 14) - { - parm->sFilter.sInnerVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT; - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sInnerVlan.bVidEnable=0; - parm->sFilter.sInnerVlan.bPriorityEnable=0; - } else if (parm->sFilter.sInnerVlan.nPriorityVal == 15) - { - parm->sFilter.sInnerVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG; - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - parm->sFilter.sInnerVlan.bVidEnable=0; - parm->sFilter.sInnerVlan.bPriorityEnable=0; - } else - { - parm->sFilter.sInnerVlan.eType=GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL; - if(parm->sFilter.sInnerVlan.nPriorityVal != 8) - parm->sFilter.sInnerVlan.bPriorityEnable=1; - else - parm->sFilter.sInnerVlan.bPriorityEnable=0; - if(parm->sFilter.sInnerVlan.nVidVal != 4096) - parm->sFilter.sInnerVlan.bVidEnable=1; - else - parm->sFilter.sInnerVlan.bVidEnable=0; - switch(tpid_dei) { - case 0: - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 4: - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_8021Q; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 5: - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; - break; - case 6: - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_0; - break; + if (parm->sFilter.sInnerVlan.nPriorityVal == 8 && + parm->sFilter.sInnerVlan.nVidVal == 4096 && + tpid_dei == 0) { + parm->sFilter.sInnerVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER; + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sInnerVlan.bVidEnable = 0; + parm->sFilter.sInnerVlan.bPriorityEnable = 0; + } else if (parm->sFilter.sInnerVlan.nPriorityVal == 14) { + parm->sFilter.sInnerVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT; + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sInnerVlan.bVidEnable = 0; + parm->sFilter.sInnerVlan.bPriorityEnable = 0; + } else if (parm->sFilter.sInnerVlan.nPriorityVal == 15) { + parm->sFilter.sInnerVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG; + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; + parm->sFilter.sInnerVlan.bVidEnable = 0; + parm->sFilter.sInnerVlan.bPriorityEnable = 0; + } else { + parm->sFilter.sInnerVlan.eType = GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL; - case 7: - parm->sFilter.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; - parm->sFilter.sInnerVlan.eDei=GSW_EXTENDEDVLAN_FILTER_DEI_1; - break; - } - } + if (parm->sFilter.sInnerVlan.nPriorityVal != 8) + parm->sFilter.sInnerVlan.bPriorityEnable = 1; + else + parm->sFilter.sInnerVlan.bPriorityEnable = 0; - /*Get Ether type filter*/ - ethtype = (tbl_prog.key[2] & 0x1F); - switch(ethtype) { + if (parm->sFilter.sInnerVlan.nVidVal != 4096) + parm->sFilter.sInnerVlan.bVidEnable = 1; + else + parm->sFilter.sInnerVlan.bVidEnable = 0; + + switch (tpid_dei) { case 0: - parm->sFilter.eEtherType= GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER; + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; break; - case 1: - parm->sFilter.eEtherType= GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE; - break; - case 2: - parm->sFilter.eEtherType= GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE; + + case 4: + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_8021Q; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; break; - case 3: - parm->sFilter.eEtherType= GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP; + + case 5: + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER; break; - case 4: - parm->sFilter.eEtherType= GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE; + + case 6: + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_0; break; - } - /**Treatment Get**/ + case 7: + parm->sFilter.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE; + parm->sFilter.sInnerVlan.eDei = GSW_EXTENDEDVLAN_FILTER_DEI_1; + break; + } + } + + /*Get Ether type filter*/ + ethtype = (tbl_prog.key[2] & 0x1F); + + switch (ethtype) { + case 0: + parm->sFilter.eEtherType = GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER; + break; + + case 1: + parm->sFilter.eEtherType = GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE; + break; + + case 2: + parm->sFilter.eEtherType = GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE; + break; + + case 3: + parm->sFilter.eEtherType = GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP; + break; + + case 4: + parm->sFilter.eEtherType = GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE; + break; + } + + /**Treatment Get**/ /** Get Number of VLAN tag to remove treatment.*/ - removetag = ((tbl_prog.val[1] & 0xC000) >> 14); - switch(removetag) { + removetag = ((tbl_prog.val[1] & 0xC000) >> 14); + + switch (removetag) { case 0: - parm->sTreatment.eRemoveTag= GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG; + parm->sTreatment.eRemoveTag = GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG; break; + case 1: - parm->sTreatment.eRemoveTag= GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG; + parm->sTreatment.eRemoveTag = GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG; break; + case 2: - parm->sTreatment.eRemoveTag= GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG; + parm->sTreatment.eRemoveTag = GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG; break; + case 3: - parm->sTreatment.eRemoveTag= GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM; + parm->sTreatment.eRemoveTag = GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM; break; } - + /** Get outer VLAN tag treatment. */ - parm->sTreatment.sOuterVlan.ePriorityVal=(tbl_prog.val[1] & 0xF); - if (parm->sTreatment.sOuterVlan.ePriorityVal == 15) - { + parm->sTreatment.sOuterVlan.ePriorityVal = (tbl_prog.val[1] & 0xF); + + if (parm->sTreatment.sOuterVlan.ePriorityVal == 15) { /*no outer VLAN tag added*/ - parm->sTreatment.bAddOuterVlan=0; + parm->sTreatment.bAddOuterVlan = 0; } else { - parm->sTreatment.bAddOuterVlan=1; - switch(parm->sTreatment.sOuterVlan.ePriorityVal) { - case 8: - parm->sTreatment.sOuterVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY; - break; - case 9: - parm->sTreatment.sOuterVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY; - break; - case 10: - parm->sTreatment.sOuterVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_DSCP; - bDscp2PcpMapEnable = 1; - break; - default: - parm->sTreatment.sOuterVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL; - break; + parm->sTreatment.bAddOuterVlan = 1; + + switch (parm->sTreatment.sOuterVlan.ePriorityVal) { + case 8: + parm->sTreatment.sOuterVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY; + break; + + case 9: + parm->sTreatment.sOuterVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY; + break; + + case 10: + parm->sTreatment.sOuterVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_DSCP; + bDscp2PcpMapEnable = 1; + break; + + default: + parm->sTreatment.sOuterVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL; + break; } /*Get Treatment for outer VID*/ - parm->sTreatment.sOuterVlan.eVidVal=((tbl_prog.val[0] & 0xFFF8) >> 3); - if(parm->sTreatment.sOuterVlan.eVidVal == 4096) - parm->sTreatment.sOuterVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_INNER_VID; + parm->sTreatment.sOuterVlan.eVidVal = ((tbl_prog.val[0] & 0xFFF8) >> 3); + + if (parm->sTreatment.sOuterVlan.eVidVal == 4096) + parm->sTreatment.sOuterVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_INNER_VID; else if (parm->sTreatment.sOuterVlan.eVidVal == 4097) - parm->sTreatment.sOuterVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID; - else - parm->sTreatment.sOuterVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_VID_VAL; + parm->sTreatment.sOuterVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID; + else + parm->sTreatment.sOuterVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_VID_VAL; /*Treatment for outer TPID/DEI*/ tpid_dei = (tbl_prog.val[0] & 0x7); - switch(tpid_dei) { - case 0: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; - break; - case 1: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; - break; - case 2: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; - break; - case 3: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; - break; - case 4: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_8021Q; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_0; - break; - case 6: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_0; - break; - case 7: - parm->sTreatment.sOuterVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sOuterVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_1; - break; + switch (tpid_dei) { + case 0: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; + break; + + case 1: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; + break; + + case 2: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; + break; + + case 3: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; + break; + + case 4: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_8021Q; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_0; + + break; + + case 6: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_0; + break; + + case 7: + parm->sTreatment.sOuterVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sOuterVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_1; + break; } } - + /** Get inner VLAN tag treatment. */ - parm->sTreatment.sInnerVlan.ePriorityVal=(tbl_prog.val[3] & 0xF); - if (parm->sTreatment.sInnerVlan.ePriorityVal == 15) - { + parm->sTreatment.sInnerVlan.ePriorityVal = (tbl_prog.val[3] & 0xF); + + if (parm->sTreatment.sInnerVlan.ePriorityVal == 15) { /*no inner VLAN tag added*/ - parm->sTreatment.bAddInnerVlan=0; - } - else - { - parm->sTreatment.bAddInnerVlan=1; - parm->sTreatment.sInnerVlan.ePriorityVal=(tbl_prog.val[3] & 0xF); - switch(parm->sTreatment.sInnerVlan.ePriorityVal) { - case 8: - parm->sTreatment.sInnerVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY; - break; - case 9: - parm->sTreatment.sInnerVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY; - break; - case 10: - parm->sTreatment.sInnerVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_DSCP; - bDscp2PcpMapEnable=1; - break; - default: - parm->sTreatment.sInnerVlan.ePriorityMode= GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL; - break; + parm->sTreatment.bAddInnerVlan = 0; + } else { + parm->sTreatment.bAddInnerVlan = 1; + parm->sTreatment.sInnerVlan.ePriorityVal = (tbl_prog.val[3] & 0xF); + + switch (parm->sTreatment.sInnerVlan.ePriorityVal) { + case 8: + parm->sTreatment.sInnerVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY; + break; + + case 9: + parm->sTreatment.sInnerVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY; + break; + + case 10: + parm->sTreatment.sInnerVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_DSCP; + bDscp2PcpMapEnable = 1; + break; + + default: + parm->sTreatment.sInnerVlan.ePriorityMode = GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL; + break; } /*Get Treatment for inner VID*/ - parm->sTreatment.sInnerVlan.eVidVal=((tbl_prog.val[2] & 0xFFF8) >> 3); - if(parm->sTreatment.sInnerVlan.eVidVal == 4096) - parm->sTreatment.sInnerVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_INNER_VID; + parm->sTreatment.sInnerVlan.eVidVal = ((tbl_prog.val[2] & 0xFFF8) >> 3); + + if (parm->sTreatment.sInnerVlan.eVidVal == 4096) + parm->sTreatment.sInnerVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_INNER_VID; else if (parm->sTreatment.sInnerVlan.eVidVal == 4097) - parm->sTreatment.sInnerVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID; - else - parm->sTreatment.sInnerVlan.eVidMode=GSW_EXTENDEDVLAN_TREATMENT_VID_VAL; + parm->sTreatment.sInnerVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID; + else + parm->sTreatment.sInnerVlan.eVidMode = GSW_EXTENDEDVLAN_TREATMENT_VID_VAL; /*Treatment for inner TPID/DEI*/ tpid_dei = (tbl_prog.val[2] & 0x7); - switch(tpid_dei) { - case 0: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; - break; - case 1: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; - break; - case 2: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; - break; - case 3: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; - break; - case 4: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_8021Q; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_0; - break; - case 6: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_0; - break; - case 7: - parm->sTreatment.sInnerVlan.eTpid=GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; - parm->sTreatment.sInnerVlan.eDei=GSW_EXTENDEDVLAN_TREATMENT_DEI_1; - break; + switch (tpid_dei) { + case 0: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; + break; + + case 1: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; + break; + + case 2: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI; + break; + + case 3: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI; + break; + + case 4: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_8021Q; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_0; + + break; + + case 6: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_0; + break; + + case 7: + parm->sTreatment.sInnerVlan.eTpid = GSW_EXTENDEDVLAN_TREATMENT_VTETYPE; + parm->sTreatment.sInnerVlan.eDei = GSW_EXTENDEDVLAN_TREATMENT_DEI_1; + break; } } - + /** Get Treatment Bridge port **/ parm->sTreatment.bReassignBridgePort = ((tbl_prog.val[4] & 0x100) >> 8); - if(parm->sTreatment.bReassignBridgePort) + + if (parm->sTreatment.bReassignBridgePort) parm->sTreatment.nNewBridgePortId = (tbl_prog.val[4] & 0xFF); /** Get Treatment DSCP **/ parm->sTreatment.bNewDscpEnable = ((tbl_prog.val[4] & 0x8000) >> 15); - if(parm->sTreatment.bNewDscpEnable) + + if (parm->sTreatment.bNewDscpEnable) parm->sTreatment.nNewDscp = ((tbl_prog.val[4] & 0x7E00) >> 9); - /** Get Treatment Traffic Class **/ + /** Get Treatment Traffic Class **/ parm->sTreatment.bNewTrafficClassEnable = ((tbl_prog.val[5] & 0x2000) >> 13); - if(parm->sTreatment.bNewTrafficClassEnable) + + if (parm->sTreatment.bNewTrafficClassEnable) parm->sTreatment.nNewTrafficClass = ((tbl_prog.val[5] & 0x1E00) >> 9); /** Treatment Metering **/ parm->sTreatment.bNewMeterEnable = ((tbl_prog.val[5] & 0x100) >> 8); - if(parm->sTreatment.bNewMeterEnable) + + if (parm->sTreatment.bNewMeterEnable) parm->sTreatment.sNewTrafficMeterId = (tbl_prog.val[5] & 0xFF); - + /** Get loopback. val 5 BIT 14*/ - parm->sTreatment.bLoopbackEnable=((tbl_prog.val[5] & 0x4000) >> 14); + parm->sTreatment.bLoopbackEnable = ((tbl_prog.val[5] & 0x4000) >> 14); /** Get destination/source MAC address swap. val 5 BIT 15*/ - parm->sTreatment.bDaSaSwapEnable=((tbl_prog.val[5] & 0x8000) >> 15); + parm->sTreatment.bDaSaSwapEnable = ((tbl_prog.val[5] & 0x8000) >> 15); /** Get traffic mirrored to the monitoring port. val 3 BIT 15 */ - parm->sTreatment.bMirrorEnable=((tbl_prog.val[3] & 0x8000) >> 15); + parm->sTreatment.bMirrorEnable = ((tbl_prog.val[3] & 0x8000) >> 15); if (bDscp2PcpMapEnable) { - dscp2pcp_pointer= ((tbl_prog.val[3] & 0x70) >> 4); - pr_err("dscp pointer = %d\n",dscp2pcp_pointer); + dscp2pcp_pointer = ((tbl_prog.val[3] & 0x70) >> 4); + pr_err("dscp pointer = %d\n", dscp2pcp_pointer); + /** Get DSCP2PCP map **/ /*This dscp2pcp idx should be in use*/ - if(!gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse) { - printk("ERROR dscp2pcp_pointer not in use %d \n",dscp2pcp_pointer); - return GSW_statusErr; + if (!gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse) { + printk("ERROR dscp2pcp_pointer not in use %d \n", dscp2pcp_pointer); + goto UNLOCK_AND_RETURN; } - dscp2pcp_get.nIndex=dscp2pcp_pointer; - ret=GSW_QOS_Dscp2PcpTableGet(cdev, &dscp2pcp_get); - if(ret==GSW_statusErr) - return ret; - memcpy(parm->sTreatment.nDscp2PcpMap,dscp2pcp_get.nMap, (sizeof(u8) * 64)); + + dscp2pcp_get.nIndex = dscp2pcp_pointer; + ret = GSW_QOS_Dscp2PcpTableGet(cdev, &dscp2pcp_get); + + if (ret == GSW_statusErr) { + pr_err("%s:%s:%d - GSW_QOS_Dscp2PcpTableGet", __FILE__, __func__, __LINE__); + goto UNLOCK_AND_RETURN; + ; + } + + memcpy(parm->sTreatment.nDscp2PcpMap, dscp2pcp_get.nMap, (sizeof(u8) * 64)); } - - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_ExtendedVlanFree(void *cdev, GSW_EXTENDEDVLAN_alloc_t *param) +GSW_return_t GSW_ExtendedVlanFree(void *cdev, GSW_EXTENDEDVLAN_alloc_t *param) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0,dscp2pcp_pointer=0,meterid=0,meterenable=0; + u32 idx = 0, dscp2pcp_pointer = 0, meterid = 0, meterenable = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (param->nExtendedVlanBlockId >= gswdev->num_of_extendvlan) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (param->nExtendedVlanBlockId >= gswdev->num_of_extendvlan) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*nExtendedVlanBlockId should be in use,if not in use return error*/ - if (!gswdev->extendvlan_idx.vlan_idx[param->nExtendedVlanBlockId].IndexInUse) - return GSW_statusErr; - + if (!gswdev->extendvlan_idx.vlan_idx[param->nExtendedVlanBlockId].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*if this nExtendedVlanBlockId usage count is not zero that means it is used by some one. This Block can be deleted, only if that some one release this block*/ - if (gswdev->extendvlan_idx.vlan_idx[param->nExtendedVlanBlockId].IndexInUsageCnt) - { - pr_err("ERROR :Extended Vlan block %u is used by some resource,can not delete\n",param->nExtendedVlanBlockId); - return GSW_statusErr; + if (gswdev->extendvlan_idx.vlan_idx[param->nExtendedVlanBlockId].IndexInUsageCnt) { + pr_err("ERROR :Extended Vlan block %u is used by some resource,can not delete\n", param->nExtendedVlanBlockId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - - idx=param->nExtendedVlanBlockId; - param->nNumberOfEntries=0; - if(gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != param->nExtendedVlanBlockId) - return GSW_statusErr; + + idx = param->nExtendedVlanBlockId; + param->nNumberOfEntries = 0; + + if (gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId != param->nExtendedVlanBlockId) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Condition to delete idx 1. idx should belong to this block 2. idx should be in Use 3. idx should be with in valid Extended VLAN table range (Entry 0-1023 is valid) */ - while(gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse && idx < gswdev->num_of_extendvlan - && (gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId == param->nExtendedVlanBlockId)) - { + while (gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse && idx < gswdev->num_of_extendvlan + && (gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId == param->nExtendedVlanBlockId)) { memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_EXTVLAN_INDEX; CLEAR_U16(tbl_prog.pcindex); @@ -15798,46 +20289,54 @@ GSW_return_t GSW_ExtendedVlanFree(void *cdev, GSW_EXTENDEDVLAN_alloc_t *param) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); - if(gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) { - /*get dscp2pcp table pointer*/ - dscp2pcp_pointer= ((tbl_prog.val[3] & 0x70) >> 4); - /*Check whether the dscp2pcp pointer in use. - It should be in use,since it got allocated or assigned in GSW_ExtendedVlanAdd - for this ExtendedVlan table idx (i.e) it is marked as InUse and Usage count - has been incremented during allocation or Usage count has been incremented - if assigned. - */ - if (!gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse) - return GSW_statusErr; - - /*Decrement the dscp2pcp index usage count. - If it becomes zero after decrement,then this index is free - for allocation by others. - In next allocation this dscp2pcp pointer's value - will be over written. - */ - gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUsageCnt--; - if(gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUsageCnt == 0) - gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse=0; - gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned=0; - gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer=0; - } - /** Treatment Metering **/ - if(gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) { - meterenable = ((tbl_prog.val[5] & 0x100) >> 8); - meterid = (tbl_prog.val[5] & 0xFF); - if(!meterenable) { - pr_err("Meterid %d is assigned while allocation for this ExVlan idx=%d\n", - meterid,idx); - pr_err("ERROR : why it is not enabled in Exvlan Table\n"); - return GSW_statusErr; - } - - gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned=0; - gswdev->extendvlan_idx.vlan_idx[idx].MeterId=0; - gswdev->meter_idx[meterid].IndexInUsageCnt--; - } - + if (gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned) { + /*get dscp2pcp table pointer*/ + dscp2pcp_pointer = ((tbl_prog.val[3] & 0x70) >> 4); + + /*Check whether the dscp2pcp pointer in use. + It should be in use,since it got allocated or assigned in GSW_ExtendedVlanAdd + for this ExtendedVlan table idx (i.e) it is marked as InUse and Usage count + has been incremented during allocation or Usage count has been incremented + if assigned. + */ + if (!gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*Decrement the dscp2pcp index usage count. + If it becomes zero after decrement,then this index is free + for allocation by others. + In next allocation this dscp2pcp pointer's value + will be over written. + */ + gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUsageCnt--; + + if (gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUsageCnt == 0) + gswdev->dscp2pcp_idx[dscp2pcp_pointer].IndexInUse = 0; + + gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointerAssigned = 0; + gswdev->extendvlan_idx.vlan_idx[idx].Dscp2PcpPointer = 0; + } + + /** Treatment Metering **/ + if (gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned) { + meterenable = ((tbl_prog.val[5] & 0x100) >> 8); + meterid = (tbl_prog.val[5] & 0xFF); + + if (!meterenable) { + pr_err("Meterid %d is assigned while allocation for this ExVlan idx=%d\n", + meterid, idx); + pr_err("ERROR : why it is not enabled in Exvlan Table\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + gswdev->extendvlan_idx.vlan_idx[idx].MeterAssigned = 0; + gswdev->extendvlan_idx.vlan_idx[idx].MeterId = 0; + gswdev->meter_idx[meterid].IndexInUsageCnt--; + } + /*Zero the Key/Value REG and write to this ExtendedVlan table idx*/ memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_EXTVLAN_INDEX; @@ -15848,9 +20347,9 @@ GSW_return_t GSW_ExtendedVlanFree(void *cdev, GSW_EXTENDEDVLAN_alloc_t *param) gsw_pce_table_write(cdev, &tbl_prog); /*free this idx and decrement the the number of used table entries/idx*/ - gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse=0; + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUse = 0; /*(Entry 0-1023 is valid) EXVLAN_ENTRY_INVALID is 1024*/ - gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId=EXVLAN_ENTRY_INVALID; + gswdev->extendvlan_idx.vlan_idx[idx].VlanBlockId = EXVLAN_ENTRY_INVALID; gswdev->extendvlan_idx.nUsedEntry--; /*A reference for the user, how many entries has been deleted in this block debugging purpose*/ @@ -15858,18 +20357,28 @@ GSW_return_t GSW_ExtendedVlanFree(void *cdev, GSW_EXTENDEDVLAN_alloc_t *param) /*increment the idx,since the block's allocation in ADD is Contiguous*/ idx++; } - - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + + } -static u8 GSW_SearchVlanFilterContiguousBlock(ethsw_api_dev_t *gswdev,u32 BlockId,u32 NumberOfEntries) +static u8 GSW_SearchVlanFilterContiguousBlock(ethsw_api_dev_t *gswdev, u32 BlockId, u32 NumberOfEntries) { u32 i; - for(i=BlockId;i <=(BlockId + NumberOfEntries);i++) - { + + for (i = BlockId; i <= (BlockId + NumberOfEntries); i++) { if (gswdev->vlanfilter_idx.filter_idx[i].IndexInUse) return 0; } + return 1; } @@ -15877,158 +20386,205 @@ GSW_return_t GSW_VlanFilterAlloc(void *cdev, GSW_VLANFILTER_alloc_t *param) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u16 VlanFilterIndex; - u8 ContiguousBlockFound=0; - u32 i; - - /* + u8 ContiguousBlockFound = 0; + u32 i, ret; + + /* Allocate New Block as per the number of table Entries requested The Block must be allocated with contiguous table index */ - - if (param->nNumberOfEntries > (gswdev->num_of_vlanfilter - gswdev->vlanfilter_idx.nUsedEntry)) + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; + } - for(VlanFilterIndex=0;VlanFilterIndex < gswdev->num_of_vlanfilter && !ContiguousBlockFound;VlanFilterIndex++) - { +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + if (param->nNumberOfEntries > (gswdev->num_of_vlanfilter - gswdev->vlanfilter_idx.nUsedEntry)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + for (VlanFilterIndex = 0; VlanFilterIndex < gswdev->num_of_vlanfilter && !ContiguousBlockFound; VlanFilterIndex++) { /*Table Index not in use*/ - if (!gswdev->vlanfilter_idx.filter_idx[VlanFilterIndex].IndexInUse) - { - ContiguousBlockFound=GSW_SearchVlanFilterContiguousBlock(gswdev,VlanFilterIndex,param->nNumberOfEntries); + if (!gswdev->vlanfilter_idx.filter_idx[VlanFilterIndex].IndexInUse) { + ContiguousBlockFound = GSW_SearchVlanFilterContiguousBlock(gswdev, VlanFilterIndex, param->nNumberOfEntries); } /*Contiguous block found in the table*/ - if(ContiguousBlockFound) - { - param->nVlanFilterBlockId=VlanFilterIndex; + if (ContiguousBlockFound) { + param->nVlanFilterBlockId = VlanFilterIndex; + /*Mark the contiguous table indexes as InUse and tag it with block id*/ - for(i=param->nVlanFilterBlockId;i < (param->nVlanFilterBlockId + param->nNumberOfEntries);i++) - { - gswdev->vlanfilter_idx.filter_idx[i].IndexInUse=1; - gswdev->vlanfilter_idx.filter_idx[i].FilterBlockId=param->nVlanFilterBlockId; - /* The following are stored as part of Index information, - Since it will be used as part of Bridge Port Configuration (GSW_BRIDGE_PORT_CONFIG_SET). - It will be used to enable/disable the following in Bridge Port Configuration Table. - 1. VLAN filtering untagged traffic forwarding mode - 2. VLAN filtering tagged unmatched traffic forwarding mode - It is not part of VLAN Filter Table Configuration - */ - gswdev->vlanfilter_idx.filter_idx[i].DiscardUntagged=param->bDiscardUntagged; - gswdev->vlanfilter_idx.filter_idx[i].DiscardUnMatchedTagged=param->bDiscardUnmatchedTagged; + for (i = param->nVlanFilterBlockId; i < (param->nVlanFilterBlockId + param->nNumberOfEntries); i++) { + gswdev->vlanfilter_idx.filter_idx[i].IndexInUse = 1; + gswdev->vlanfilter_idx.filter_idx[i].FilterBlockId = param->nVlanFilterBlockId; + /* The following are stored as part of Index information, + Since it will be used as part of Bridge Port Configuration (GSW_BRIDGE_PORT_CONFIG_SET). + It will be used to enable/disable the following in Bridge Port Configuration Table. + 1. VLAN filtering untagged traffic forwarding mode + 2. VLAN filtering tagged unmatched traffic forwarding mode + It is not part of VLAN Filter Table Configuration + */ + gswdev->vlanfilter_idx.filter_idx[i].DiscardUntagged = param->bDiscardUntagged; + gswdev->vlanfilter_idx.filter_idx[i].DiscardUnMatchedTagged = param->bDiscardUnmatchedTagged; gswdev->vlanfilter_idx.nUsedEntry++; } } } + /*Contiguous block not found in the table*/ - if(!ContiguousBlockFound) - return GSW_statusErr; - - return GSW_statusOk; + if (!ContiguousBlockFound) { + ret = GSW_statusErr; + pr_err(" ContiguousBlockFound %s:%s:%d", __FILE__, __func__, __LINE__); + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; + } -GSW_return_t GSW_VlanFilterSet(void *cdev, GSW_VLANFILTER_config_t *param) +GSW_return_t GSW_VlanFilterSet(void *cdev, GSW_VLANFILTER_config_t *param) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0; + u32 idx = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif /* Once the New blk allocated,param->nEntryIndex will decide which index with in this block has to be set.only one index will be set at a time. - It is users responsibility to set all the index with in this block + It is users responsibility to set all the index with in this block by calling GSW_ExtendedVlanAdd as many times as required (i.e) param->nNumberOfEntries*/ - idx=param->nVlanFilterBlockId + param->nEntryIndex; + idx = param->nVlanFilterBlockId + param->nEntryIndex; if (idx >= gswdev->num_of_vlanfilter) { - pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n",idx,(gswdev->num_of_vlanfilter - 1)); - return GSW_statusErr; - } + pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n", idx, (gswdev->num_of_vlanfilter - 1)); + goto UNLOCK_AND_RETURN; + } if (!gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse) { - pr_err("ERROR: Index not InUse\n"); - return GSW_statusErr; - } - - if(gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != param->nVlanFilterBlockId) { - pr_err("gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != param->nVlanFilterBlockId\n"); - return GSW_statusErr; - } - + pr_err("ERROR: Index not InUse\n"); + goto UNLOCK_AND_RETURN; + } + + if (gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != param->nVlanFilterBlockId) { + pr_err("gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != param->nVlanFilterBlockId\n"); + goto UNLOCK_AND_RETURN; + } + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_VLANFILTER_INDEX; CLEAR_U16(tbl_prog.pcindex); /*Table Entry address (VLAN Filter index) Bit 11:0 in PCE_TBL_ADDR*/ tbl_prog.pcindex |= (idx & 0xFFF); - - /*This is the Filter mask which will be applied for all the Index with in + + /*This is the Filter mask which will be applied for all the Index with in this Allocated Block*/ - gswdev->vlanfilter_idx.filter_idx[idx].FilterMask=param->eVlanFilterMask; + gswdev->vlanfilter_idx.filter_idx[idx].FilterMask = param->eVlanFilterMask; CLEAR_U16(tbl_prog.key[0]); + /* KEY REG0 BIT 11:0 -VID,BIT 15:13-PCP,BIT 12-DEI*/ - switch(gswdev->vlanfilter_idx.filter_idx[idx].FilterMask) { - case GSW_VLAN_FILTER_TCI_MASK_VID: - tbl_prog.key[0] |= (param->nVal & 0xFFF); - break; - case GSW_VLAN_FILTER_TCI_MASK_PCP: - tbl_prog.key[0] |= ((param->nVal & 0x7) << 13); - break; - case GSW_VLAN_FILTER_TCI_MASK_TCI: - tbl_prog.key[0] |= (param->nVal & 0xFFFF); - break; - default: - return GSW_statusErr; + switch (gswdev->vlanfilter_idx.filter_idx[idx].FilterMask) { + case GSW_VLAN_FILTER_TCI_MASK_VID: + tbl_prog.key[0] |= (param->nVal & 0xFFF); + break; + + case GSW_VLAN_FILTER_TCI_MASK_PCP: + tbl_prog.key[0] |= ((param->nVal & 0x7) << 13); + break; + + case GSW_VLAN_FILTER_TCI_MASK_TCI: + tbl_prog.key[0] |= (param->nVal & 0xFFFF); + break; + + default: + goto UNLOCK_AND_RETURN; } - + /*VLAN Filter Match action*/ - /* VAL REG0 BIT 0 + /* VAL REG0 BIT 0 0 - Traffic Allowed 1 - Traffic Blocked */ - if(param->bDiscardMatched) + if (param->bDiscardMatched) tbl_prog.val[0] |= 1; else tbl_prog.val[0] &= ~(1); /*Address-based write*/ gsw_pce_table_write(cdev, &tbl_prog); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_VlanFilterGet(void *cdev, GSW_VLANFILTER_config_t *parm) +GSW_return_t GSW_VlanFilterGet(void *cdev, GSW_VLANFILTER_config_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0; + u32 idx = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nVlanFilterBlockId > gswdev->num_of_vlanfilter) - return GSW_statusErr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif - idx=parm->nVlanFilterBlockId + parm->nEntryIndex; - if (idx >= gswdev->num_of_vlanfilter) { - pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n",idx,(gswdev->num_of_vlanfilter - 1)); - return GSW_statusErr; - } + if (parm->nVlanFilterBlockId > gswdev->num_of_vlanfilter) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - /*Index is not in USE*/ + idx = parm->nVlanFilterBlockId + parm->nEntryIndex; + + if (idx >= gswdev->num_of_vlanfilter) { + pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n", idx, (gswdev->num_of_vlanfilter - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*Index is not in USE*/ if (!gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse) { pr_err("Error :Index not in use\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /*Index does not belongs to this VlanBlock*/ - if(gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != parm->nVlanFilterBlockId) - return GSW_statusErr; - + if (gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != parm->nVlanFilterBlockId) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_VLANFILTER_INDEX; CLEAR_U16(tbl_prog.pcindex); @@ -16037,71 +20593,91 @@ GSW_return_t GSW_VlanFilterGet(void *cdev, GSW_VLANFILTER_config_t *parm) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); - parm->eVlanFilterMask=gswdev->vlanfilter_idx.filter_idx[idx].FilterMask; + parm->eVlanFilterMask = gswdev->vlanfilter_idx.filter_idx[idx].FilterMask; // parm->bDiscardUntagged=gswdev->vlanfilter_idx.filter_idx[idx].DiscardUntagged; // parm->bDiscardUnmatchedTagged=gswdev->vlanfilter_idx.filter_idx[idx].DiscardUnMatchedTagged; - + /* KEY REG0 BIT 11:0 -VID,BIT 15:13-PCP,BIT 12-DEI*/ - switch(gswdev->vlanfilter_idx.filter_idx[idx].FilterMask) { - case GSW_VLAN_FILTER_TCI_MASK_VID: - parm->nVal = (tbl_prog.key[0] & 0xFFF); - break; - case GSW_VLAN_FILTER_TCI_MASK_PCP: - parm->nVal = ((tbl_prog.key[0] & 0xE000) >> 13); - break; - case GSW_VLAN_FILTER_TCI_MASK_TCI: - parm->nVal = (tbl_prog.key[0] & 0xFFFF); - break; - default: - return GSW_statusErr; + switch (gswdev->vlanfilter_idx.filter_idx[idx].FilterMask) { + case GSW_VLAN_FILTER_TCI_MASK_VID: + parm->nVal = (tbl_prog.key[0] & 0xFFF); + break; + + case GSW_VLAN_FILTER_TCI_MASK_PCP: + parm->nVal = ((tbl_prog.key[0] & 0xE000) >> 13); + break; + + case GSW_VLAN_FILTER_TCI_MASK_TCI: + parm->nVal = (tbl_prog.key[0] & 0xFFFF); + break; + + default: + goto UNLOCK_AND_RETURN; } - - parm->bDiscardMatched=(tbl_prog.val[0] & 0x1); - return GSW_statusOk; + + parm->bDiscardMatched = (tbl_prog.val[0] & 0x1); + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_VlanFilterFree(void *cdev, GSW_VLANFILTER_alloc_t *parm) +GSW_return_t GSW_VlanFilterFree(void *cdev, GSW_VLANFILTER_alloc_t *parm) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0; + u32 idx = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (parm->nVlanFilterBlockId >= gswdev->num_of_vlanfilter) { - pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n",idx,(gswdev->num_of_vlanfilter - 1)); - return GSW_statusErr; - } - + pr_err("ERROR: nVlanFilterBlockId idx %d out of range [supported num_of_vlanfilter %d]\n", idx, (gswdev->num_of_vlanfilter - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*nVlanFilterBlockId should be in use,if not in use return error*/ if (!gswdev->vlanfilter_idx.filter_idx[parm->nVlanFilterBlockId].IndexInUse) { pr_err("Error :Index not in use\n"); - return GSW_statusErr; - } + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*If this nVlanFilterBlockId usage count is not zero, that means it is still used by some one. This Block can be deleted, only if that some one release this block*/ - if (gswdev->vlanfilter_idx.filter_idx[parm->nVlanFilterBlockId].IndexInUsageCnt) - { - pr_err("ERROR :Vlan Filter block %u is used by some resource,can not delete\n",parm->nVlanFilterBlockId); - return GSW_statusErr; + if (gswdev->vlanfilter_idx.filter_idx[parm->nVlanFilterBlockId].IndexInUsageCnt) { + pr_err("ERROR :Vlan Filter block %u is used by some resource,can not delete\n", parm->nVlanFilterBlockId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + idx = parm->nVlanFilterBlockId; + parm->nNumberOfEntries = 0; + + if (gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != parm->nVlanFilterBlockId) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - idx=parm->nVlanFilterBlockId; - parm->nNumberOfEntries=0; - if(gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId != parm->nVlanFilterBlockId) - return GSW_statusErr; - /*Condition to delete idx 1. idx should belong to this block 2. idx should be in Use 3. idx should be with in valid VLAN Filter table range (Entry 0-1023 is valid) */ - while(gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse && idx < gswdev->num_of_vlanfilter - && (gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId == parm->nVlanFilterBlockId)) - { + while (gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse && idx < gswdev->num_of_vlanfilter + && (gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId == parm->nVlanFilterBlockId)) { /*Zero the Key/Value REG and write to this VLAN Filter table idx*/ memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_VLANFILTER_INDEX; @@ -16111,9 +20687,9 @@ GSW_return_t GSW_VlanFilterFree(void *cdev, GSW_VLANFILTER_alloc_t *parm) /*Address-based write*/ gsw_pce_table_write(cdev, &tbl_prog); /*free this idx and decrement the the number of used table entries/idx*/ - gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse=0; + gswdev->vlanfilter_idx.filter_idx[idx].IndexInUse = 0; /*(Entry 0-1023 is valid) VLANFILTER_ENTRY_INVALID is 1024*/ - gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId=VLANFILTER_ENTRY_INVALID; + gswdev->vlanfilter_idx.filter_idx[idx].FilterBlockId = VLANFILTER_ENTRY_INVALID; gswdev->vlanfilter_idx.nUsedEntry--; /*A reference for the user, how many entries has been deleted in this block debugging purpose*/ @@ -16121,89 +20697,121 @@ GSW_return_t GSW_VlanFilterFree(void *cdev, GSW_VLANFILTER_alloc_t *parm) /*increment the idx,since the block's allocation in ADD is Contiguous*/ idx++; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_BridgeAlloc(void *cdev, GSW_BRIDGE_alloc_t *param) +GSW_return_t GSW_BridgeAlloc(void *cdev, GSW_BRIDGE_alloc_t *param) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0,freeidxfound=0; - - /*find a free Bridge configuration table index and allocate - New Bridge configuration table index*/ - for (idx=1;idx < gswdev->num_of_bridge && !freeidxfound;idx++) - { - if(!(gswdev->brdgeconfig_idx[idx].IndexInUse)) - { - gswdev->brdgeconfig_idx[idx].IndexInUse=1; - param->nBridgeId=idx; - freeidxfound=1; + u32 idx = 0, freeidxfound = 0; + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + /*find a free Bridge configuration table index and allocate + New Bridge configuration table index + note: bridge port 0 is special purpose-can not be allocated*/ + for (idx = 1; idx < gswdev->num_of_bridge && !freeidxfound; idx++) { + if (!(gswdev->brdgeconfig_idx[idx].IndexInUse)) { + gswdev->brdgeconfig_idx[idx].IndexInUse = 1; + param->nBridgeId = idx; + freeidxfound = 1; } } + /*No free Slot return Error*/ - if (!freeidxfound) - return GSW_statusErr; -return GSW_statusOk; + if (!freeidxfound) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; } -GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) +GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0,meterid; + u32 idx = 0, meterid; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + if (param->nBridgeId >= gswdev->num_of_bridge) { - pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n",param->nBridgeId,(gswdev->num_of_bridge - 1)); - return GSW_statusErr; - } + pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n", param->nBridgeId, (gswdev->num_of_bridge - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*GSW_BRIDGE_CONFIG_MASK_FORCE is for debugging purpose only if this mask is enabled , there is no check on index in-use*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { /*If Bridge ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!(gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse)) { - pr_err("ERROR nBridgeId %d: Index not in use\n",param->nBridgeId); - return GSW_statusErr; + if (!(gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse)) { + pr_err("ERROR nBridgeId %d: Index not in use\n", param->nBridgeId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } - + memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); tbl_prog.table = PCE_BRGCFG_INDEX; CLEAR_U16(tbl_prog.pcindex); /*Table Entry address (Bridge Config Table index) Bit 9:0 in PCE_TBL_ADDR*/ tbl_prog.pcindex |= (param->nBridgeId & 0x3F); - - /*Address-based read - Do Not disturb the existing value in case of + + /*Address-based read - Do Not disturb the existing value in case of configuration update, so read first,then update only the required field*/ gsw_pce_table_read(cdev, &tbl_prog); - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT) - { + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT) { /*If Learning limit is enabled,Set the user defined limit If Learning limit not enable,Set default limit -255*/ - if(param->bMacLearningLimitEnable) { + if (param->bMacLearningLimitEnable) { tbl_prog.val[0] &= ~0xFF; tbl_prog.val[0] |= (param->nMacLearningLimit & 0xFF); - } - else + } else /*Set default limit -255*/ tbl_prog.val[0] |= (0xFF); - } - - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_SUB_METER) - { + } + + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_SUB_METER) { /** Bridge Meter for bridge process with specific type As defined in GSW_BridgePortEgressMeter_t - + Index of broadcast traffic meter GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST = 0, Index of known multicast traffic meter @@ -16212,55 +20820,52 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP = 2, Index of unknown multicast non-IP traffic meter GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP = 3, - Index of unknown unicast traffic meter + Index of unknown unicast traffic meter GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC = 4, **/ /*GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST*/ - if(param->bSubMeteringEnable[0]) - { - meterid=param->nTrafficSubMeterId[0]; - /*This below field enable indicates that this meter id is + if (param->bSubMeteringEnable[0]) { + meterid = param->nTrafficSubMeterId[0]; + + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId != - meterid) - { - idx=gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId; + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId != + meterid) { + idx = gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId=0; + gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) - { - gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned=1; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) { + gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned = 1; gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } - + } else { pr_err("BroadcastMeter Not allocated\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Clear the field first*/ tbl_prog.val[4] &= ~(0x7F << 8); tbl_prog.val[4] |= 1; @@ -16271,51 +20876,48 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_MULTICAST*/ - if(param->bSubMeteringEnable[1]) - { - meterid=param->nTrafficSubMeterId[1]; - /*This below field enable indicates that this meter id is + if (param->bSubMeteringEnable[1]) { + meterid = param->nTrafficSubMeterId[1]; + + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId != - meterid) - { - idx=gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId; + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId != + meterid) { + idx = gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId=0; + gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) - { - gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned=1; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) { + gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned = 1; gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } - + } else { pr_err("MulticastMeter Not allocated\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Clear the field first*/ tbl_prog.val[5] &= ~(0x7F << 8); tbl_prog.val[5] |= 1; @@ -16326,49 +20928,47 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP*/ - if(param->bSubMeteringEnable[2]) { - meterid=param->nTrafficSubMeterId[2]; - /*This below field enable indicates that this meter id is + if (param->bSubMeteringEnable[2]) { + meterid = param->nTrafficSubMeterId[2]; + + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId != - meterid) - { - idx=gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId; + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId != + meterid) { + idx = gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId=0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) - { - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned=1; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) { + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned = 1; gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("UnknownMultiIpMeter Not allocated\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Clear the field first*/ tbl_prog.val[8] &= ~(0x7F << 8); tbl_prog.val[8] |= 1; @@ -16377,52 +20977,50 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) /*Disable Unknown Multicast ip sub meter*/ tbl_prog.val[8] &= ~1; } - + /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP*/ - if(param->bSubMeteringEnable[3]) { - meterid=param->nTrafficSubMeterId[3]; - /*This below field enable indicates that this meter id is + if (param->bSubMeteringEnable[3]) { + meterid = param->nTrafficSubMeterId[3]; + + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId != - meterid) - { - idx=gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId; + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId != + meterid) { + idx = gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[meterid].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId=0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) - { - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned=1; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) { + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned = 1; gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } - + } else { pr_err("UnknownMultiNonIpMeter Not allocated\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Clear the field first*/ tbl_prog.val[7] &= ~(0x7F << 8); tbl_prog.val[7] |= 1; @@ -16433,49 +21031,47 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC*/ - if(param->bSubMeteringEnable[4]) { - meterid=param->nTrafficSubMeterId[4]; - /*This below field enable indicates that this meter id is + if (param->bSubMeteringEnable[4]) { + meterid = param->nTrafficSubMeterId[4]; + + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId != - meterid) - { - idx=gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId; + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId != + meterid) { + idx = gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[meterid].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId=0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) - { - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned=1; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) { + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned = 1; gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { - pr_err("UnknownUniCastMeter Not allocated\n"); - return GSW_statusErr; + pr_err("UnknownUniCastMeter Not allocated\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Clear the field first*/ tbl_prog.val[6] &= ~(0x7F << 8); tbl_prog.val[6] |= 1; @@ -16485,96 +21081,123 @@ GSW_return_t GSW_BridgeConfigSet(void *cdev, GSW_BRIDGE_config_t *param) tbl_prog.val[6] |= ~1; } } - - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE) - { + + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE) { /*Clear the field first*/ tbl_prog.val[1] &= ~0x3; - switch(param->eForwardBroadcast) { - case GSW_BRIDGE_FORWARD_FLOOD: - break; - case GSW_BRIDGE_FORWARD_DISCARD: - tbl_prog.val[1] |= 0x1; - break; - case GSW_BRIDGE_FORWARD_CPU: - tbl_prog.val[1] |= 0x2; - break; - } + + switch (param->eForwardBroadcast) { + case GSW_BRIDGE_FORWARD_FLOOD: + break; + + case GSW_BRIDGE_FORWARD_DISCARD: + tbl_prog.val[1] |= 0x1; + break; + + case GSW_BRIDGE_FORWARD_CPU: + tbl_prog.val[1] |= 0x2; + break; + } /*Clear the field first*/ tbl_prog.val[1] &= ~0xC; - switch(param->eForwardUnknownUnicast) { - case GSW_BRIDGE_FORWARD_FLOOD: - break; - case GSW_BRIDGE_FORWARD_DISCARD: - tbl_prog.val[1] |= (0x1 << 2); - break; - case GSW_BRIDGE_FORWARD_CPU: - tbl_prog.val[1] |= (0x2 << 2); - break; - } + + switch (param->eForwardUnknownUnicast) { + case GSW_BRIDGE_FORWARD_FLOOD: + break; + + case GSW_BRIDGE_FORWARD_DISCARD: + tbl_prog.val[1] |= (0x1 << 2); + break; + + case GSW_BRIDGE_FORWARD_CPU: + tbl_prog.val[1] |= (0x2 << 2); + break; + } /*Clear the field first*/ tbl_prog.val[1] &= ~0x30; - switch(param->eForwardUnknownMulticastNonIp) { - case GSW_BRIDGE_FORWARD_FLOOD: - break; - case GSW_BRIDGE_FORWARD_DISCARD: - tbl_prog.val[1] |= (0x1 << 4); - break; - case GSW_BRIDGE_FORWARD_CPU: - tbl_prog.val[1] |= (0x2 << 4); - break; - } + + switch (param->eForwardUnknownMulticastNonIp) { + case GSW_BRIDGE_FORWARD_FLOOD: + break; + + case GSW_BRIDGE_FORWARD_DISCARD: + tbl_prog.val[1] |= (0x1 << 4); + break; + + case GSW_BRIDGE_FORWARD_CPU: + tbl_prog.val[1] |= (0x2 << 4); + break; + } /*Clear the field first*/ tbl_prog.val[1] &= ~0xC0; - switch(param->eForwardUnknownMulticastIp) { - case GSW_BRIDGE_FORWARD_FLOOD: - break; - case GSW_BRIDGE_FORWARD_DISCARD: - tbl_prog.val[1] |= (0x1 << 6); - break; - case GSW_BRIDGE_FORWARD_CPU: - tbl_prog.val[1] |= (0x2 << 6); - break; - } + + switch (param->eForwardUnknownMulticastIp) { + case GSW_BRIDGE_FORWARD_FLOOD: + break; + + case GSW_BRIDGE_FORWARD_DISCARD: + tbl_prog.val[1] |= (0x1 << 6); + break; + + case GSW_BRIDGE_FORWARD_CPU: + tbl_prog.val[1] |= (0x2 << 6); + break; + } } + tbl_prog.table = PCE_BRGCFG_INDEX; CLEAR_U16(tbl_prog.pcindex); /*Table Entry address (Bridge Config Table index) Bit 5:0 in PCE_TBL_ADDR*/ tbl_prog.pcindex |= (param->nBridgeId & 0x3F); - + /*Address-based write*/ gsw_pce_table_write(cdev, &tbl_prog); - pr_err("param->nBridgeId %d\n",param->nBridgeId); - return GSW_statusOk; + pr_err("param->nBridgeId %d\n", param->nBridgeId); + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; + } -GSW_return_t GSW_BridgeConfigGet(void *cdev, GSW_BRIDGE_config_t *param) +GSW_return_t GSW_BridgeConfigGet(void *cdev, GSW_BRIDGE_config_t *param) { pctbl_prog_t tbl_prog; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 ForwardMode; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (param->nBridgeId >= gswdev->num_of_bridge) { - pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n",param->nBridgeId,(gswdev->num_of_bridge - 1)); - return GSW_statusErr; + pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n", param->nBridgeId, (gswdev->num_of_bridge - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /*GSW_BRIDGE_CONFIG_MASK_FORCE is for debugging purpose only if this mask is enabled , there is no check on index in-use*/ - if(!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) - { + if (!(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORCE)) { /*If Bridge ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse) - return GSW_statusErr; + if (!gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } memset(&tbl_prog, 0, sizeof(pctbl_prog_t)); @@ -16585,19 +21208,18 @@ GSW_return_t GSW_BridgeConfigGet(void *cdev, GSW_BRIDGE_config_t *param) /*Address-based read*/ gsw_pce_table_read(cdev, &tbl_prog); - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT) - { - param->nMacLearningLimit = (tbl_prog.val[0] & 0xFF); - if(param->nMacLearningLimit != 255) - param->bMacLearningLimitEnable=1; - } + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT) { + param->nMacLearningLimit = (tbl_prog.val[0] & 0xFF); - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_SUB_METER) - { + if (param->nMacLearningLimit != 255) + param->bMacLearningLimitEnable = 1; + } + + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_SUB_METER) { /** Bridge Meter for bridge process with specific type As defined in GSW_BridgePortEgressMeter_t - + Index of broadcast traffic meter GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST = 0, Index of known multicast traffic meter @@ -16606,138 +21228,170 @@ GSW_return_t GSW_BridgeConfigGet(void *cdev, GSW_BRIDGE_config_t *param) GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP = 2, Index of unknown multicast non-IP traffic meter GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP = 3, - Index of unknown unicast traffic meter + Index of unknown unicast traffic meter GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC = 4, **/ /*Broadcast*/ param->bSubMeteringEnable[0] = (tbl_prog.val[4] & 0x1); + /*Meter ID*/ if (param->bSubMeteringEnable[0]) param->nTrafficSubMeterId[0] = ((tbl_prog.val[4] & 0x7F00) >> 8); - + /*Multicast*/ param->bSubMeteringEnable[1] = (tbl_prog.val[5] & 0x1); + /*Meter ID*/ if (param->bSubMeteringEnable[1]) param->nTrafficSubMeterId[1] = ((tbl_prog.val[5] & 0x7F00) >> 8); - + /*Unknown Multicast IP*/ param->bSubMeteringEnable[2] = (tbl_prog.val[8] & 0x1); + /*Meter ID*/ if (param->bSubMeteringEnable[2]) param->nTrafficSubMeterId[2] = ((tbl_prog.val[8] & 0x7F00) >> 8); /*Unknown Multicast NON-IP*/ param->bSubMeteringEnable[3] = (tbl_prog.val[7] & 0x1); + /*Meter ID*/ if (param->bSubMeteringEnable[3]) param->nTrafficSubMeterId[3] = ((tbl_prog.val[7] & 0x7F00) >> 8); /*Unknown Uni-Cast*/ param->bSubMeteringEnable[4] = (tbl_prog.val[6] & 0x1); + /*Meter ID*/ if (param->bSubMeteringEnable[4]) param->nTrafficSubMeterId[4] = ((tbl_prog.val[6] & 0x7F00) >> 8); } - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE) - { + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE) { ForwardMode = (tbl_prog.val[1] & 0x3); - switch(ForwardMode) { - case 0: - param->eForwardBroadcast= GSW_BRIDGE_FORWARD_FLOOD; - break; - case 1: - param->eForwardBroadcast= GSW_BRIDGE_FORWARD_DISCARD; - break; - case 2: - param->eForwardBroadcast= GSW_BRIDGE_FORWARD_CPU; - break; - } + + switch (ForwardMode) { + case 0: + param->eForwardBroadcast = GSW_BRIDGE_FORWARD_FLOOD; + break; + + case 1: + param->eForwardBroadcast = GSW_BRIDGE_FORWARD_DISCARD; + break; + + case 2: + param->eForwardBroadcast = GSW_BRIDGE_FORWARD_CPU; + break; + } ForwardMode = ((tbl_prog.val[1] & 0xC0) >> 6); - switch(ForwardMode) { - case 0: - param->eForwardUnknownMulticastIp= GSW_BRIDGE_FORWARD_FLOOD; - break; - case 1: - param->eForwardUnknownMulticastIp= GSW_BRIDGE_FORWARD_DISCARD; - break; - case 2: - param->eForwardUnknownMulticastIp= GSW_BRIDGE_FORWARD_CPU; - break; - } + + switch (ForwardMode) { + case 0: + param->eForwardUnknownMulticastIp = GSW_BRIDGE_FORWARD_FLOOD; + break; + + case 1: + param->eForwardUnknownMulticastIp = GSW_BRIDGE_FORWARD_DISCARD; + break; + + case 2: + param->eForwardUnknownMulticastIp = GSW_BRIDGE_FORWARD_CPU; + break; + } ForwardMode = ((tbl_prog.val[1] & 0x30) >> 4); - switch(ForwardMode) { - case 0: - param->eForwardUnknownMulticastNonIp= GSW_BRIDGE_FORWARD_FLOOD; - break; - case 1: - param->eForwardUnknownMulticastNonIp= GSW_BRIDGE_FORWARD_DISCARD; - break; - case 2: - param->eForwardUnknownMulticastNonIp= GSW_BRIDGE_FORWARD_CPU; - break; - } - + + switch (ForwardMode) { + case 0: + param->eForwardUnknownMulticastNonIp = GSW_BRIDGE_FORWARD_FLOOD; + break; + + case 1: + param->eForwardUnknownMulticastNonIp = GSW_BRIDGE_FORWARD_DISCARD; + break; + + case 2: + param->eForwardUnknownMulticastNonIp = GSW_BRIDGE_FORWARD_CPU; + break; + } + ForwardMode = ((tbl_prog.val[1] & 0xC) >> 2); - switch(ForwardMode) { - case 0: - param->eForwardUnknownUnicast= GSW_BRIDGE_FORWARD_FLOOD; - break; - case 1: - param->eForwardUnknownUnicast= GSW_BRIDGE_FORWARD_DISCARD; - break; - case 2: - param->eForwardUnknownUnicast= GSW_BRIDGE_FORWARD_CPU; - break; - } + + switch (ForwardMode) { + case 0: + param->eForwardUnknownUnicast = GSW_BRIDGE_FORWARD_FLOOD; + break; + + case 1: + param->eForwardUnknownUnicast = GSW_BRIDGE_FORWARD_DISCARD; + break; + + case 2: + param->eForwardUnknownUnicast = GSW_BRIDGE_FORWARD_CPU; + break; + } } - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNED_COUNT) - { + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_LEARNED_COUNT) { param->nMacLearningCount = (tbl_prog.val[9] & 0x1FFF); } - - if(param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_DISCARD_COUNT) - { + + if (param->eMask & GSW_BRIDGE_CONFIG_MASK_MAC_DISCARD_COUNT) { param->nLearningDiscardEvent |= ((tbl_prog.val[2] & 0xFFFF)); param->nLearningDiscardEvent |= (((tbl_prog.val[3] & 0xFFFF) << 16)); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_BridgeFree(void *cdev, GSW_BRIDGE_alloc_t *param) +GSW_return_t GSW_BridgeFree(void *cdev, GSW_BRIDGE_alloc_t *param) { pctbl_prog_t tbl_prog; GSW_BRIDGE_config_t temp; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 count; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (param->nBridgeId >= gswdev->num_of_bridge) { - pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n",param->nBridgeId,gswdev->num_of_bridge); - return GSW_statusErr; + pr_err("nBridgeId %d out of range [Suported num_of_bridge = %d]\n", param->nBridgeId, gswdev->num_of_bridge); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /*Bridge ID should be in use,if not in use return error*/ if (!gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse) { - pr_err("nBridge %u is Not inUse -> need to allocate before freeing\n",param->nBridgeId); - return GSW_statusErr; + pr_err("nBridge %u is Not inUse -> need to allocate before freeing\n", param->nBridgeId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - + /*If this Bridge usage count is not zero that means it is still used by some one. This Bridge configuration can be deleted, only if that some one release this Bridge*/ if (gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUsageCnt) { - count = gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUsageCnt; - pr_err("nBridge %u IndexInUsageCnt = %u is not zero ?!,Some Bridge Ports is holding this Bridge ?\n", - param->nBridgeId,count); - pr_err("Free that Bridge Ports first,which will detach this association\n"); - return GSW_statusErr; - } + count = gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUsageCnt; + pr_err("nBridge %u IndexInUsageCnt = %u is not zero ?!,Some Bridge Ports is holding this Bridge ?\n", + param->nBridgeId, count); + pr_err("Free that Bridge Ports first,which will detach this association\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /** IMPROTANT : Release the Enabled Sub Meters associated with this bridge by Decrementing it's Usage count **/ @@ -16753,98 +21407,98 @@ GSW_return_t GSW_BridgeFree(void *cdev, GSW_BRIDGE_alloc_t *param) /*Egress Broadcast Meter*/ temp.nTrafficSubMeterId[0] = ((tbl_prog.val[4] & 0x7F00) >> 8); - if(gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId == - temp.nTrafficSubMeterId[0]) - { + + if (gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId == + temp.nTrafficSubMeterId[0]) { /*Release this meter id from this Bridge*/ gswdev->meter_idx[temp.nTrafficSubMeterId[0]].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId=0; - + gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].BroadcastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Multicast Meter*/ temp.nTrafficSubMeterId[1] = ((tbl_prog.val[5] & 0x7F00) >> 8); - if(gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId == - temp.nTrafficSubMeterId[1]) - { + + if (gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId == + temp.nTrafficSubMeterId[1]) { /*Release this meter id from this Bridge*/ gswdev->meter_idx[temp.nTrafficSubMeterId[1]].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId=0; - + gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].MulticastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown Multicast IP Meter*/ temp.nTrafficSubMeterId[2] = ((tbl_prog.val[8] & 0x7F00) >> 8); - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId == - temp.nTrafficSubMeterId[2]) - { + + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId == + temp.nTrafficSubMeterId[2]) { /*Release this meter id from this Bridge*/ gswdev->meter_idx[temp.nTrafficSubMeterId[2]].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId=0; - + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiIpMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown Multicast NON IP Meter*/ temp.nTrafficSubMeterId[3] = ((tbl_prog.val[7] & 0x7F00) >> 8); - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId == - temp.nTrafficSubMeterId[3]) - { + + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId == + temp.nTrafficSubMeterId[3]) { /*Release this meter id from this Bridge*/ gswdev->meter_idx[temp.nTrafficSubMeterId[3]].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId=0; - + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownMultiNonIpMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown UniCast Meter*/ temp.nTrafficSubMeterId[4] = ((tbl_prog.val[6] & 0x7F00) >> 8); - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) - { - if(gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId == - temp.nTrafficSubMeterId[4]) - { + + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned) { + if (gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId == + temp.nTrafficSubMeterId[4]) { /*Release this meter id from this Bridge*/ gswdev->meter_idx[temp.nTrafficSubMeterId[4]].IndexInUsageCnt--; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned=0; - gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId=0; - + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringAssigned = 0; + gswdev->brdgeconfig_idx[param->nBridgeId].UnknownUniCastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /** Clear the table idx**/ /*reset to default this bridge idx*/ @@ -16858,128 +21512,152 @@ GSW_return_t GSW_BridgeFree(void *cdev, GSW_BRIDGE_alloc_t *param) tbl_prog.val[0] |= (0xFF); gsw_pce_table_write(cdev, &tbl_prog); /*Free this bridge Idx*/ - gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse=0; - - return GSW_statusOk; + gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse = 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_BridgePortAlloc(void *cdev, GSW_BRIDGE_portAlloc_t *param) +GSW_return_t GSW_BridgePortAlloc(void *cdev, GSW_BRIDGE_portAlloc_t *param) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); pctbl_prog_t tbl_prog_brdgeport_ingress; pctbl_prog_t tbl_prog_brdgeport_egress; - u32 idx=0; - u16 freeidxfound=0; + u32 idx = 0; + u16 freeidxfound = 0; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - - /*Find a free Bridge port configuration table index + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + /*Find a free Bridge port configuration table index and allocate - New Bridge Port configuration table index - Bridge Port 0 and 127 is reserved , + New Bridge Port configuration table index + Bridge Port 0,1 and 127 is reserved , So will not be allocated to user*/ - for (idx=1;idx < (gswdev->num_of_bridge_port - 1) && !freeidxfound;idx++) - { - if(!(gswdev->brdgeportconfig_idx[idx].IndexInUse)) - { - gswdev->brdgeportconfig_idx[idx].IndexInUse=1; - param->nBridgePortId=idx; - freeidxfound=1; + for (idx = 2; idx < (gswdev->num_of_bridge_port - 1) && !freeidxfound; idx++) { + if (!(gswdev->brdgeportconfig_idx[idx].IndexInUse)) { + gswdev->brdgeportconfig_idx[idx].IndexInUse = 1; + param->nBridgePortId = idx; + freeidxfound = 1; } } + /*No free Slot return Error*/ - if (!freeidxfound) - return GSW_statusErr; + if (!freeidxfound) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); - + /*Learning Limit 255*/ - tbl_prog_brdgeport_ingress.val[4] |= 0xFF; - gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit=0xFF; + tbl_prog_brdgeport_ingress.val[4] |= 0xFF; + gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit = 0xFF; /*STP state Forward enable*/ - tbl_prog_brdgeport_ingress.val[0] |= 0x7; - tbl_prog_brdgeport_egress.val[0] |= 0x7; + tbl_prog_brdgeport_ingress.val[0] |= 0x7; + tbl_prog_brdgeport_egress.val[0] |= 0x7; /*Default STP State is GSW_STP_PORT_STATE_FORWARD it can be changed using GSW_Stp_PortCfgSet*/ - gswdev->brdgeportconfig_idx[param->nBridgePortId].StpState = - GSW_STP_PORT_STATE_FORWARD; + gswdev->brdgeportconfig_idx[param->nBridgePortId].StpState = + GSW_STP_PORT_STATE_FORWARD; /*By Default 8021X State is GSW_8021X_PORT_STATE_AUTHORIZED it can be changed using GSW_8021X_PortCfgSet*/ - gswdev->brdgeportconfig_idx[param->nBridgePortId].P8021xState= - GSW_8021X_PORT_STATE_AUTHORIZED; - /*NOTE :Bridge Port ingrees port map and Egress destination - logical port will be zero,It is up to the User to configure + gswdev->brdgeportconfig_idx[param->nBridgePortId].P8021xState = + GSW_8021X_PORT_STATE_AUTHORIZED; + /*NOTE :Bridge Port ingrees port map and Egress destination + logical port will be zero,It is up to the User to configure these fields using GSW_BridgePortConfigSet */ - - /*Same bridge port idx for ingress and egress bridge port configuration*/ + + /*Same bridge port idx for ingress and egress bridge port configuration*/ tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); - + /*Address-based write for ingress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_ingress); /*Address-based write for egress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_egress); - return GSW_statusOk; + ret = GSW_statusOk; + + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; } -GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) +GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) { pctbl_prog_t tbl_prog_brdgeport_ingress; pctbl_prog_t tbl_prog_brdgeport_egress; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0,FirstIdx,LastIdx,pmapper_idx,meterid; - u16 i,val_reg_idx,ret,IngressStpState,EgressStpState; + u32 idx = 0, FirstIdx, LastIdx, pmapper_idx, meterid; + u16 i, val_reg_idx, ret, IngressStpState, EgressStpState; + u32 BlkSize = 0; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif - - - if (param->nBridgePortId >= gswdev->num_of_bridge_port) - { - pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n",param->nBridgePortId,(gswdev->num_of_bridge_port - 1)); - return GSW_statusErr; - } + if (param->nBridgePortId >= gswdev->num_of_bridge_port) { + pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n", + param->nBridgePortId, (gswdev->num_of_bridge_port - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*GSW_BRIDGE_PORT_CONFIG_MASK_FORCE is for debugging purpose only if this mask is enabled , there is no check on index in-use*/ - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { /*If Bridge Port ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse)) { - pr_err("nBridgePortId %d Index not InUse\n",param->nBridgePortId); - return GSW_statusErr; + if (!(gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse)) { + pr_err("nBridgePortId %d Index not InUse\n", param->nBridgePortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } - - /*Same bridge port idx for ingress and egress bridge port configuration*/ + + /*Same bridge port idx for ingress and egress bridge port configuration*/ memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); @@ -16995,142 +21673,149 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) */ gsw_pce_table_read(cdev, &tbl_prog_brdgeport_egress); - /**Default Bridge Port Configuration Settings**/ - /*By Default STP State are GSW_STP_PORT_STATE_FORWARD. - it can be changed using GSW_STP_PortCfgSet - GSW_BridgePortConfigSet will not set any STP related - configuration in BridgePort Table*/ + /**Default Bridge Port Configuration Settings**/ + /*By Default STP State are GSW_STP_PORT_STATE_FORWARD. + it can be changed using GSW_STP_PortCfgSet + GSW_BridgePortConfigSet will not set any STP related + configuration in BridgePort Table*/ /*STP State - ingress*/ - IngressStpState = (tbl_prog_brdgeport_ingress.val[0] & 0x7); + IngressStpState = (tbl_prog_brdgeport_ingress.val[0] & 0x7); /*STP State - egress*/ - EgressStpState = (tbl_prog_brdgeport_egress.val[0] & 0x7); - /*Both ingress/egress states must be same + EgressStpState = (tbl_prog_brdgeport_egress.val[0] & 0x7); + + /*Both ingress/egress states must be same if not equal return error*/ - if(IngressStpState != EgressStpState) - { - pr_err("IngressStpState != EgressStpState"); - return GSW_statusErr; - } - - /*By default MAC Learning Limit default 255 - It can be changed using eMask - GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT - and bMacLearningLimitEnable in GSW_BridgePortConfigSet*/ - gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit= - (tbl_prog_brdgeport_ingress.val[4] & 0xFF); - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID) - { + if (IngressStpState != EgressStpState) { + pr_err("IngressStpState != EgressStpState"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*By default MAC Learning Limit default 255 + It can be changed using eMask + GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT + and bMacLearningLimitEnable in GSW_BridgePortConfigSet*/ + gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit = + (tbl_prog_brdgeport_ingress.val[4] & 0xFF); + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID) { if (param->nBridgeId >= gswdev->num_of_bridge) { - pr_err("Error : nBridgeId %d >= gswdev->num_of_bridge %d\n",param->nBridgeId,gswdev->num_of_bridge); - return GSW_statusErr; - } + pr_err("Error : nBridgeId %d >= gswdev->num_of_bridge %d\n", + param->nBridgeId, gswdev->num_of_bridge); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*GSW_BRIDGE_PORT_CONFIG_MASK_FORCE is for debugging purpose only if this mask is enabled , there is no check on index in-use*/ - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this bridge id is + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this bridge id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different bridge idx !! or wanted to allocate a new bridge idx ??!! may happen by mistake ??!! the previous bridge idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId != - param->nBridgeId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId != + param->nBridgeId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId; /*release the usage of previous bridge idx*/ gswdev->brdgeconfig_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId = 0; } } - + /*This Bridge ID should be in use (i.e) that is this Bridge ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse) - { - /*Usage count will be incremented only once during bridge idx assignment + if (gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse) { + /*Usage count will be incremented only once during bridge idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId - =param->nBridgeId; + = param->nBridgeId; /*Since this bridge id can be shared,Increment it's usage count*/ gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUsageCnt++; } } else { pr_err("gswdev->brdgeconfig_idx[param->nBridgeId].IndexInUse not in use\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - + } + /*Clear the Fields*/ tbl_prog_brdgeport_ingress.val[4] &= ~(0x3F << 8); tbl_prog_brdgeport_ingress.val[4] |= ((param->nBridgeId & 0x3F) << 8); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN) - { - if(param->bIngressExtendedVlanEnable) - { - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN) { + if (param->bIngressExtendedVlanEnable) { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this Bridge Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId != - param->nIngressExtendedVlanBlockId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId != + param->nIngressExtendedVlanBlockId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId = EXVLAN_ENTRY_INVALID; } } } - + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nIngressExtendedVlanBlockId; - if(FirstIdx >= gswdev->num_of_extendvlan) { - pr_err("in FirstIdx %d >= gswdev->num_of_egvlan %d\n",FirstIdx,gswdev->num_of_extendvlan); - return GSW_statusErr; - } - + FirstIdx = param->nIngressExtendedVlanBlockId; + + if (FirstIdx >= gswdev->num_of_extendvlan) { + pr_err("in FirstIdx %d >= gswdev->num_of_egvlan %d\n", FirstIdx, gswdev->num_of_extendvlan); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { - pr_err("!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse\n"); - return GSW_statusErr; - } + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + pr_err("!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nIngressExtendedVlanBlockId) { - pr_err("VlanBlockId != param->nIngressExtendedVlanBlockId\n"); - return GSW_statusErr; - } + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nIngressExtendedVlanBlockId) { + pr_err("VlanBlockId != param->nIngressExtendedVlanBlockId\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nIngressExtendedVlanBlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_brdgeport_ingress.val[1] |= (1 << 14); /*Set First Index of the Block*/ @@ -17138,19 +21823,17 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_ingress.val[1] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_brdgeport_ingress.val[2] &= ~(0x3FF); - tbl_prog_brdgeport_ingress.val[2] |= ((LastIdx-1) & 0x3FF); - pr_err("\nBridge port ExVlan FirstIdx = %d\n",FirstIdx); - pr_err("Bridge port ExVlan LastIdx = %d\n",LastIdx-1); + tbl_prog_brdgeport_ingress.val[2] |= ((LastIdx - 1) & 0x3FF); + pr_err("\nBridge port ExVlan FirstIdx = %d\n", FirstIdx); + pr_err("Bridge port ExVlan LastIdx = %d\n", LastIdx - 1); - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId - =param->nIngressExtendedVlanBlockId; + = param->nIngressExtendedVlanBlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -17158,66 +21841,83 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } else { /*Disable ingress Extended VLAN*/ tbl_prog_brdgeport_ingress.val[1] &= ~(1 << 14); + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId = EXVLAN_ENTRY_INVALID; + } } - } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN) - { - if(param->bEgressExtendedVlanEnable) - { - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + } + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN) { + if (param->bEgressExtendedVlanEnable) { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this Bridge Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId != - param->nEgressExtendedVlanBlockId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId != + param->nEgressExtendedVlanBlockId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId = EXVLAN_ENTRY_INVALID; } } } + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nEgressExtendedVlanBlockId; - if(FirstIdx >= gswdev->num_of_extendvlan) { - pr_err("FirstIdx >= gswdev->num_of_egvlan\n"); - return GSW_statusErr; - } - + FirstIdx = param->nEgressExtendedVlanBlockId; + + if (FirstIdx >= gswdev->num_of_extendvlan) { + pr_err("FirstIdx >= gswdev->num_of_egvlan\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { - pr_err("!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse\n"); - return GSW_statusErr; - } + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + pr_err("!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nEgressExtendedVlanBlockId) { - pr_err("VlanBlockId!= param->nEgressExtendedVlanBlockId\n"); - return GSW_statusErr; - } + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nEgressExtendedVlanBlockId) { + pr_err("VlanBlockId!= param->nEgressExtendedVlanBlockId\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nEgressExtendedVlanBlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_brdgeport_egress.val[1] |= (1 << 14); /*Set First Index of the Block*/ @@ -17225,17 +21925,15 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_egress.val[1] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_brdgeport_egress.val[2] &= ~(0x3FF); - tbl_prog_brdgeport_egress.val[2] |= ((LastIdx-1) & 0x3FF); + tbl_prog_brdgeport_egress.val[2] |= ((LastIdx - 1) & 0x3FF); - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId - =param->nEgressExtendedVlanBlockId; + = param->nEgressExtendedVlanBlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -17243,115 +21941,135 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } else { /*Disable Egress Extended VLAN*/ tbl_prog_brdgeport_egress.val[1] &= ~(1 << 14); + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId = EXVLAN_ENTRY_INVALID; + } } - } + } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING) { tbl_prog_brdgeport_ingress.val[3] &= ~(7); - switch(param->eIngressMarkingMode) { - case GSW_MARKING_ALL_GREEN: - break; - case GSW_MARKING_INTERNAL_MARKING: - tbl_prog_brdgeport_ingress.val[3] |= 0x1; - break; - case GSW_MARKING_DEI: - tbl_prog_brdgeport_ingress.val[3] |= 0x2; - break; - case GSW_MARKING_PCP_8P0D: - tbl_prog_brdgeport_ingress.val[3] |= 0x3; - break; - case GSW_MARKING_PCP_7P1D: - tbl_prog_brdgeport_ingress.val[3] |= 0x4; - break; - case GSW_MARKING_PCP_6P2D: - tbl_prog_brdgeport_ingress.val[3] |= 0x5; - break; - case GSW_MARKING_PCP_5P3D: - tbl_prog_brdgeport_ingress.val[3] |= 0x6; - break; - case GSW_MARKING_DSCP_AF: - tbl_prog_brdgeport_ingress.val[3] |= 0x7; - break; + + switch (param->eIngressMarkingMode) { + case GSW_MARKING_ALL_GREEN: + break; + + case GSW_MARKING_INTERNAL_MARKING: + tbl_prog_brdgeport_ingress.val[3] |= 0x1; + break; + + case GSW_MARKING_DEI: + tbl_prog_brdgeport_ingress.val[3] |= 0x2; + break; + + case GSW_MARKING_PCP_8P0D: + tbl_prog_brdgeport_ingress.val[3] |= 0x3; + break; + + case GSW_MARKING_PCP_7P1D: + tbl_prog_brdgeport_ingress.val[3] |= 0x4; + break; + + case GSW_MARKING_PCP_6P2D: + tbl_prog_brdgeport_ingress.val[3] |= 0x5; + break; + + case GSW_MARKING_PCP_5P3D: + tbl_prog_brdgeport_ingress.val[3] |= 0x6; + break; + + case GSW_MARKING_DSCP_AF: + tbl_prog_brdgeport_ingress.val[3] |= 0x7; + break; } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING) { tbl_prog_brdgeport_egress.val[3] &= ~(7); - switch(param->eEgressRemarkingMode) { - case GSW_REMARKING_NONE: - break; - case GSW_REMARKING_DEI: - tbl_prog_brdgeport_egress.val[3] |= 0x2; - break; - case GSW_REMARKING_PCP_8P0D: - tbl_prog_brdgeport_egress.val[3] |= 0x3; - break; - case GSW_REMARKING_PCP_7P1D: - tbl_prog_brdgeport_egress.val[3] |= 0x4; - break; - case GSW_REMARKING_PCP_6P2D: - tbl_prog_brdgeport_egress.val[3] |= 0x5; - break; - case GSW_REMARKING_PCP_5P3D: - tbl_prog_brdgeport_egress.val[3] |= 0x6; - break; - case GSW_REMARKING_DSCP_AF: - tbl_prog_brdgeport_egress.val[3] |= 0x7; - break; + + switch (param->eEgressRemarkingMode) { + case GSW_REMARKING_NONE: + break; + + case GSW_REMARKING_DEI: + tbl_prog_brdgeport_egress.val[3] |= 0x2; + break; + + case GSW_REMARKING_PCP_8P0D: + tbl_prog_brdgeport_egress.val[3] |= 0x3; + break; + + case GSW_REMARKING_PCP_7P1D: + tbl_prog_brdgeport_egress.val[3] |= 0x4; + break; + + case GSW_REMARKING_PCP_6P2D: + tbl_prog_brdgeport_egress.val[3] |= 0x5; + break; + + case GSW_REMARKING_PCP_5P3D: + tbl_prog_brdgeport_egress.val[3] |= 0x6; + break; + + case GSW_REMARKING_DSCP_AF: + tbl_prog_brdgeport_egress.val[3] |= 0x7; + break; } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER) - { - if (param->bIngressMeteringEnable) - { - if(param->nIngressTrafficMeterId >= gswdev->num_of_meters) - return GSW_statusErr; + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER) { + if (param->bIngressMeteringEnable) { + if (param->nIngressTrafficMeterId >= gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId != - param->nIngressTrafficMeterId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId; + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId != + param->nIngressTrafficMeterId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId - =param->nIngressTrafficMeterId; + = param->nIngressTrafficMeterId; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Enable Meter Id*/ tbl_prog_brdgeport_ingress.val[3] |= (1 << 7); tbl_prog_brdgeport_ingress.val[3] &= ~(0x7F << 8); @@ -17360,56 +22078,52 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) /*Disable Ingress Meter*/ tbl_prog_brdgeport_ingress.val[3] &= ~(1 << 7); } - } + } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER) { /*GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST*/ - if(param->bEgressSubMeteringEnable[0]) - { - meterid=param->nEgressTrafficSubMeterId[0]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[0]) { + meterid = param->nEgressTrafficSubMeterId[0]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[meterid].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_brdgeport_egress.val[5] |= (1 << 7); tbl_prog_brdgeport_egress.val[5] &= ~(0x7F << 8); tbl_prog_brdgeport_egress.val[5] |= ((param->nEgressTrafficSubMeterId[0] & 0x7F) << 8); @@ -17419,51 +22133,48 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_MULTICAST*/ - if(param->bEgressSubMeteringEnable[1]) - { - meterid=param->nEgressTrafficSubMeterId[1]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[1]) { + meterid = param->nEgressTrafficSubMeterId[1]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[meterid].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_brdgeport_egress.val[6] |= (1 << 7); tbl_prog_brdgeport_egress.val[6] &= ~(0x7F << 8); tbl_prog_brdgeport_egress.val[6] |= ((param->nEgressTrafficSubMeterId[1] & 0x7F) << 8); @@ -17473,51 +22184,49 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP*/ - if(param->bEgressSubMeteringEnable[2]) { - meterid=param->nEgressTrafficSubMeterId[2]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[2]) { + meterid = param->nEgressTrafficSubMeterId[2]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[meterid].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_brdgeport_egress.val[9] |= (1 << 7); tbl_prog_brdgeport_egress.val[9] &= ~(0x7F << 8); tbl_prog_brdgeport_egress.val[9] |= ((param->nEgressTrafficSubMeterId[2] & 0x7F) << 8); @@ -17527,50 +22236,48 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP*/ - if(param->bEgressSubMeteringEnable[3]) { - meterid=param->nEgressTrafficSubMeterId[3]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[3]) { + meterid = param->nEgressTrafficSubMeterId[3]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[meterid].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_brdgeport_egress.val[8] |= (1 << 7); tbl_prog_brdgeport_egress.val[8] &= ~(0x7F << 8); tbl_prog_brdgeport_egress.val[8] |= ((param->nEgressTrafficSubMeterId[3] & 0x7F) << 8); @@ -17580,50 +22287,48 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } /*GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC*/ - if(param->bEgressSubMeteringEnable[4]) { - meterid=param->nEgressTrafficSubMeterId[4]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[4]) { + meterid = param->nEgressTrafficSubMeterId[4]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("gswdev->meter_idx[meterid].IndexInUse\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_brdgeport_egress.val[7] |= (1 << 7); tbl_prog_brdgeport_egress.val[7] &= ~(0x7F << 8); tbl_prog_brdgeport_egress.val[7] |= ((param->nEgressTrafficSubMeterId[4] & 0x7F) << 8); @@ -17631,54 +22336,52 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) /*Disable Unknown Unicast sub meter*/ tbl_prog_brdgeport_egress.val[7] &= ~(1 << 7); } - + /*GSW_BRIDGE_PORT_EGRESS_METER_OTHERS*/ - if(param->bEgressSubMeteringEnable[5]) { - meterid=param->nEgressTrafficSubMeterId[5]; - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->bEgressSubMeteringEnable[5]) { + meterid = param->nEgressTrafficSubMeterId[5]; + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this Bridge Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId != - meterid) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId != + meterid) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[meterid].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[meterid].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId - =meterid; + = meterid; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[meterid].IndexInUsageCnt++; } } else { pr_err("Meter Id not In Use\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Enable Meter Id*/ tbl_prog_brdgeport_egress.val[3] |= (1 << 7); tbl_prog_brdgeport_egress.val[3] &= ~(0x7F << 8); @@ -17689,39 +22392,37 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING) { /** This field defines destination logical port. */ tbl_prog_brdgeport_egress.val[4] &= ~(0xF << 8); tbl_prog_brdgeport_egress.val[4] |= ((param->nDestLogicalPortId & 0xF) << 8); - - if(param->bPmapperEnable) - { - /*This below field indicates that one P-mapper idx is already allocated and + + if (param->bPmapperEnable) { + /*This below field indicates that one P-mapper idx is already allocated and it's idx recorded for this Bridge Port id. If next time the user update this p-mapper field with different p-mapper idx !! or wanted to allocate a new p-mapper idx ??!! may happen by mistake ??!! the previous p-mapper idx should be released*/ - + /*TODO:changed as per code review As per code review - user is not responsible pmapper allocation*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) - param->sPmapper.nPmapperId=gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx; - else - param->sPmapper.nPmapperId=PMAPPER_ENTRY_INVALID; - - /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to - derive sub interface ID. */ + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) + param->sPmapper.nPmapperId = gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx; + else + param->sPmapper.nPmapperId = PMAPPER_ENTRY_INVALID; + + /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to + derive sub interface ID. */ /*PCP-P-mapper table entry 1-8*/ /*DSCP-P-mapper table entry 9-72. */ - switch(param->ePmapperMappingMode) - { - case GSW_PMAPPER_MAPPING_PCP: - tbl_prog_brdgeport_egress.val[4] &= ~(1 << 13); - break; - case GSW_PMAPPER_MAPPING_DSCP: - tbl_prog_brdgeport_egress.val[4] |=(1 << 13); - break; + switch (param->ePmapperMappingMode) { + case GSW_PMAPPER_MAPPING_PCP: + tbl_prog_brdgeport_egress.val[4] &= ~(1 << 13); + break; + + case GSW_PMAPPER_MAPPING_DSCP: + tbl_prog_brdgeport_egress.val[4] |= (1 << 13); + break; } /* If the p-mapper id is invalid then the GSW_QOS_PmapperTableSet will @@ -17729,22 +22430,23 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) If p-mapper index is valid the GSW_QOS_PmapperTableSet will just program the table */ - ret=GSW_QOS_PmapperTableSet(cdev,¶m->sPmapper); - if(ret == GSW_statusErr) { - pr_err("GSW_QOS_PmapperTableSet ERROR\n"); - return GSW_statusErr; - } + ret = GSW_QOS_PmapperTableSet(cdev, ¶m->sPmapper); + + if (ret == GSW_statusErr) { + pr_err("GSW_QOS_PmapperTableSet ERROR\n"); + goto UNLOCK_AND_RETURN; + } + + pmapper_idx = param->sPmapper.nPmapperId; - pmapper_idx=param->sPmapper.nPmapperId; /*Usage count will be incremented only once during p-mapper idx allocation or assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned=1; - gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx=pmapper_idx; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned = 1; + gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx = pmapper_idx; } - tbl_prog_brdgeport_egress.val[4] |=(1 << 14); + tbl_prog_brdgeport_egress.val[4] |= (1 << 14); tbl_prog_brdgeport_egress.val[4] &= ~(0xFF); tbl_prog_brdgeport_egress.val[4] |= (pmapper_idx & 0xFF); } else { @@ -17756,133 +22458,135 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_egress.val[4] |= (param->nDestSubIfIdGroup & 0xFF); } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP) - { - val_reg_idx=10; - for(i=0;i < 8;i++) - { - tbl_prog_brdgeport_ingress.val[val_reg_idx] = (param->nBridgePortMap[i] & 0xFFFF); + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP) { + val_reg_idx = 10; + + for (i = 0; i < 8; i++) { + tbl_prog_brdgeport_ingress.val[val_reg_idx] = (param->nBridgePortMap[i] & 0xFFFF); val_reg_idx++; } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP) { /* 0- disable , 1 - enable*/ - if(param->bMcDestIpLookupDisable) + if (param->bMcDestIpLookupDisable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 13); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 13); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP) { /* 0- disable , 1 - enable*/ - if(param->bMcSrcIpLookupEnable) + if (param->bMcSrcIpLookupEnable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 9); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 9); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP) { /* 1- disable , 0 - enable*/ - if(param->bDestMacLookupDisable) + if (param->bDestMacLookupDisable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 14); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 14); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING) { /* 1- disable , 0 - enable*/ - if(param->bSrcMacLearningDisable) + if (param->bSrcMacLearningDisable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 15); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 15); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING) { /* 0- disable , 1 - enable*/ - if(param->bMacSpoofingDetectEnable) + if (param->bMacSpoofingDetectEnable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 11); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 11); } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK) - { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK) { /* 0- disable , 1 - enable*/ - if(param->bPortLockEnable) + if (param->bPortLockEnable) tbl_prog_brdgeport_ingress.val[0] |= (1 << 12); else tbl_prog_brdgeport_ingress.val[0] &= ~(1 << 12); } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER) - { + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER) { /*BypassEgress vlan filter range 1*/ - if(param->bBypassEgressVlanFilter1) + if (param->bBypassEgressVlanFilter1) tbl_prog_brdgeport_ingress.val[5] |= (1 << 15); else tbl_prog_brdgeport_ingress.val[5] &= ~(1 << 15); - - if(param->bIngressVlanFilterEnable) - { - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + + if (param->bIngressVlanFilterEnable) { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this Bridge Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId != - param->nIngressVlanFilterBlockId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId != + param->nIngressVlanFilterBlockId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId; /*release the usage of previous vlan block id*/ gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId = VLANFILTER_ENTRY_INVALID; } } } - + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nIngressVlanFilterBlockId; - if(FirstIdx > gswdev->num_of_vlanfilter) { - pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); - return GSW_statusErr; - } + FirstIdx = param->nIngressVlanFilterBlockId; + + if (FirstIdx > gswdev->num_of_vlanfilter) { + pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { - pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); - return GSW_statusErr; - } + if (!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { + pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId - != param->nIngressVlanFilterBlockId) { - pr_err("FilterBlockId != param->nIngressVlanFilterBlockId\n"); - return GSW_statusErr; - } + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId + != param->nIngressVlanFilterBlockId) { + pr_err("FilterBlockId != param->nIngressVlanFilterBlockId\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx - && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx + && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { LastIdx++; - } + } + + BlkSize = param->nIngressVlanFilterBlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /* enable ingress VLAN filtering*/ tbl_prog_brdgeport_ingress.val[5] |= (1 << 14); /*Set First Index of the Block*/ @@ -17890,114 +22594,133 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_ingress.val[5] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_brdgeport_ingress.val[6] &= ~(0x3FF); - tbl_prog_brdgeport_ingress.val[6] |= ((LastIdx-1) & 0x3FF); - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) + tbl_prog_brdgeport_ingress.val[6] |= ((LastIdx - 1) & 0x3FF); + + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) tbl_prog_brdgeport_ingress.val[5] |= (1 << 12); - else + else tbl_prog_brdgeport_ingress.val[5] &= ~(1 << 12); - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) + + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) tbl_prog_brdgeport_ingress.val[5] |= (1 << 13); - else + else tbl_prog_brdgeport_ingress.val[5] &= ~(1 << 13); - - - /* mask mode + + + /* mask mode 00 :VID Only 01 :RESERVED 10 :PCP 11 :TCI */ - + tbl_prog_brdgeport_ingress.val[6] &= ~(0x3000); - switch(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { - case GSW_VLAN_FILTER_TCI_MASK_VID: - break; - case GSW_VLAN_FILTER_TCI_MASK_PCP: - tbl_prog_brdgeport_ingress.val[6] |= (2 << 12); - break; - case GSW_VLAN_FILTER_TCI_MASK_TCI: - tbl_prog_brdgeport_ingress.val[6] |= (3 << 12); - break; - } - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment - for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned=1; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId - =param->nIngressVlanFilterBlockId; - /*Since this vlan blk can be shared,Increment it's usage count*/ - gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt++;; - } - } + + switch (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { + case GSW_VLAN_FILTER_TCI_MASK_VID: + break; + + case GSW_VLAN_FILTER_TCI_MASK_PCP: + tbl_prog_brdgeport_ingress.val[6] |= (2 << 12); + break; + + case GSW_VLAN_FILTER_TCI_MASK_TCI: + tbl_prog_brdgeport_ingress.val[6] |= (3 << 12); + break; + } + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment + for this bridge port id*/ + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned = 1; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId + = param->nIngressVlanFilterBlockId; + /*Since this vlan blk can be shared,Increment it's usage count*/ + gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt++;; + } + } } else { /* disable ingress VLAN filtering*/ tbl_prog_brdgeport_ingress.val[5] &= ~(1 << 14); - + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId; + /*release the usage of vlan block id, if it is assigned previously + when vlan filter operation is disabled,it is must to release + the mapped vlan filter resource*/ + gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId = VLANFILTER_ENTRY_INVALID; + } } } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1) - { - if(param->bEgressVlanFilter1Enable) - { - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1) { + if (param->bEgressVlanFilter1Enable) { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this Bridge Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId != - param->nEgressVlanFilter1BlockId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId != + param->nEgressVlanFilter1BlockId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId; /*release the usage of previous vlan block id*/ gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId = VLANFILTER_ENTRY_INVALID; } } } - + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nEgressVlanFilter1BlockId; - if(FirstIdx > gswdev->num_of_vlanfilter) { - pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); - return GSW_statusErr; - } + FirstIdx = param->nEgressVlanFilter1BlockId; + + if (FirstIdx > gswdev->num_of_vlanfilter) { + pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { - pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); - return GSW_statusErr; - } + if (!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { + pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId - != param->nEgressVlanFilter1BlockId) { - pr_err("FilterBlockId != param->nEgressVlanFilter1BlockId\n"); - return GSW_statusErr; - } + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId + != param->nEgressVlanFilter1BlockId) { + pr_err("FilterBlockId != param->nEgressVlanFilter1BlockId\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx - && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx + && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { LastIdx++; - } + } + + BlkSize = param->nEgressVlanFilter1BlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /* enable egress VLAN filtering -Range 1*/ tbl_prog_brdgeport_egress.val[10] |= (1 << 14); /*Set First Index of the Block*/ @@ -18005,46 +22728,48 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_egress.val[10] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_brdgeport_egress.val[11] &= ~(0x3FF); - tbl_prog_brdgeport_egress.val[11] |= ((LastIdx-1) & 0x3FF); + tbl_prog_brdgeport_egress.val[11] |= ((LastIdx - 1) & 0x3FF); - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) + + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) tbl_prog_brdgeport_egress.val[10] |= (1 << 12); - else + else tbl_prog_brdgeport_egress.val[10] &= ~(1 << 12); - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) + + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) tbl_prog_brdgeport_egress.val[10] |= (1 << 13); - else + else tbl_prog_brdgeport_egress.val[10] &= ~(1 << 13); - - /* mask mode + + /* mask mode 00 :VID Only 01 :RESERVED 10 :PCP 11 :TCI */ tbl_prog_brdgeport_egress.val[11] &= ~(0x3000); - switch(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { - case GSW_VLAN_FILTER_TCI_MASK_VID: - break; - case GSW_VLAN_FILTER_TCI_MASK_PCP: - tbl_prog_brdgeport_egress.val[11] |= (2 << 12); - break; - case GSW_VLAN_FILTER_TCI_MASK_TCI: - tbl_prog_brdgeport_egress.val[11] |= (3 << 12); - break; - } - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + + switch (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { + case GSW_VLAN_FILTER_TCI_MASK_VID: + break; + + case GSW_VLAN_FILTER_TCI_MASK_PCP: + tbl_prog_brdgeport_egress.val[11] |= (2 << 12); + break; + + case GSW_VLAN_FILTER_TCI_MASK_TCI: + tbl_prog_brdgeport_egress.val[11] |= (3 << 12); + break; + } + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId - =param->nEgressVlanFilter1BlockId; + = param->nEgressVlanFilter1BlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt++;; } @@ -18052,67 +22777,84 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } else { /* disable Egress VLAN filtering - Range 1*/ tbl_prog_brdgeport_ingress.val[10] &= ~(1 << 14); + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId; + /*release the usage of vlan block id, if it is assigned previously + when vlan filter operation is disabled,it is must to release + the mapped vlan filter resource*/ + gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId = VLANFILTER_ENTRY_INVALID; + } } } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2) - { - if(param->bEgressVlanFilter2Enable) - { - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2) { + if (param->bEgressVlanFilter2Enable) { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this Bridge Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this Bridge Port*/ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId != - param->nEgressVlanFilter2BlockId) - { - idx=gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId; + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId != + param->nEgressVlanFilter2BlockId) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId; /*release the usage of previous vlan block id*/ gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId = VLANFILTER_ENTRY_INVALID; } } } - + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nEgressVlanFilter2BlockId; - if(FirstIdx > gswdev->num_of_vlanfilter) { - pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); - return GSW_statusErr; - } - + FirstIdx = param->nEgressVlanFilter2BlockId; + + if (FirstIdx > gswdev->num_of_vlanfilter) { + pr_err("FirstIdx > gswdev->num_of_vlanfilter\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { - pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); - return GSW_statusErr; - } + if (!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse) { + pr_err("!gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUse\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId - != param->nEgressVlanFilter2BlockId) { - pr_err("FilterBlockId != param->nEgressVlanFilter2BlockId\n"); - return GSW_statusErr; - } + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterBlockId + != param->nEgressVlanFilter2BlockId) { + pr_err("FilterBlockId != param->nEgressVlanFilter2BlockId\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx - && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->vlanfilter_idx.filter_idx[LastIdx].FilterBlockId == FirstIdx + && gswdev->vlanfilter_idx.filter_idx[LastIdx].IndexInUse) { LastIdx++; - } + } + + BlkSize = param->nEgressVlanFilter2BlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /* enable egress VLAN filtering -Range 2*/ tbl_prog_brdgeport_egress.val[12] |= (1 << 14); /*Set First Index of the Block*/ @@ -18120,46 +22862,48 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) tbl_prog_brdgeport_egress.val[12] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_brdgeport_egress.val[13] &= ~(0x3FF); - tbl_prog_brdgeport_egress.val[13] |= ((LastIdx-1) & 0x3FF); - + tbl_prog_brdgeport_egress.val[13] |= ((LastIdx - 1) & 0x3FF); + + - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUntagged) tbl_prog_brdgeport_egress.val[12] |= (1 << 12); - else + else tbl_prog_brdgeport_egress.val[12] &= ~(1 << 12); - - if(gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) + + if (gswdev->vlanfilter_idx.filter_idx[FirstIdx].DiscardUnMatchedTagged) tbl_prog_brdgeport_egress.val[12] |= (1 << 13); - else + else tbl_prog_brdgeport_egress.val[12] &= ~(1 << 13); - - /* mask mode + + /* mask mode 00 :VID Only 01 :RESERVED 10 :PCP 11 :TCI */ tbl_prog_brdgeport_egress.val[13] &= ~(0x3000); - switch(gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { - case GSW_VLAN_FILTER_TCI_MASK_VID: - break; - case GSW_VLAN_FILTER_TCI_MASK_PCP: - tbl_prog_brdgeport_egress.val[13] |= (2 << 12); - break; - case GSW_VLAN_FILTER_TCI_MASK_TCI: - tbl_prog_brdgeport_egress.val[13] |= (3 << 12); - break; - } - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + + switch (gswdev->vlanfilter_idx.filter_idx[FirstIdx].FilterMask) { + case GSW_VLAN_FILTER_TCI_MASK_VID: + break; + + case GSW_VLAN_FILTER_TCI_MASK_PCP: + tbl_prog_brdgeport_egress.val[13] |= (2 << 12); + break; + + case GSW_VLAN_FILTER_TCI_MASK_TCI: + tbl_prog_brdgeport_egress.val[13] |= (3 << 12); + break; + } + + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this bridge port id*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) - { - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned=1; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) { + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned = 1; gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId - =param->nEgressVlanFilter2BlockId; + = param->nEgressVlanFilter2BlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt++; } @@ -18167,80 +22911,108 @@ GSW_return_t GSW_BridgePortConfigSet(void *cdev, GSW_BRIDGE_portConfig_t *param) } else { /* disable Egress VLAN filtering - Range 2*/ tbl_prog_brdgeport_ingress.val[12] &= ~(1 << 14); + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) { + idx = gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId; + /*release the usage of vlan block id, if it is assigned previously + when vlan filter operation is disabled,it is must to release + the mapped vlan filter resource*/ + gswdev->vlanfilter_idx.filter_idx[idx].IndexInUsageCnt--; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId = VLANFILTER_ENTRY_INVALID; + } } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT) - { - if(param->bMacLearningLimitEnable) { + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT) { + if (param->bMacLearningLimitEnable) { tbl_prog_brdgeport_ingress.val[4] &= ~0xFF; tbl_prog_brdgeport_ingress.val[4] |= (param->nMacLearningLimit & 0xFF); - gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit= - param->nMacLearningLimit; - } - } - /*Same bridge port idx for ingress and egress bridge port configuration*/ + gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit = + param->nMacLearningLimit; + } + } + + /*Same bridge port idx for ingress and egress bridge port configuration*/ tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); - + /*Address-based write for ingress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_ingress); /*Address-based write for egress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_egress); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } -GSW_return_t GSW_BridgePortFree(void *cdev, GSW_BRIDGE_portAlloc_t *param) +GSW_return_t GSW_BridgePortFree(void *cdev, GSW_BRIDGE_portAlloc_t *param) { pctbl_prog_t tbl_prog_brdgeport_ingress; pctbl_prog_t tbl_prog_brdgeport_egress; GSW_BRIDGE_portConfig_t temp; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 FirstIdx,count; + u32 FirstIdx, count; + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (param->nBridgePortId >= gswdev->num_of_bridge_port) { - pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n",param->nBridgePortId,(gswdev->num_of_bridge_port - 1)); - return GSW_statusErr; + pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n", param->nBridgePortId, (gswdev->num_of_bridge_port - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - + /*If Bridge Port ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse) { - pr_err("nBridgePortId %u is Not inUse -> need to allocate before freeing\n",param->nBridgePortId); - return GSW_statusErr; + if (!gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse) { + pr_err("nBridgePortId %u is Not inUse -> need to allocate before freeing\n", param->nBridgePortId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /*If this Bridge port usage count is not zero that means it is still used by some one. - This Bridge configuration can be deleted, only if that some one release this Bridge + This Bridge configuration can be deleted, only if that some one release this Bridge port*/ if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUsageCnt) { - count = gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUsageCnt; - pr_err("BridgePortId %u's IndexInUsageCnt=%u is not Zero ??!!, some CTP is holding this BP ??\n", - param->nBridgePortId,count); - pr_err("Free that CTP first,which will detach this association\n"); - return GSW_statusErr; + count = gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUsageCnt; + pr_err("BridgePortId %u's IndexInUsageCnt=%u is not Zero , some CTP is holding this BP \n", + param->nBridgePortId, count); + pr_err("Free that CTP first,which will detach this association\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - /*Same Bridge port idx for ingress and egress bridge port configuration*/ + + /*Same Bridge port idx for ingress and egress bridge port configuration*/ memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); @@ -18251,328 +23023,344 @@ GSW_return_t GSW_BridgePortFree(void *cdev, GSW_BRIDGE_portAlloc_t *param) gsw_pce_table_read(cdev, &tbl_prog_brdgeport_egress); temp.nBridgeId = ((tbl_prog_brdgeport_ingress.val[4] & 0x3F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId == - temp.nBridgeId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId == + temp.nBridgeId) { /*Release this Bridge from this Bridge Port*/ gswdev->brdgeconfig_idx[temp.nBridgeId].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgIdAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BrdgId = 0; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + temp.nIngressExtendedVlanBlockId = (tbl_prog_brdgeport_ingress.val[1] & 0x3FFF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId == - temp.nIngressExtendedVlanBlockId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId == + temp.nIngressExtendedVlanBlockId) { /*Release this vlan blk from this Bridge Port*/ - FirstIdx=temp.nIngressExtendedVlanBlockId; + FirstIdx = temp.nIngressExtendedVlanBlockId; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId=0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressExVlanBlkId = EXVLAN_ENTRY_INVALID; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + temp.nEgressExtendedVlanBlockId = (tbl_prog_brdgeport_egress.val[1] & 0x3FFF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId == - temp.nEgressExtendedVlanBlockId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId == + temp.nEgressExtendedVlanBlockId) { /*Release this vlan blk from this Bridge Port*/ - FirstIdx=temp.nEgressExtendedVlanBlockId; + FirstIdx = temp.nEgressExtendedVlanBlockId; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressExVlanBlkId = EXVLAN_ENTRY_INVALID; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + temp.nIngressTrafficMeterId = ((tbl_prog_brdgeport_ingress.val[3] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId == - temp.nIngressTrafficMeterId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId == + temp.nIngressTrafficMeterId) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nIngressTrafficMeterId].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressTrafficMeterId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } + /*other meter*/ temp.nEgressTrafficSubMeterId[5] = ((tbl_prog_brdgeport_egress.val[3] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId == - temp.nEgressTrafficSubMeterId[5]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId == + temp.nEgressTrafficSubMeterId[5]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[5]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressTrafficMeterId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + /*Egress Broadcast Meter*/ temp.nEgressTrafficSubMeterId[0] = ((tbl_prog_brdgeport_egress.val[5] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId == - temp.nEgressTrafficSubMeterId[0]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId == + temp.nEgressTrafficSubMeterId[0]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[0]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].BroadcastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Multicast Meter*/ temp.nEgressTrafficSubMeterId[1] = ((tbl_prog_brdgeport_egress.val[6] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId == - temp.nEgressTrafficSubMeterId[1]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId == + temp.nEgressTrafficSubMeterId[1]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[1]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].MulticastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown Multicast IP Meter*/ temp.nEgressTrafficSubMeterId[2] = ((tbl_prog_brdgeport_egress.val[9] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId == - temp.nEgressTrafficSubMeterId[2]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId == + temp.nEgressTrafficSubMeterId[2]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[2]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiIpMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown Multicast NON IP Meter*/ temp.nEgressTrafficSubMeterId[3] = ((tbl_prog_brdgeport_egress.val[8] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId == - temp.nEgressTrafficSubMeterId[3]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId == + temp.nEgressTrafficSubMeterId[3]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[3]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownMultiNonIpMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } /*Egress Unknown UniCast Meter*/ temp.nEgressTrafficSubMeterId[4] = ((tbl_prog_brdgeport_egress.val[7] & 0x7F00) >> 8); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId == - temp.nEgressTrafficSubMeterId[4]) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId == + temp.nEgressTrafficSubMeterId[4]) { /*Release this meter id from this Bridge Port*/ gswdev->meter_idx[temp.nEgressTrafficSubMeterId[4]].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].UnknownUniCastMeteringId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } temp.sPmapper.nPmapperId = (tbl_prog_brdgeport_egress.val[4] & 0xFF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) - { - /*Release this p-mapper idx from this Bridge Port*/ - gswdev->pmapper_idx[temp.sPmapper.nPmapperId].IndexInUse=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx=0; - } - + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned) { + /*Release this p-mapper idx from this Bridge Port*/ + gswdev->pmapper_idx[temp.sPmapper.nPmapperId].IndexInUse = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].PmapperAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].PmappperIdx = 0; + } + temp.nIngressVlanFilterBlockId = (tbl_prog_brdgeport_ingress.val[5] & 0x3FF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId == - temp.nIngressVlanFilterBlockId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId == + temp.nIngressVlanFilterBlockId) { /*Release this vlan blk from this Bridge Port*/ - FirstIdx=temp.nIngressVlanFilterBlockId; + FirstIdx = temp.nIngressVlanFilterBlockId; gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterAssigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].IngressVlanFilterBlkId = VLANFILTER_ENTRY_INVALID; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + temp.nEgressVlanFilter1BlockId = (tbl_prog_brdgeport_egress.val[10] & 0x3FF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId == - temp.nEgressVlanFilter1BlockId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId == + temp.nEgressVlanFilter1BlockId) { /*Release this vlan blk from this Bridge Port*/ - FirstIdx=temp.nEgressVlanFilter1BlockId; + FirstIdx = temp.nEgressVlanFilter1BlockId; gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter1BlkId = VLANFILTER_ENTRY_INVALID; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - + } + temp.nEgressVlanFilter2BlockId = (tbl_prog_brdgeport_egress.val[12] & 0x3FF); - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) - { - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId == - temp.nEgressVlanFilter2BlockId) - { + + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned) { + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId == + temp.nEgressVlanFilter2BlockId) { /*Release this vlan blk from this Bridge Port*/ - FirstIdx=temp.nEgressVlanFilter2BlockId; + FirstIdx = temp.nEgressVlanFilter2BlockId; gswdev->vlanfilter_idx.filter_idx[FirstIdx].IndexInUsageCnt--; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned=0; - gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId=0; - + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2Assigned = 0; + gswdev->brdgeportconfig_idx[param->nBridgePortId].EgressVlanFilter2BlkId = VLANFILTER_ENTRY_INVALID; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - /*Zero the ingress/egress bridge port table index*/ - /*Same Bridge port idx for ingress and egress bridge port configuration*/ + } + + /*Zero the ingress/egress bridge port table index*/ + /*Same Bridge port idx for ingress and egress bridge port configuration*/ memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); - - /*Restore the Learing Limit 255*/ - tbl_prog_brdgeport_ingress.val[4] |= 0xFF; - gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit=0xFF; + + /*Restore the Learing Limit 255*/ + tbl_prog_brdgeport_ingress.val[4] |= 0xFF; + gswdev->brdgeportconfig_idx[param->nBridgePortId].LearningLimit = 0xFF; /*Stp State disabled for all traffic*/ - tbl_prog_brdgeport_ingress.val[0] |= 0x3; - tbl_prog_brdgeport_egress.val[0] |= 0x3; - gswdev->brdgeportconfig_idx[param->nBridgePortId].StpState= - GSW_STP_PORT_STATE_DISABLE; - gswdev->brdgeportconfig_idx[param->nBridgePortId].P8021xState= - GSW_8021X_PORT_STATE_UNAUTHORIZED; - + tbl_prog_brdgeport_ingress.val[0] |= 0x3; + tbl_prog_brdgeport_egress.val[0] |= 0x3; + gswdev->brdgeportconfig_idx[param->nBridgePortId].StpState = + GSW_STP_PORT_STATE_DISABLE; + gswdev->brdgeportconfig_idx[param->nBridgePortId].P8021xState = + GSW_8021X_PORT_STATE_UNAUTHORIZED; + /*Address-based write for ingress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_ingress); /*Address-based write for egress bridge port configuration*/ gsw_pce_table_write(cdev, &tbl_prog_brdgeport_egress); /*Free this bridge port idx*/ - gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse=0; - - return GSW_statusOk; -} + gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse = 0; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} -GSW_return_t GSW_BridgePortConfigGet(void *cdev, GSW_BRIDGE_portConfig_t *param) +GSW_return_t GSW_BridgePortConfigGet(void *cdev, GSW_BRIDGE_portConfig_t *param) { pctbl_prog_t tbl_prog_brdgeport_ingress; pctbl_prog_t tbl_prog_brdgeport_egress; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 value; - u16 i,val_reg_idx,ret; + u32 value, FirstIdx, LastIdx, BlkSize; + u16 i, val_reg_idx, ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + if (param->nBridgePortId >= gswdev->num_of_bridge_port) { - pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n",param->nBridgePortId,(gswdev->num_of_bridge_port - 1)); - return GSW_statusErr; + pr_err("nBridgePortId %d is out of range [num_of_bridge_port supported =%d]\n", param->nBridgePortId, (gswdev->num_of_bridge_port - 1)); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /*GSW_BRIDGE_PORT_CONFIG_MASK_FORCE is for debugging purpose only if this mask is enabled , there is no check on index in-use*/ - if(!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) - { + if (!(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_FORCE)) { /*If Bridge Port ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!(gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse)) - return GSW_statusErr; - } + if (!(gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + } - /*Same bridge port idx for ingress and egress bridge port configuration*/ + /*Same bridge port idx for ingress and egress bridge port configuration*/ memset(&tbl_prog_brdgeport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_ingress.table = PCE_IGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_ingress.pcindex); /*Table Entry address (Bridge port ingress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_ingress.pcindex |= (param->nBridgePortId & 0xFF); memset(&tbl_prog_brdgeport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_brdgeport_egress.table = PCE_EGBGP_INDEX; - CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); + CLEAR_U16(tbl_prog_brdgeport_egress.pcindex); /*Table Entry address (Bridge port egress Table index) Bit 7:0 in PCE_TBL_ADDR*/ tbl_prog_brdgeport_egress.pcindex |= (param->nBridgePortId & 0xFF); @@ -18581,206 +23369,280 @@ GSW_return_t GSW_BridgePortConfigGet(void *cdev, GSW_BRIDGE_portConfig_t *param) /*Address-based read for egress bridge port configuration*/ gsw_pce_table_read(cdev, &tbl_prog_brdgeport_egress); - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID) + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID) param->nBridgeId = ((tbl_prog_brdgeport_ingress.val[4] & 0x3F00) >> 8); - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT) + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT) param->nMacLearningLimit = (tbl_prog_brdgeport_ingress.val[4] & 0xFF); - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN) - { - param->bIngressExtendedVlanEnable=((tbl_prog_brdgeport_ingress.val[1] & 0x4000) >> 14); - if(param->bIngressExtendedVlanEnable) - param->nIngressExtendedVlanBlockId=((tbl_prog_brdgeport_ingress.val[1] & 0x3FF)); - } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN) - { - param->bEgressExtendedVlanEnable=((tbl_prog_brdgeport_egress.val[1] & 0x4000) >> 14); - if(param->bEgressExtendedVlanEnable) - param->nEgressExtendedVlanBlockId=(tbl_prog_brdgeport_egress.val[1] & 0x3FF); - } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING) - { - value = (tbl_prog_brdgeport_ingress.val[3] & 0x7); - switch(value) - { - case 0: - param->eIngressMarkingMode=GSW_MARKING_ALL_GREEN; - break; - case 1: - param->eIngressMarkingMode=GSW_MARKING_INTERNAL_MARKING; - break; - case 2: - param->eIngressMarkingMode=GSW_MARKING_DEI; - break; - case 3: - param->eIngressMarkingMode=GSW_MARKING_PCP_8P0D; - break; - case 4: - param->eIngressMarkingMode=GSW_MARKING_PCP_7P1D; - break; - case 5: - param->eIngressMarkingMode=GSW_MARKING_PCP_6P2D; - break; - case 6: - param->eIngressMarkingMode=GSW_MARKING_PCP_5P3D; - break; - case 7: - param->eIngressMarkingMode=GSW_MARKING_DSCP_AF; - break; - } - } + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN) { + param->bIngressExtendedVlanEnable = ((tbl_prog_brdgeport_ingress.val[1] & 0x4000) >> 14); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING) - { - value = (tbl_prog_brdgeport_egress.val[3] & 0x7); - switch(value) - { - case 0: - param->eEgressRemarkingMode=GSW_REMARKING_NONE; - break; - case 1: - param->eEgressRemarkingMode=GSW_REMARKING_NONE; - break; - case 2: - param->eEgressRemarkingMode=GSW_REMARKING_DEI; - break; - case 3: - param->eEgressRemarkingMode=GSW_REMARKING_PCP_8P0D; - break; - case 4: - param->eEgressRemarkingMode=GSW_REMARKING_PCP_7P1D; - break; - case 5: - param->eEgressRemarkingMode=GSW_REMARKING_PCP_6P2D; - break; - case 6: - param->eEgressRemarkingMode=GSW_REMARKING_PCP_5P3D; - break; - case 7: - param->eEgressRemarkingMode=GSW_REMARKING_DSCP_AF; - break; + if (param->bIngressExtendedVlanEnable) { + param->nIngressExtendedVlanBlockId = ((tbl_prog_brdgeport_ingress.val[1] & 0x3FF)); + FirstIdx = param->nIngressExtendedVlanBlockId; + LastIdx = (tbl_prog_brdgeport_ingress.val[2] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nIngressExtendedVlanBlockSize = BlkSize; } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER) - { - param->bIngressMeteringEnable=((tbl_prog_brdgeport_ingress.val[3] & 0x80) >> 7); - if(param->bIngressMeteringEnable) - param->nIngressTrafficMeterId=((tbl_prog_brdgeport_ingress.val[3] & 0x7F00) >> 8); - } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER) - { - /*Broadcast meter*/ - param->bEgressSubMeteringEnable[0]=((tbl_prog_brdgeport_egress.val[5] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[0]) - param->nEgressTrafficSubMeterId[0]=((tbl_prog_brdgeport_egress.val[5] & 0x7F00) >> 8); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN) { + param->bEgressExtendedVlanEnable = ((tbl_prog_brdgeport_egress.val[1] & 0x4000) >> 14); - /*multicast meter*/ - param->bEgressSubMeteringEnable[1]=((tbl_prog_brdgeport_egress.val[6] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[1]) - param->nEgressTrafficSubMeterId[1]=((tbl_prog_brdgeport_egress.val[6] & 0x7F00) >> 8); + if (param->bEgressExtendedVlanEnable) { + param->nEgressExtendedVlanBlockId = (tbl_prog_brdgeport_egress.val[1] & 0x3FF); + FirstIdx = param->nEgressExtendedVlanBlockId; + LastIdx = (tbl_prog_brdgeport_egress.val[2] & 0x3FF); - /*unknown multicast ip meter*/ - param->bEgressSubMeteringEnable[2]=((tbl_prog_brdgeport_egress.val[9] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[2]) - param->nEgressTrafficSubMeterId[2]=((tbl_prog_brdgeport_egress.val[9] & 0x7F00) >> 8); + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); - /*unknown multicast Non ip meter*/ - param->bEgressSubMeteringEnable[3]=((tbl_prog_brdgeport_egress.val[8] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[3]) - param->nEgressTrafficSubMeterId[3]=((tbl_prog_brdgeport_egress.val[8] & 0x7F00) >> 8); + param->nEgressExtendedVlanBlockSize = BlkSize; + } + } + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING) { + value = (tbl_prog_brdgeport_ingress.val[3] & 0x7); - /*unknown unicast meter*/ - param->bEgressSubMeteringEnable[4]=((tbl_prog_brdgeport_egress.val[7] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[4]) - param->nEgressTrafficSubMeterId[4]=((tbl_prog_brdgeport_egress.val[7] & 0x7F00) >> 8); + switch (value) { + case 0: + param->eIngressMarkingMode = GSW_MARKING_ALL_GREEN; + break; + + case 1: + param->eIngressMarkingMode = GSW_MARKING_INTERNAL_MARKING; + break; + + case 2: + param->eIngressMarkingMode = GSW_MARKING_DEI; + break; + + case 3: + param->eIngressMarkingMode = GSW_MARKING_PCP_8P0D; + break; + + case 4: + param->eIngressMarkingMode = GSW_MARKING_PCP_7P1D; + break; + + case 5: + param->eIngressMarkingMode = GSW_MARKING_PCP_6P2D; + break; + + case 6: + param->eIngressMarkingMode = GSW_MARKING_PCP_5P3D; + break; + + case 7: + param->eIngressMarkingMode = GSW_MARKING_DSCP_AF; + break; + } + } + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING) { + value = (tbl_prog_brdgeport_egress.val[3] & 0x7); + + switch (value) { + case 0: + param->eEgressRemarkingMode = GSW_REMARKING_NONE; + break; + + case 1: + param->eEgressRemarkingMode = GSW_REMARKING_NONE; + break; + + case 2: + param->eEgressRemarkingMode = GSW_REMARKING_DEI; + break; + + case 3: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_8P0D; + break; + + case 4: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_7P1D; + break; + + case 5: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_6P2D; + break; + + case 6: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_5P3D; + break; + + case 7: + param->eEgressRemarkingMode = GSW_REMARKING_DSCP_AF; + break; + } + } + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER) { + param->bIngressMeteringEnable = ((tbl_prog_brdgeport_ingress.val[3] & 0x80) >> 7); + + if (param->bIngressMeteringEnable) + param->nIngressTrafficMeterId = ((tbl_prog_brdgeport_ingress.val[3] & 0x7F00) >> 8); + } + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER) { + /*Broadcast meter*/ + param->bEgressSubMeteringEnable[0] = ((tbl_prog_brdgeport_egress.val[5] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[0]) + param->nEgressTrafficSubMeterId[0] = ((tbl_prog_brdgeport_egress.val[5] & 0x7F00) >> 8); + + /*multicast meter*/ + param->bEgressSubMeteringEnable[1] = ((tbl_prog_brdgeport_egress.val[6] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[1]) + param->nEgressTrafficSubMeterId[1] = ((tbl_prog_brdgeport_egress.val[6] & 0x7F00) >> 8); + + /*unknown multicast ip meter*/ + param->bEgressSubMeteringEnable[2] = ((tbl_prog_brdgeport_egress.val[9] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[2]) + param->nEgressTrafficSubMeterId[2] = ((tbl_prog_brdgeport_egress.val[9] & 0x7F00) >> 8); + + /*unknown multicast Non ip meter*/ + param->bEgressSubMeteringEnable[3] = ((tbl_prog_brdgeport_egress.val[8] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[3]) + param->nEgressTrafficSubMeterId[3] = ((tbl_prog_brdgeport_egress.val[8] & 0x7F00) >> 8); + + + /*unknown unicast meter*/ + param->bEgressSubMeteringEnable[4] = ((tbl_prog_brdgeport_egress.val[7] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[4]) + param->nEgressTrafficSubMeterId[4] = ((tbl_prog_brdgeport_egress.val[7] & 0x7F00) >> 8); /*other meter*/ - param->bEgressSubMeteringEnable[5]=((tbl_prog_brdgeport_egress.val[3] & 0x80) >> 7); - if(param->bEgressSubMeteringEnable[5]) - param->nEgressTrafficSubMeterId[5]=((tbl_prog_brdgeport_egress.val[3] & 0x7F00) >> 8); + param->bEgressSubMeteringEnable[5] = ((tbl_prog_brdgeport_egress.val[3] & 0x80) >> 7); + + if (param->bEgressSubMeteringEnable[5]) + param->nEgressTrafficSubMeterId[5] = ((tbl_prog_brdgeport_egress.val[3] & 0x7F00) >> 8); } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING) - { + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING) { param->nDestLogicalPortId = ((tbl_prog_brdgeport_egress.val[4] & 0xF00) >> 8); - param->bPmapperEnable=((tbl_prog_brdgeport_egress.val[4] & 0x4000) >> 14 ); - param->ePmapperMappingMode=((tbl_prog_brdgeport_egress.val[4] & 0x2000) >> 13 ); + param->bPmapperEnable = ((tbl_prog_brdgeport_egress.val[4] & 0x4000) >> 14); + param->ePmapperMappingMode = ((tbl_prog_brdgeport_egress.val[4] & 0x2000) >> 13); + if (param->bPmapperEnable) { - param->sPmapper.nPmapperId=(tbl_prog_brdgeport_egress.val[4] & 0xFF); - ret=GSW_QOS_PmapperTableGet(cdev,¶m->sPmapper); - if(ret == GSW_statusErr) { + param->sPmapper.nPmapperId = (tbl_prog_brdgeport_egress.val[4] & 0xFF); + ret = GSW_QOS_PmapperTableGet(cdev, ¶m->sPmapper); + + if (ret == GSW_statusErr) { pr_err("ERROR :P-mapper Get return Error\n"); - return GSW_statusErr; + goto UNLOCK_AND_RETURN; } } else { - param->nDestSubIfIdGroup=(tbl_prog_brdgeport_egress.val[4] & 0xFF); + param->nDestSubIfIdGroup = (tbl_prog_brdgeport_egress.val[4] & 0xFF); } } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP) - { - val_reg_idx=10; - for(i=0;i < 8;i++) - { - param->nBridgePortMap[i]=( tbl_prog_brdgeport_ingress.val[val_reg_idx] & 0xFFFF); + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP) { + val_reg_idx = 10; + + for (i = 0; i < 8; i++) { + param->nBridgePortMap[i] = (tbl_prog_brdgeport_ingress.val[val_reg_idx] & 0xFFFF); val_reg_idx++; } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP) - param->bMcDestIpLookupDisable=((tbl_prog_brdgeport_ingress.val[0] & 0x2000) >> 13); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP) + param->bMcDestIpLookupDisable = ((tbl_prog_brdgeport_ingress.val[0] & 0x2000) >> 13); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP) - param->bMcSrcIpLookupEnable=((tbl_prog_brdgeport_ingress.val[0] & 0x200) >> 9); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP) + param->bMcSrcIpLookupEnable = ((tbl_prog_brdgeport_ingress.val[0] & 0x200) >> 9); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP) - param->bDestMacLookupDisable=((tbl_prog_brdgeport_ingress.val[0] & 0x4000) >> 14); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP) + param->bDestMacLookupDisable = ((tbl_prog_brdgeport_ingress.val[0] & 0x4000) >> 14); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING) - param->bSrcMacLearningDisable=((tbl_prog_brdgeport_ingress.val[0] & 0x8000) >> 15); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING) + param->bSrcMacLearningDisable = ((tbl_prog_brdgeport_ingress.val[0] & 0x8000) >> 15); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING) - param->bMacSpoofingDetectEnable=((tbl_prog_brdgeport_ingress.val[0] & 0x800) >> 11); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING) + param->bMacSpoofingDetectEnable = ((tbl_prog_brdgeport_ingress.val[0] & 0x800) >> 11); - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK) - param->bPortLockEnable=((tbl_prog_brdgeport_ingress.val[0] & 0x1000) >> 12); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK) + param->bPortLockEnable = ((tbl_prog_brdgeport_ingress.val[0] & 0x1000) >> 12); - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER) - { - param->bIngressVlanFilterEnable= ((tbl_prog_brdgeport_ingress.val[5] & 0x4000) >> 14); - if(param->bIngressVlanFilterEnable) - param->nIngressVlanFilterBlockId=(tbl_prog_brdgeport_ingress.val[5] & 0x3FF); - param->bBypassEgressVlanFilter1=((tbl_prog_brdgeport_ingress.val[5] & 0x8000) >> 15); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER) { + param->bIngressVlanFilterEnable = ((tbl_prog_brdgeport_ingress.val[5] & 0x4000) >> 14); + + if (param->bIngressVlanFilterEnable) { + param->nIngressVlanFilterBlockId = (tbl_prog_brdgeport_ingress.val[5] & 0x3FF); + FirstIdx = param->nIngressVlanFilterBlockId; + LastIdx = (tbl_prog_brdgeport_ingress.val[6] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nIngressVlanFilterBlockSize = BlkSize; + } + + param->bBypassEgressVlanFilter1 = ((tbl_prog_brdgeport_ingress.val[5] & 0x8000) >> 15); } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1) - { - param->bEgressVlanFilter1Enable= ((tbl_prog_brdgeport_egress.val[10] & 0x4000) >> 14); - if(param->bEgressVlanFilter1Enable) - param->nEgressVlanFilter1BlockId=(tbl_prog_brdgeport_egress.val[10] & 0x3FF); + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1) { + param->bEgressVlanFilter1Enable = ((tbl_prog_brdgeport_egress.val[10] & 0x4000) >> 14); + + if (param->bEgressVlanFilter1Enable) { + param->nEgressVlanFilter1BlockId = (tbl_prog_brdgeport_egress.val[10] & 0x3FF); + FirstIdx = param->nEgressVlanFilter1BlockId; + LastIdx = (tbl_prog_brdgeport_egress.val[11] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nEgressVlanFilter1BlockSize = BlkSize; + } } - - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2) - { - param->bEgressVlanFilter2Enable= ((tbl_prog_brdgeport_egress.val[12] & 0x4000) >> 14); - if(param->bEgressVlanFilter2Enable) - param->nEgressVlanFilter2BlockId=(tbl_prog_brdgeport_egress.val[12] & 0x3FF); + + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2) { + param->bEgressVlanFilter2Enable = ((tbl_prog_brdgeport_egress.val[12] & 0x4000) >> 14); + + if (param->bEgressVlanFilter2Enable) { + param->nEgressVlanFilter2BlockId = (tbl_prog_brdgeport_egress.val[12] & 0x3FF); + FirstIdx = param->nEgressVlanFilter2BlockId; + LastIdx = (tbl_prog_brdgeport_egress.val[13] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nEgressVlanFilter2BlockSize = BlkSize; + } } - if(param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNED_COUNT) - param->nMacLearningCount= (tbl_prog_brdgeport_ingress.val[9] & 0x1FFF); + if (param->eMask & GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNED_COUNT) + param->nMacLearningCount = (tbl_prog_brdgeport_ingress.val[9] & 0x1FFF); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) @@ -18788,72 +23650,82 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) pctbl_prog_t tbl_prog_ctpport_ingress; pctbl_prog_t tbl_prog_ctpport_egress; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 idx=0,FirstIdx,LastIdx,pmapper_idx,ctp_port; - u16 ret; + u32 idx = 0, FirstIdx, LastIdx, pmapper_idx, ctp_port; + u32 BlkSize = 0; + u32 ret; GSW_CTP_portAssignment_t ctp_get; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /*Checking based on number of logical port*/ if (param->nLogicalPortId >= gswdev->tpnum) { - pr_err("nLogicalPortId %d >= gswdev->pnum %d\n",param->nLogicalPortId,gswdev->pnum); - return GSW_statusErr; - } - - /*CTP ports has to assigned/mapped to Logical port before calling + pr_err("nLogicalPortId %d >= gswdev->pnum %d\n", param->nLogicalPortId, gswdev->pnum); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*CTP ports has to assigned/mapped to Logical port before calling CTP port configuration. GSW_CTP_PortAssignmentGet will get the info on the assignment Use this info to find whether this CTP port is with in the range this logical port */ - ctp_get.nLogicalPortId=param->nLogicalPortId; - ret=GSW_CTP_PortAssignmentGet(cdev,&ctp_get); - if(ret==GSW_statusErr) { + ctp_get.nLogicalPortId = param->nLogicalPortId; + ret = GSW_CTP_PortAssignmentGet(cdev, &ctp_get); + + if (ret == GSW_statusErr) { pr_err("GSW_CTP_PortAssignmentGet returns ERROR\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /*IMPORTANT NOTE : :As per the CTP concept nFirstCtpPortId + nSubIfIdGroup is the expected CTP port*/ - ctp_port=ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; + ctp_port = ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; + if (ctp_port >= gswdev->num_of_ctp) { - pr_err("ctp_port %d >= gswdev->num_of_ctp %d\n",ctp_port,gswdev->num_of_ctp); - return GSW_statusErr; - } + pr_err("ctp_port %d >= gswdev->num_of_ctp %d\n", ctp_port, gswdev->num_of_ctp); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If not with in the Assigned range Return Error -This check is just extra*/ + if (ctp_port < ctp_get.nFirstCtpPortId || + ctp_port >= (ctp_get.nFirstCtpPortId + ctp_get.nNumberOfCtpPort)) { + pr_err("ERROR:ctp_port %d Assigned range not correct\n", ctp_port); + pr_err("ERROR:Check using CTP assignment get\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - /*If not with in the Assigned range Return Error -This check is just extra*/ - if(ctp_port < ctp_get.nFirstCtpPortId || - ctp_port >= (ctp_get.nFirstCtpPortId +ctp_get.nNumberOfCtpPort)) { - pr_err("ERROR:ctp_port %d Assigned range not correct\n",ctp_port); - pr_err("ERROR:Check using CTP assignment get\n"); - return GSW_statusErr; - } - /*NOTE : This Mask is for debugging purpose only If GSW_CTP_PORT_CONFIG_MASK_FORCE mask is set It will not check index in-use */ - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) - { - pr_err("ERROR :ctp_port %d Index not in use,CTP not allocated\n",ctp_port); - return GSW_statusErr; - } + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ + if (!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) { + pr_err("ERROR :ctp_port %d Index not in use,CTP not allocated\n", ctp_port); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } - /*Same ctp port idx for ingress and egress ctp port configuration*/ + /*Same ctp port idx for ingress and egress ctp port configuration*/ memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); + CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_egress.pcindex); + CLEAR_U16(tbl_prog_ctpport_egress.pcindex); /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); @@ -18868,140 +23740,143 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) is not disturbed in the case of update specific fields. */ gsw_pce_table_read(cdev, &tbl_prog_ctpport_egress); - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID) - { + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID) { if (param->nBridgePortId >= gswdev->num_of_bridge_port) { pr_err("nBridgePortId (%i) >= num_of_bridge_port (%i)\n", param->nBridgePortId, gswdev->num_of_bridge_port); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { - /*This below field enable indicates that this bridge port id is + /*This below field enable indicates that this bridge port id is already assigned and it's idx recorded for this CTP Port id. - If next time the user update this field with different - bridge port idx !!or wanted to allocate a new bridge port idx ??!! + If next time the user update this field with different + bridge port idx !!or wanted to allocate a new bridge port idx ??!! may happen by mistake ??!! the previous bridge port idx must be released from this CTP Port*/ - if(gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].BrdgPortId != - param->nBridgePortId) - { - idx=gswdev->ctpportconfig_idx[ctp_port].BrdgPortId; + if (gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].BrdgPortId != + param->nBridgePortId) { + idx = gswdev->ctpportconfig_idx[ctp_port].BrdgPortId; /*release the usage of previous bridge port idx*/ gswdev->brdgeportconfig_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].BrdgPortId=0; + gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].BrdgPortId = 0; } } - - /*This Bridge Port ID should be in use (i.e) that is this Bridge Port ID + + /*This Bridge Port ID should be in use (i.e) that is this Bridge Port ID should be allocated - before calling CTP port configuration + before calling CTP port configuration If not in use return ERROR */ - if(gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse) - { - /*Usage count will be incremented only once during bridge port idx assignment + if (gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUse) { + /*Usage count will be incremented only once during bridge port idx assignment for this CTP port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) { + gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].BrdgPortId - =param->nBridgePortId; + = param->nBridgePortId; /*Since this bridge port id can be shared,Increment it's usage count*/ gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUsageCnt++; } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + tbl_prog_ctpport_ingress.val[0] &= ~(0xFF); tbl_prog_ctpport_ingress.val[0] |= (param->nBridgePortId & 0xFF); } - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS) - { + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS) { /** Default traffic class associated with all traffic from this CTP Port. */ tbl_prog_ctpport_ingress.val[0] &= ~(0xF << 8); tbl_prog_ctpport_ingress.val[0] |= ((param->nDefaultTrafficClass & 0xF) << 8); /** Default traffic class can not be overridden by other rules (except traffic flow table and special tag) in following stages. */ - /* 0 -Traffic class can be over written by the following processing stage - 1 -Traffic class can not be over written by the following processing stage - */ - if(param->bForcedTrafficClass) - tbl_prog_ctpport_ingress.val[0] |= (1 << 12); - else - tbl_prog_ctpport_ingress.val[0] &= ~(1 << 12); + /* 0 -Traffic class can be over written by the following processing stage + 1 -Traffic class can not be over written by the following processing stage + */ + if (param->bForcedTrafficClass) + tbl_prog_ctpport_ingress.val[0] |= (1 << 12); + else + tbl_prog_ctpport_ingress.val[0] &= ~(1 << 12); } - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN) - { - if(param->bIngressExtendedVlanEnable) - { - /*This below field enable indicates that this vlan block is + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN) { + if (param->bIngressExtendedVlanEnable) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this CTP Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this CTP Port*/ - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId != - param->nIngressExtendedVlanBlockId) - { - idx=gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId; + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId != + param->nIngressExtendedVlanBlockId) { + idx = gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; } } } - + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nIngressExtendedVlanBlockId; - if(FirstIdx > gswdev->num_of_extendvlan) { - pr_err("FirstIdx %d > gswdev->num_of_extendvlan %d\n",FirstIdx,gswdev->num_of_egvlan); - return GSW_statusErr; + FirstIdx = param->nIngressExtendedVlanBlockId; + + if (FirstIdx > gswdev->num_of_extendvlan) { + pr_err("FirstIdx %d > gswdev->num_of_extendvlan %d\n", FirstIdx, gswdev->num_of_egvlan); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - + /*Check whether this index is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { - pr_err("Not in use gswdev->extendvlan_idx.vlan_idx[%d].IndexInUse\n",FirstIdx); - return GSW_statusErr; + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + pr_err("Not in use gswdev->extendvlan_idx.vlan_idx[%d].IndexInUse\n", FirstIdx); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nIngressExtendedVlanBlockId) { + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nIngressExtendedVlanBlockId) { pr_err("gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId != param->nIngressExtendedVlanBlockId\n"); - pr_err("param->nIngressExtendedVlanBlockId = %d\n",param->nIngressExtendedVlanBlockId); - return GSW_statusErr; + pr_err("param->nIngressExtendedVlanBlockId = %d\n", param->nIngressExtendedVlanBlockId); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nIngressExtendedVlanBlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_ctpport_ingress.val[1] |= (1 << 14); /*Set First Index of the Block*/ @@ -19009,17 +23884,15 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) tbl_prog_ctpport_ingress.val[1] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_ctpport_ingress.val[2] &= ~(0x3FF); - tbl_prog_ctpport_ingress.val[2] |= ((LastIdx-1) & 0x3FF); + tbl_prog_ctpport_ingress.val[2] |= ((LastIdx - 1) & 0x3FF); - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this CTP port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) { + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId - =param->nIngressExtendedVlanBlockId; + = param->nIngressExtendedVlanBlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -19027,62 +23900,81 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) } else { /*Disable ingress Extended VLAN non igmp*/ tbl_prog_ctpport_ingress.val[1] &= ~(1 << 14); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) { + idx = gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; + } } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP) - { - if(param->bIngressExtendedVlanIgmpEnable) - { - /*This below field enable indicates that this vlan block is + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP) { + if (param->bIngressExtendedVlanIgmpEnable) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this CTP Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this CTP Port*/ - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId != - param->nIngressExtendedVlanBlockIdIgmp) - { - idx=gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId; + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId != + param->nIngressExtendedVlanBlockIdIgmp) { + idx = gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; } } } /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nIngressExtendedVlanBlockIdIgmp; - if(FirstIdx > gswdev->num_of_extendvlan) - return GSW_statusErr; - + FirstIdx = param->nIngressExtendedVlanBlockIdIgmp; + + if (FirstIdx > gswdev->num_of_extendvlan) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) - return GSW_statusErr; + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nIngressExtendedVlanBlockIdIgmp) - return GSW_statusErr; + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nIngressExtendedVlanBlockIdIgmp) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nIngressExtendedVlanBlockSizeIgmp; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_ctpport_ingress.val[5] |= (1 << 14); /*Set First Index of the Block*/ @@ -19090,17 +23982,15 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) tbl_prog_ctpport_ingress.val[5] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_ctpport_ingress.val[6] &= ~(0x3FF); - tbl_prog_ctpport_ingress.val[6] |= ((LastIdx-1) & 0x3FF); + tbl_prog_ctpport_ingress.val[6] |= ((LastIdx - 1) & 0x3FF); - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this CTP port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) { + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId - =param->nIngressExtendedVlanBlockIdIgmp; + = param->nIngressExtendedVlanBlockIdIgmp; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -19108,62 +23998,82 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) } else { /*Disable ingress Extended VLAN igmp*/ tbl_prog_ctpport_ingress.val[5] &= ~(1 << 14); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) { + idx = gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + } } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN) - { - if(param->bEgressExtendedVlanEnable) - { - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN) { + if (param->bEgressExtendedVlanEnable) { + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this CTP Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this CTP Port*/ - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId != - param->nEgressExtendedVlanBlockId) - { - idx=gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId; + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId != + param->nEgressExtendedVlanBlockId) { + idx = gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; } } } + /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nEgressExtendedVlanBlockId; - if(FirstIdx > gswdev->num_of_extendvlan) - return GSW_statusErr; - + FirstIdx = param->nEgressExtendedVlanBlockId; + + if (FirstIdx > gswdev->num_of_extendvlan) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) - return GSW_statusErr; + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nEgressExtendedVlanBlockId) - return GSW_statusErr; + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nEgressExtendedVlanBlockId) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nEgressExtendedVlanBlockSize; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_ctpport_egress.val[1] |= (1 << 14); /*Set First Index of the Block*/ @@ -19171,17 +24081,15 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) tbl_prog_ctpport_egress.val[1] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_ctpport_egress.val[2] &= ~(0x3FF); - tbl_prog_ctpport_egress.val[2] |= ((LastIdx-1) & 0x3FF); + tbl_prog_ctpport_egress.val[2] |= ((LastIdx - 1) & 0x3FF); - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this CTP port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) { + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId - =param->nEgressExtendedVlanBlockId; + = param->nEgressExtendedVlanBlockId; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -19189,62 +24097,81 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) } else { /*Disable egress Extended VLAN non igmp*/ tbl_prog_ctpport_egress.val[1] &= ~(1 << 14); + + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) { + idx = gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; + } } - } + } - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP) - { - if(param->bEgressExtendedVlanIgmpEnable) - { - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this vlan block is + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP) { + if (param->bEgressExtendedVlanIgmpEnable) { + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this vlan block is already assigned and it's Blk id recorded for this CTP Port id. If next time the user update this Vlan blk field with different blk id !! or wanted to allocate a new vlan blk ??!! may happen by mistake ??!! the previous blk id must be released from this CTP Port*/ - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId != - param->nEgressExtendedVlanBlockIdIgmp) - { - idx=gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId; + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId != + param->nEgressExtendedVlanBlockIdIgmp) { + idx = gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId; /*release the usage of previous vlan block id*/ gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; } } } /*Note: First Index of the Block is the BlockID*/ - FirstIdx=param->nEgressExtendedVlanBlockIdIgmp; - if(FirstIdx > gswdev->num_of_extendvlan) - return GSW_statusErr; - + FirstIdx = param->nEgressExtendedVlanBlockIdIgmp; + + if (FirstIdx > gswdev->num_of_extendvlan) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index is InUse Since it will be marked as InUse during allocation. */ - if(!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) - return GSW_statusErr; + if (!gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Check whether this index belongs to this BlockID Since it will be marked during allocation. */ - if(gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId - != param->nEgressExtendedVlanBlockIdIgmp) - return GSW_statusErr; + if (gswdev->extendvlan_idx.vlan_idx[FirstIdx].VlanBlockId + != param->nEgressExtendedVlanBlockIdIgmp) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*Search for the Last Index of this block. Note: The Blocks are always allocated contiguously. */ - - LastIdx=FirstIdx; - while(gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx - && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { + + LastIdx = FirstIdx; + + while (gswdev->extendvlan_idx.vlan_idx[LastIdx].VlanBlockId == FirstIdx + && gswdev->extendvlan_idx.vlan_idx[LastIdx].IndexInUse) { LastIdx++; - } - + } + + BlkSize = param->nEgressExtendedVlanBlockSizeIgmp; + + if (BlkSize && ((FirstIdx + BlkSize) <= LastIdx)) + LastIdx = (FirstIdx + BlkSize); + /*Enable Extended VLAN operation*/ tbl_prog_ctpport_egress.val[5] |= (1 << 14); /*Set First Index of the Block*/ @@ -19252,17 +24179,15 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) tbl_prog_ctpport_egress.val[5] |= (FirstIdx & 0x3FF); /*Set Last Index of the Block*/ tbl_prog_ctpport_egress.val[6] &= ~(0x3FF); - tbl_prog_ctpport_egress.val[6] |= ((LastIdx-1) & 0x3FF); + tbl_prog_ctpport_egress.val[6] |= ((LastIdx - 1) & 0x3FF); - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Usage count will be incremented only once during vlan blk assignment + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Usage count will be incremented only once during vlan blk assignment for this CTP port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) { + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId - =param->nEgressExtendedVlanBlockIdIgmp; + = param->nEgressExtendedVlanBlockIdIgmp; /*Since this vlan blk can be shared,Increment it's usage count*/ gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt++; } @@ -19270,71 +24195,78 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) } else { /*Disable ingress Extended VLAN igmp*/ tbl_prog_ctpport_egress.val[5] &= ~(1 << 14); + + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) { + idx = gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId; + /*release the usage of vlan block id, if it is assigned previously + when Extended vlan operation is disabled,it is must to release + the mapped exvlan resource*/ + gswdev->extendvlan_idx.vlan_idx[idx].IndexInUsageCnt--; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; + } } - } + } - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN) - { - if(param->bIngressNto1VlanEnable) + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN) { + if (param->bIngressNto1VlanEnable) tbl_prog_ctpport_ingress.val[1] |= (1 << 15); else tbl_prog_ctpport_ingress.val[1] &= ~(1 << 15); } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN) - { - if(param->bEgressNto1VlanEnable) + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN) { + if (param->bEgressNto1VlanEnable) tbl_prog_ctpport_egress.val[1] |= (1 << 15); else tbl_prog_ctpport_egress.val[1] &= ~(1 << 15); } - if(param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_METER) - { - if (param->bIngressMeteringEnable) - { - if(param->nIngressTrafficMeterId > gswdev->num_of_meters) - return GSW_statusErr; - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + if (param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_METER) { + if (param->bIngressMeteringEnable) { + if (param->nIngressTrafficMeterId > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this CTP port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this CTP Port*/ - - if(gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId != - param->nIngressTrafficMeterId) - { - idx=gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId; + + if (gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId != + param->nIngressTrafficMeterId) { + idx = gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId=0; + gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling bridge port configuration + before calling bridge port configuration If not in use return ERROR */ - if(gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUse) { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this ctp port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) { + gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId - =param->nIngressTrafficMeterId; + = param->nIngressTrafficMeterId; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUsageCnt++; } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Enable Meter Id*/ tbl_prog_ctpport_ingress.val[3] |= (1 << 7); tbl_prog_ctpport_ingress.val[3] &= ~(0x7F << 8); @@ -19343,55 +24275,53 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) /*Disable Ingress Meter*/ tbl_prog_ctpport_ingress.val[3] &= ~(1 << 7); } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_METER) - { - if (param->bEgressMeteringEnable) - { - if(param->nEgressTrafficMeterId > gswdev->num_of_meters) - return GSW_statusErr; - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*This below field enable indicates that this meter id is + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_METER) { + if (param->bEgressMeteringEnable) { + if (param->nEgressTrafficMeterId > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*This below field enable indicates that this meter id is already assigned and it's idx recorded for this CTP Port id. If next time the user update this meter field with different meter idx !! or wanted to allocate a new meter idx ??!! may happen by mistake ??!! the previous meter idx must be released from this CTP Port*/ - if(gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId != - param->nIngressTrafficMeterId) - { - idx=gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId; + if (gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId != + param->nIngressTrafficMeterId) { + idx = gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId; /*release the usage of previous meter idx*/ gswdev->meter_idx[idx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId=0; + gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId = 0; } } /*This Meter ID should be in use (i.e) that is this Meter ID should be allocated - before calling ctp port configuration + before calling ctp port configuration If not in use return ERROR */ - if(gswdev->meter_idx[param->nEgressTrafficMeterId].IndexInUse) - { - /*Usage count will be incremented only once during meter idx assignment + if (gswdev->meter_idx[param->nEgressTrafficMeterId].IndexInUse) { + /*Usage count will be incremented only once during meter idx assignment for this bridge port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned=1; + if (!gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) { + gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned = 1; gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId - =param->nEgressTrafficMeterId; + = param->nEgressTrafficMeterId; /*Since this meter id can be shared,Increment the it's usage count*/ gswdev->meter_idx[param->nEgressTrafficMeterId].IndexInUsageCnt++; } } else { - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + /*Enable Meter Id*/ tbl_prog_ctpport_egress.val[3] |= (1 << 7); tbl_prog_ctpport_egress.val[3] &= ~(0x7F << 8); @@ -19400,42 +24330,39 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) /*Disable Egress Meter*/ tbl_prog_ctpport_egress.val[3] &= ~(1 << 7); } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS) - { - if(param->bBridgingBypass) - { - /** By pass bridging/multicast processing. Following parameters are used - to determine destination. Traffic flow table is not bypassed. */ + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS) { + if (param->bBridgingBypass) { + /** By pass bridging/multicast processing. Following parameters are used + to determine destination. Traffic flow table is not bypassed. */ /*Enable Bridge Bypass*/ tbl_prog_ctpport_ingress.val[4] |= (1 << 15); /** This field defines destination logical port. */ - tbl_prog_ctpport_ingress.val[4] &= ~(0xF << 8); + tbl_prog_ctpport_ingress.val[4] &= ~(0xF << 8); tbl_prog_ctpport_ingress.val[4] |= ((param->nDestLogicalPortId & 0xF) << 8); - - if(param->bPmapperEnable) - { + + if (param->bPmapperEnable) { /*TODO : as per code review - user is not responsible to allocate p-mapper*/ - if(gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) - param->sPmapper.nPmapperId=gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx; + if (gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) + param->sPmapper.nPmapperId = gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx; else - param->sPmapper.nPmapperId=PMAPPER_ENTRY_INVALID; + param->sPmapper.nPmapperId = PMAPPER_ENTRY_INVALID; - - /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to - derive sub interface ID. */ + + /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to + derive sub interface ID. */ /*PCP-P-mapper table entry 1-8*/ /*DSCP-P-mapper table entry 9-72. */ - switch(param->ePmapperMappingMode) - { - case GSW_PMAPPER_MAPPING_PCP: - tbl_prog_ctpport_ingress.val[4] &= ~(1 << 13); - break; - case GSW_PMAPPER_MAPPING_DSCP: - tbl_prog_ctpport_ingress.val[4] |=(1 << 13); - break; + switch (param->ePmapperMappingMode) { + case GSW_PMAPPER_MAPPING_PCP: + tbl_prog_ctpport_ingress.val[4] &= ~(1 << 13); + break; + + case GSW_PMAPPER_MAPPING_DSCP: + tbl_prog_ctpport_ingress.val[4] |= (1 << 13); + break; } /* If the p-mapper id is invalid then the GSW_QOS_PmapperTableSet will @@ -19443,21 +24370,23 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) If p-mapper index is valid the GSW_QOS_PmapperTableSet will just program the table */ - ret=GSW_QOS_PmapperTableSet(cdev,¶m->sPmapper); - if(ret == GSW_statusErr) { + ret = GSW_QOS_PmapperTableSet(cdev, ¶m->sPmapper); + + if (ret == GSW_statusErr) { pr_err("ERROR : GSW_QOS_PmapperTableSet return erro\n"); - return GSW_statusErr; + goto UNLOCK_AND_RETURN; } - pmapper_idx=param->sPmapper.nPmapperId; + + pmapper_idx = param->sPmapper.nPmapperId; + /*Usage count will be incremented only once during p-mapper idx allocation or assignment for this ctp port id*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) - { - gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned=1; - gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx=pmapper_idx; + if (!gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) { + gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned = 1; + gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx = pmapper_idx; } - tbl_prog_ctpport_ingress.val[4] |=(1 << 14); + tbl_prog_ctpport_ingress.val[4] |= (1 << 14); tbl_prog_ctpport_ingress.val[4] &= ~(0xFF); tbl_prog_ctpport_ingress.val[4] |= (pmapper_idx & 0xFF); } else { @@ -19473,511 +24402,622 @@ GSW_return_t GSW_CtpPortConfigSet(void *cdev, GSW_CTP_portConfig_t *param) tbl_prog_ctpport_ingress.val[4] &= ~(1 << 15); } } - - if(param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_MARKING) - { - tbl_prog_ctpport_ingress.val[3] &= ~(7); - switch(param->eIngressMarkingMode) { - case GSW_MARKING_ALL_GREEN: - break; - case GSW_MARKING_INTERNAL_MARKING: - tbl_prog_ctpport_ingress.val[3] |= 0x1; - break; - case GSW_MARKING_DEI: - tbl_prog_ctpport_ingress.val[3] |= 0x2; - break; - case GSW_MARKING_PCP_8P0D: - tbl_prog_ctpport_ingress.val[3] |= 0x3; - break; - case GSW_MARKING_PCP_7P1D: - tbl_prog_ctpport_ingress.val[3] |= 0x4; - break; - case GSW_MARKING_PCP_6P2D: - tbl_prog_ctpport_ingress.val[3] |= 0x5; - break; - case GSW_MARKING_PCP_5P3D: - tbl_prog_ctpport_ingress.val[3] |= 0x6; - break; - case GSW_MARKING_DSCP_AF: - tbl_prog_ctpport_ingress.val[3] |= 0x7; - break; + + if (param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_MARKING) { + tbl_prog_ctpport_ingress.val[3] &= ~(7); + + switch (param->eIngressMarkingMode) { + case GSW_MARKING_ALL_GREEN: + break; + + case GSW_MARKING_INTERNAL_MARKING: + tbl_prog_ctpport_ingress.val[3] |= 0x1; + break; + + case GSW_MARKING_DEI: + tbl_prog_ctpport_ingress.val[3] |= 0x2; + break; + + case GSW_MARKING_PCP_8P0D: + tbl_prog_ctpport_ingress.val[3] |= 0x3; + break; + + case GSW_MARKING_PCP_7P1D: + tbl_prog_ctpport_ingress.val[3] |= 0x4; + break; + + case GSW_MARKING_PCP_6P2D: + tbl_prog_ctpport_ingress.val[3] |= 0x5; + break; + + case GSW_MARKING_PCP_5P3D: + tbl_prog_ctpport_ingress.val[3] |= 0x6; + break; + + case GSW_MARKING_DSCP_AF: + tbl_prog_ctpport_ingress.val[3] |= 0x7; + break; } } - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING) - { - tbl_prog_ctpport_ingress.val[3] &= ~(0x70); - switch(param->eEgressMarkingMode) { + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING) { + tbl_prog_ctpport_ingress.val[3] &= ~(0x70); + + switch (param->eEgressMarkingMode) { + case GSW_MARKING_ALL_GREEN: + break; + + case GSW_MARKING_INTERNAL_MARKING: + tbl_prog_ctpport_ingress.val[3] |= (0x1 << 4); + break; + + case GSW_MARKING_DEI: + tbl_prog_ctpport_ingress.val[3] |= (0x2 << 4); + break; + + case GSW_MARKING_PCP_8P0D: + tbl_prog_ctpport_ingress.val[3] |= (0x3 << 4); + break; + + case GSW_MARKING_PCP_7P1D: + tbl_prog_ctpport_ingress.val[3] |= (0x4 << 4); + break; + + case GSW_MARKING_PCP_6P2D: + tbl_prog_ctpport_ingress.val[3] |= (0x5 << 4); + break; + + case GSW_MARKING_PCP_5P3D: + tbl_prog_ctpport_ingress.val[3] |= (0x6 << 4); + break; + + case GSW_MARKING_DSCP_AF: + tbl_prog_ctpport_ingress.val[3] |= (0x7 << 4); + break; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_REMARKING) { + tbl_prog_ctpport_egress.val[3] &= ~(0x7); + + switch (param->eEgressRemarkingMode) { + case GSW_REMARKING_NONE: + break; + + case GSW_REMARKING_DEI: + tbl_prog_ctpport_egress.val[3] |= 0x2; + break; + + case GSW_REMARKING_PCP_8P0D: + tbl_prog_ctpport_egress.val[3] |= 0x3; + break; + + case GSW_REMARKING_PCP_7P1D: + tbl_prog_ctpport_egress.val[3] |= 0x4; + break; + + case GSW_REMARKING_PCP_6P2D: + tbl_prog_ctpport_egress.val[3] |= 0x5; + break; + + case GSW_REMARKING_PCP_5P3D: + tbl_prog_ctpport_egress.val[3] |= 0x6; + break; + + case GSW_REMARKING_DSCP_AF: + tbl_prog_ctpport_egress.val[3] |= 0x7; + break; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE) { + if (param->bEgressMarkingOverrideEnable) { + /*Enable OverRide*/ + tbl_prog_ctpport_egress.val[3] |= (1 << 3); + tbl_prog_ctpport_egress.val[3] &= ~(0x70); + + switch (param->eEgressMarkingModeOverride) { case GSW_MARKING_ALL_GREEN: break; + case GSW_MARKING_INTERNAL_MARKING: - tbl_prog_ctpport_ingress.val[3] |= (0x1 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x1 << 4); break; + case GSW_MARKING_DEI: - tbl_prog_ctpport_ingress.val[3] |= (0x2 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x2 << 4); break; + case GSW_MARKING_PCP_8P0D: - tbl_prog_ctpport_ingress.val[3] |= (0x3 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x3 << 4); break; + case GSW_MARKING_PCP_7P1D: - tbl_prog_ctpport_ingress.val[3] |= (0x4 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x4 << 4); break; + case GSW_MARKING_PCP_6P2D: - tbl_prog_ctpport_ingress.val[3] |= (0x5 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x5 << 4); break; + case GSW_MARKING_PCP_5P3D: - tbl_prog_ctpport_ingress.val[3] |= (0x6 << 4); + tbl_prog_ctpport_egress.val[3] |= (0x6 << 4); break; + case GSW_MARKING_DSCP_AF: - tbl_prog_ctpport_ingress.val[3] |=(0x7 << 4); - break; - } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_REMARKING) - { - tbl_prog_ctpport_egress.val[3] &= ~(0x7); - switch(param->eEgressRemarkingMode) { - case GSW_REMARKING_NONE: - break; - case GSW_REMARKING_DEI: - tbl_prog_ctpport_egress.val[3] |= 0x2; - break; - case GSW_REMARKING_PCP_8P0D: - tbl_prog_ctpport_egress.val[3] |= 0x3; - break; - case GSW_REMARKING_PCP_7P1D: - tbl_prog_ctpport_egress.val[3] |= 0x4; - break; - case GSW_REMARKING_PCP_6P2D: - tbl_prog_ctpport_egress.val[3] |= 0x5; + tbl_prog_ctpport_egress.val[3] |= (0x7 << 4); break; - case GSW_REMARKING_PCP_5P3D: - tbl_prog_ctpport_egress.val[3] |= 0x6; - break; - case GSW_REMARKING_DSCP_AF: - tbl_prog_ctpport_egress.val[3] |= 0x7; - break; - } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE) - { - if(param->bEgressMarkingOverrideEnable) - { - /*Enable OverRide*/ - tbl_prog_ctpport_egress.val[3] |= (1 << 3); - tbl_prog_ctpport_egress.val[3] &= ~(0x70); - switch(param->eEgressMarkingModeOverride) { - case GSW_MARKING_ALL_GREEN: - break; - case GSW_MARKING_INTERNAL_MARKING: - tbl_prog_ctpport_egress.val[3] |= (0x1 << 4); - break; - case GSW_MARKING_DEI: - tbl_prog_ctpport_egress.val[3] |= (0x2 << 4); - break; - case GSW_MARKING_PCP_8P0D: - tbl_prog_ctpport_egress.val[3] |= (0x3 << 4); - break; - case GSW_MARKING_PCP_7P1D: - tbl_prog_ctpport_egress.val[3] |= (0x4 << 4); - break; - case GSW_MARKING_PCP_6P2D: - tbl_prog_ctpport_egress.val[3] |= (0x5 << 4); - break; - case GSW_MARKING_PCP_5P3D: - tbl_prog_ctpport_egress.val[3] |= (0x6 << 4); - break; - case GSW_MARKING_DSCP_AF: - tbl_prog_ctpport_egress.val[3] |=(0x7 << 4); - break; } } else { /*Disable OverRide*/ tbl_prog_ctpport_egress.val[3] &= ~(1 << 3); } } - - if(param->eMask & GSW_CTP_PORT_CONFIG_FLOW_ENTRY) - { + + if (param->eMask & GSW_CTP_PORT_CONFIG_FLOW_ENTRY) { tbl_prog_ctpport_ingress.val[7] &= ~(0x7F << 2); tbl_prog_ctpport_ingress.val[7] |= (param->nFirstFlowEntryIndex & 0x1FC); tbl_prog_ctpport_ingress.val[8] &= ~(0xFF << 2); tbl_prog_ctpport_ingress.val[8] |= (param->nNumberOfFlowEntries & 0x3FC); } - - if(param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) - { - if(param->bIngressLoopbackEnable) + + if (param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) { + if (param->bIngressLoopbackEnable) tbl_prog_ctpport_ingress.val[2] |= (1 << 14); else tbl_prog_ctpport_ingress.val[2] &= ~(1 << 14); - - if(param->bEgressLoopbackEnable) - tbl_prog_ctpport_egress.val[4] |= (1 << 12); + + if (param->bEgressLoopbackEnable) + tbl_prog_ctpport_egress.val[4] |= (1 << 12); else tbl_prog_ctpport_egress.val[4] &= ~(1 << 12); - if(param->bIngressMirrorEnable) + if (param->bIngressMirrorEnable) tbl_prog_ctpport_ingress.val[5] |= (1 << 15); else tbl_prog_ctpport_ingress.val[5] &= ~(1 << 15); - if(param->bEgressMirrorEnable) + if (param->bEgressMirrorEnable) tbl_prog_ctpport_egress.val[5] |= (1 << 15); else tbl_prog_ctpport_egress.val[5] &= ~(1 << 15); } - if(param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) - { - if(param->bIngressDaSaSwapEnable) + if (param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) { + if (param->bIngressDaSaSwapEnable) tbl_prog_ctpport_ingress.val[4] |= (1 << 12); else tbl_prog_ctpport_ingress.val[4] &= ~(1 << 12); - if(param->bEgressDaSaSwapEnable) + if (param->bEgressDaSaSwapEnable) tbl_prog_ctpport_egress.val[4] |= (1 << 13); else tbl_prog_ctpport_egress.val[4] &= ~(1 << 13); } - - /*Same ctp port idx for ingress and egress ctp port configuration*/ + + /*Same ctp port idx for ingress and egress ctp port configuration*/ + tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; + CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); + /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ + tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); + + tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; + CLEAR_U16(tbl_prog_ctpport_egress.pcindex); + /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ + tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); + + + /*Address-based write for ingress ctp port configuration*/ + gsw_pce_table_write(cdev, &tbl_prog_ctpport_ingress); + /*Address-based write for egress ctp port configuration*/ + gsw_pce_table_write(cdev, &tbl_prog_ctpport_egress); + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; +} + +GSW_return_t GSW_CtpPortConfigGet(void *cdev, GSW_CTP_portConfig_t *param) +{ + pctbl_prog_t tbl_prog_ctpport_ingress; + pctbl_prog_t tbl_prog_ctpport_egress; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ctp_port, FirstIdx, LastIdx, BlkSize; + u16 ret, value; + GSW_CTP_portAssignment_t ctp_get; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + + /*check based on number of logical port*/ + if (param->nLogicalPortId > gswdev->tpnum) { + pr_err("param->nLogicalPortId > gswdev->pnum\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*CTP ports has to assigned/mapped to Logical port before calling + CTP port configuration. + GSW_CTP_PortAssignmentGet will get the info on the assignment + Use this info to find whether this CTP port is with in the range + this logical port + */ + ctp_get.nLogicalPortId = param->nLogicalPortId; + ret = GSW_CTP_PortAssignmentGet(cdev, &ctp_get); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; + + /*IMPORTANT NOTE : :As per the CTP concept nFirstCtpPortId + nSubIfIdGroup is the expected CTP port*/ + ctp_port = ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; + + if (ctp_port > gswdev->num_of_ctp) { + pr_err("ctp_port %d > gswdev->num_of_ctp\n", ctp_port); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If not with in the Assigned range Return Error*/ + if (ctp_port < ctp_get.nFirstCtpPortId || + ctp_port >= (ctp_get.nFirstCtpPortId + ctp_get.nNumberOfCtpPort)) { + pr_err("ERROR :CTP port not with in Allocated range\n"); + pr_err("Check CTP assignment Get\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*NOTE : This Mask is for debugging purpose only + If GSW_CTP_PORT_CONFIG_MASK_FORCE mask is set + It will not check index in-use */ + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ + if (!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) { + pr_err("ctp_port %d Index not in use,CTP not allocated\n", ctp_port); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + } + + /*Same ctp port idx for ingress and egress ctp port configuration*/ + memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); + CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); + memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_egress.pcindex); + CLEAR_U16(tbl_prog_ctpport_egress.pcindex); /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); + /*Address-based read for ingress ctp port configuration*/ + gsw_pce_table_read(cdev, &tbl_prog_ctpport_ingress); + + /*Address-based read for egress ctp port configuration*/ + gsw_pce_table_read(cdev, &tbl_prog_ctpport_egress); + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID) { + param->nBridgePortId = (tbl_prog_ctpport_ingress.val[0] & 0xFF); + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS) { + /** Default traffic class associated with all traffic from this CTP Port. */ + param->nDefaultTrafficClass = ((tbl_prog_ctpport_ingress.val[0] & 0xF00) >> 8); + /* 0 -Traffic class can be over written by the following processing stage + 1 -Traffic class can not be over written by the following processing stage + */ + param->bForcedTrafficClass = ((tbl_prog_ctpport_ingress.val[0] & 0x1000) >> 12); + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN) { + param->bIngressExtendedVlanEnable = ((tbl_prog_ctpport_ingress.val[1] & 0x4000) >> 14); + + if (param->bIngressExtendedVlanEnable) { + param->nIngressExtendedVlanBlockId = (tbl_prog_ctpport_ingress.val[1] & 0x3FF); + FirstIdx = param->nIngressExtendedVlanBlockId; + LastIdx = (tbl_prog_ctpport_ingress.val[2] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nIngressExtendedVlanBlockSize = BlkSize; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP) { + param->bIngressExtendedVlanIgmpEnable = ((tbl_prog_ctpport_ingress.val[5] & 0x4000) >> 14); + + if (param->bIngressExtendedVlanIgmpEnable) { + param->nIngressExtendedVlanBlockIdIgmp = (tbl_prog_ctpport_ingress.val[5] & 0x3FF); + FirstIdx = param->nIngressExtendedVlanBlockIdIgmp; + LastIdx = (tbl_prog_ctpport_ingress.val[6] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nIngressExtendedVlanBlockSizeIgmp = BlkSize; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN) { + param->bEgressExtendedVlanEnable = ((tbl_prog_ctpport_egress.val[1] & 0x4000) >> 14); + + if (param->bEgressExtendedVlanEnable) { + param->nEgressExtendedVlanBlockId = (tbl_prog_ctpport_egress.val[1] & 0x3FF); + FirstIdx = param->nEgressExtendedVlanBlockId; + LastIdx = (tbl_prog_ctpport_egress.val[2] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nEgressExtendedVlanBlockSize = BlkSize; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP) { + param->bEgressExtendedVlanIgmpEnable = ((tbl_prog_ctpport_egress.val[5] & 0x4000) >> 14); + + if (param->bEgressExtendedVlanIgmpEnable) { + param->nEgressExtendedVlanBlockIdIgmp = (tbl_prog_ctpport_egress.val[5] & 0x3FF); + FirstIdx = param->nEgressExtendedVlanBlockIdIgmp; + LastIdx = (tbl_prog_ctpport_egress.val[6] & 0x3FF); + + if (FirstIdx == LastIdx) + BlkSize = 1; + else + BlkSize = ((LastIdx - FirstIdx) + 1); + + param->nEgressExtendedVlanBlockSizeIgmp = BlkSize; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN) + param->bIngressNto1VlanEnable = ((tbl_prog_ctpport_ingress.val[1] & 0x8000) >> 15); + + if (param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN) + param->bEgressNto1VlanEnable = ((tbl_prog_ctpport_egress.val[1] & 0x8000) >> 15); + + if (param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_METER) { + param->bIngressMeteringEnable = ((tbl_prog_ctpport_ingress.val[3] & 0x80) >> 7); + + if (param->bIngressMeteringEnable) + param->nIngressTrafficMeterId = ((tbl_prog_ctpport_ingress.val[3] & 0x7F00) >> 8); + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_METER) { + param->bEgressMeteringEnable = ((tbl_prog_ctpport_egress.val[3] & 0x80) >> 7); + + if (param->bEgressMeteringEnable) + param->nEgressTrafficMeterId = ((tbl_prog_ctpport_egress.val[3] & 0x7F00) >> 8); + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS) { + param->bBridgingBypass = ((tbl_prog_ctpport_ingress.val[4] & 0x8000) >> 15); + + if (param->bBridgingBypass) { + param->nDestLogicalPortId = ((tbl_prog_ctpport_ingress.val[4] & 0xF00) >> 8); + param->bPmapperEnable = ((tbl_prog_ctpport_ingress.val[4] & 0x4000) >> 14); + + if (param->bPmapperEnable) { + param->sPmapper.nPmapperId = (tbl_prog_ctpport_ingress.val[4] & 0xFF); + ret = GSW_QOS_PmapperTableGet(cdev, ¶m->sPmapper); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; + + value = ((tbl_prog_ctpport_ingress.val[4] & 0x2000) >> 13); + + switch (value) { + case 0: + param->ePmapperMappingMode = GSW_PMAPPER_MAPPING_PCP; + break; + + case 1: + param->ePmapperMappingMode = GSW_PMAPPER_MAPPING_DSCP; + break; + } + } else { + param->nDestSubIfIdGroup = (tbl_prog_ctpport_ingress.val[4] & 0xFF); + } + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_MARKING) { + value = (tbl_prog_ctpport_ingress.val[3] & 0x7); + + switch (value) { + case 0: + param->eIngressMarkingMode = GSW_MARKING_ALL_GREEN; + break; + + case 1: + param->eIngressMarkingMode = GSW_MARKING_INTERNAL_MARKING; + break; + + case 2: + param->eIngressMarkingMode = GSW_MARKING_DEI; + break; + + case 3: + param->eIngressMarkingMode = GSW_MARKING_PCP_8P0D; + break; + + case 4: + param->eIngressMarkingMode = GSW_MARKING_PCP_7P1D; + break; + + case 5: + param->eIngressMarkingMode = GSW_MARKING_PCP_6P2D; + break; + + case 6: + param->eIngressMarkingMode = GSW_MARKING_PCP_5P3D; + break; + + case 7: + param->eIngressMarkingMode = GSW_MARKING_DSCP_AF; + break; + } + } + + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING) { + value = ((tbl_prog_ctpport_ingress.val[3] & 0x70) >> 4); + + switch (value) { + case 0: + param->eEgressMarkingMode = GSW_MARKING_ALL_GREEN; + break; + + case 1: + param->eEgressMarkingMode = GSW_MARKING_INTERNAL_MARKING; + break; + + case 2: + param->eEgressMarkingMode = GSW_MARKING_DEI; + break; - /*Address-based write for ingress ctp port configuration*/ - gsw_pce_table_write(cdev, &tbl_prog_ctpport_ingress); - /*Address-based write for egress ctp port configuration*/ - gsw_pce_table_write(cdev, &tbl_prog_ctpport_egress); - - return GSW_statusOk; -} + case 3: + param->eEgressMarkingMode = GSW_MARKING_PCP_8P0D; + break; -GSW_return_t GSW_CtpPortConfigGet(void *cdev, GSW_CTP_portConfig_t *param) -{ - pctbl_prog_t tbl_prog_ctpport_ingress; - pctbl_prog_t tbl_prog_ctpport_egress; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 ctp_port; - u16 ret,value; - GSW_CTP_portAssignment_t ctp_get; + case 4: + param->eEgressMarkingMode = GSW_MARKING_PCP_7P1D; + break; - if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } + case 5: + param->eEgressMarkingMode = GSW_MARKING_PCP_6P2D; + break; - /*check based on number of logical port*/ - if (param->nLogicalPortId > gswdev->tpnum) { - pr_err("param->nLogicalPortId > gswdev->pnum\n"); - return GSW_statusErr; - } - - /*CTP ports has to assigned/mapped to Logical port before calling - CTP port configuration. - GSW_CTP_PortAssignmentGet will get the info on the assignment - Use this info to find whether this CTP port is with in the range - this logical port - */ - ctp_get.nLogicalPortId=param->nLogicalPortId; - ret=GSW_CTP_PortAssignmentGet(cdev,&ctp_get); - if(ret==GSW_statusErr) - return GSW_statusErr; - - /*IMPORTANT NOTE : :As per the CTP concept nFirstCtpPortId + nSubIfIdGroup is the expected CTP port*/ - ctp_port=ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; - if (ctp_port > gswdev->num_of_ctp) { - pr_err("ctp_port %d > gswdev->num_of_ctp\n",ctp_port); - return GSW_statusErr; - } + case 6: + param->eEgressMarkingMode = GSW_MARKING_PCP_5P3D; + break; - /*If not with in the Assigned range Return Error*/ - if(ctp_port < ctp_get.nFirstCtpPortId || - ctp_port >=(ctp_get.nFirstCtpPortId +ctp_get.nNumberOfCtpPort)) { - pr_err("ERROR :CTP port not with in Allocated range\n"); - pr_err("Check CTP assignment Get\n"); - return GSW_statusErr; - } - - /*NOTE : This Mask is for debugging purpose only - If GSW_CTP_PORT_CONFIG_MASK_FORCE mask is set - It will not check index in-use */ - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) { - pr_err("ctp_port %d Index not in use,CTP not allocated\n",ctp_port); - return GSW_statusErr; - } + case 7: + param->eEgressMarkingMode = GSW_MARKING_DSCP_AF; + break; + } } - /*Same ctp port idx for ingress and egress ctp port configuration*/ - memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); - tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); - /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ - tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_REMARKING) { + value = (tbl_prog_ctpport_egress.val[3] & 0x7); - memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); - tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_egress.pcindex); - /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ - tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); + switch (value) { + case 0: + case 1: + param->eEgressRemarkingMode = GSW_REMARKING_NONE; + break; - /*Address-based read for ingress ctp port configuration*/ - gsw_pce_table_read(cdev, &tbl_prog_ctpport_ingress); + case 2: + param->eEgressRemarkingMode = GSW_REMARKING_DEI; + break; - /*Address-based read for egress ctp port configuration*/ - gsw_pce_table_read(cdev, &tbl_prog_ctpport_egress); - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID) { - param->nBridgePortId = (tbl_prog_ctpport_ingress.val[0] & 0xFF); - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS) - { - /** Default traffic class associated with all traffic from this CTP Port. */ - param->nDefaultTrafficClass = ((tbl_prog_ctpport_ingress.val[0] & 0xF00) >> 8); - /* 0 -Traffic class can be over written by the following processing stage - 1 -Traffic class can not be over written by the following processing stage - */ - param->bForcedTrafficClass = ((tbl_prog_ctpport_ingress.val[0] & 0x1000) >> 12); - } + case 3: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_8P0D; + break; - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN) - { - param->bIngressExtendedVlanEnable=((tbl_prog_ctpport_ingress.val[1] & 0x4000) >> 14); - if(param->bIngressExtendedVlanEnable) - param->nIngressExtendedVlanBlockId=(tbl_prog_ctpport_ingress.val[1] & 0x3FF); - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP) - { - param->bIngressExtendedVlanIgmpEnable=((tbl_prog_ctpport_ingress.val[5] & 0x4000) >> 14); - if(param->bIngressExtendedVlanIgmpEnable) - param->nIngressExtendedVlanBlockIdIgmp=(tbl_prog_ctpport_ingress.val[5] & 0x3FF); - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN) - { - param->bEgressExtendedVlanEnable=((tbl_prog_ctpport_egress.val[1] & 0x4000) >> 14); - if(param->bEgressExtendedVlanEnable) - param->nEgressExtendedVlanBlockId=(tbl_prog_ctpport_egress.val[1] & 0x3FF); - } + case 4: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_7P1D; + break; - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP) - { - param->bEgressExtendedVlanIgmpEnable=((tbl_prog_ctpport_egress.val[5] & 0x4000) >> 14); - if(param->bEgressExtendedVlanIgmpEnable) - param->nEgressExtendedVlanBlockIdIgmp=(tbl_prog_ctpport_egress.val[5] & 0x3FF); - } + case 5: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_6P2D; + break; - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN) - param->bIngressNto1VlanEnable=((tbl_prog_ctpport_ingress.val[1] & 0x8000) >> 15); - - if(param->eMask & GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN) - param->bEgressNto1VlanEnable=((tbl_prog_ctpport_egress.val[1] & 0x8000) >> 15); + case 6: + param->eEgressRemarkingMode = GSW_REMARKING_PCP_5P3D; + break; - if(param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_METER) - { - param->bIngressMeteringEnable=((tbl_prog_ctpport_ingress.val[3] & 0x80) >> 7); - if(param->bIngressMeteringEnable) - param->nIngressTrafficMeterId=((tbl_prog_ctpport_ingress.val[3] & 0x7F00) >> 8); - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_METER) - { - param->bEgressMeteringEnable=((tbl_prog_ctpport_egress.val[3] & 0x80) >> 7); - if(param->bEgressMeteringEnable) - param->nEgressTrafficMeterId=((tbl_prog_ctpport_egress.val[3] & 0x7F00) >> 8); - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS) - { - param->bBridgingBypass=((tbl_prog_ctpport_ingress.val[4] & 0x8000) >> 15); - if(param->bBridgingBypass) - { - param->nDestLogicalPortId=((tbl_prog_ctpport_ingress.val[4] & 0xF00) >> 8); - param->bPmapperEnable=((tbl_prog_ctpport_ingress.val[4] & 0x4000) >> 14); - if(param->bPmapperEnable) - { - param->sPmapper.nPmapperId=(tbl_prog_ctpport_ingress.val[4] & 0xFF); - ret=GSW_QOS_PmapperTableGet(cdev,¶m->sPmapper); - if(ret == GSW_statusErr) - return GSW_statusErr; - - value=((tbl_prog_ctpport_ingress.val[4] & 0x2000) >> 13); - switch(value) - { - case 0: - param->ePmapperMappingMode=GSW_PMAPPER_MAPPING_PCP; - break; - case 1: - param->ePmapperMappingMode=GSW_PMAPPER_MAPPING_DSCP; - break; - } - } else { - param->nDestSubIfIdGroup=(tbl_prog_ctpport_ingress.val[4] & 0xFF); - } - } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_INGRESS_MARKING) - { - value=(tbl_prog_ctpport_ingress.val[3] & 0x7); - switch(value) { - case 0: - param->eIngressMarkingMode= GSW_MARKING_ALL_GREEN; - break; - case 1: - param->eIngressMarkingMode= GSW_MARKING_INTERNAL_MARKING; - break; - case 2: - param->eIngressMarkingMode=GSW_MARKING_DEI; - break; - case 3: - param->eIngressMarkingMode= GSW_MARKING_PCP_8P0D; - break; - case 4: - param->eIngressMarkingMode= GSW_MARKING_PCP_7P1D; - break; - case 5: - param->eIngressMarkingMode= GSW_MARKING_PCP_6P2D; - break; - case 6: - param->eIngressMarkingMode= GSW_MARKING_PCP_5P3D; - break; - case 7: - param->eIngressMarkingMode= GSW_MARKING_DSCP_AF; - break; + case 7: + param->eEgressRemarkingMode = GSW_REMARKING_DSCP_AF; + break; } } - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING) - { - value=((tbl_prog_ctpport_ingress.val[3] & 0x70) >> 4); - switch(value) { + if (param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE) { + param->bEgressMarkingOverrideEnable = ((tbl_prog_ctpport_egress.val[3] & 0x8) >> 3); + + if (param->bEgressMarkingOverrideEnable) { + value = ((tbl_prog_ctpport_egress.val[3] & 0x70) >> 4); + + switch (value) { case 0: - param->eEgressMarkingMode= GSW_MARKING_ALL_GREEN; - break; - case 1: - param->eEgressMarkingMode= GSW_MARKING_INTERNAL_MARKING; - break; - case 2: - param->eEgressMarkingMode=GSW_MARKING_DEI; - break; - case 3: - param->eEgressMarkingMode= GSW_MARKING_PCP_8P0D; - break; - case 4: - param->eEgressMarkingMode= GSW_MARKING_PCP_7P1D; - break; - case 5: - param->eEgressMarkingMode= GSW_MARKING_PCP_6P2D; - break; - case 6: - param->eEgressMarkingMode= GSW_MARKING_PCP_5P3D; - break; - case 7: - param->eEgressMarkingMode= GSW_MARKING_DSCP_AF; + param->eEgressMarkingModeOverride = GSW_MARKING_ALL_GREEN; break; - } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_REMARKING) - { - value=(tbl_prog_ctpport_egress.val[3] & 0x7); - switch(value) { - case 0: + case 1: - param->eEgressRemarkingMode= GSW_REMARKING_NONE; + param->eEgressMarkingModeOverride = GSW_MARKING_INTERNAL_MARKING; break; + case 2: - param->eEgressRemarkingMode= GSW_REMARKING_DEI; + param->eEgressMarkingModeOverride = GSW_MARKING_DEI; break; + case 3: - param->eEgressRemarkingMode = GSW_REMARKING_PCP_8P0D; + param->eEgressMarkingModeOverride = GSW_MARKING_PCP_8P0D; break; + case 4: - param->eEgressRemarkingMode= GSW_REMARKING_PCP_7P1D; + param->eEgressMarkingModeOverride = GSW_MARKING_PCP_7P1D; break; + case 5: - param->eEgressRemarkingMode= GSW_REMARKING_PCP_6P2D; + param->eEgressMarkingModeOverride = GSW_MARKING_PCP_6P2D; break; + case 6: - param->eEgressRemarkingMode= GSW_REMARKING_PCP_5P3D; + param->eEgressMarkingModeOverride = GSW_MARKING_PCP_5P3D; break; + case 7: - param->eEgressRemarkingMode= GSW_REMARKING_DSCP_AF; + param->eEgressMarkingModeOverride = GSW_MARKING_DSCP_AF; break; - } - } - - if(param->eMask & GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE) - { - param->bEgressMarkingOverrideEnable=((tbl_prog_ctpport_egress.val[3] & 0x8) >> 3); - if(param->bEgressMarkingOverrideEnable) - { - value=((tbl_prog_ctpport_egress.val[3] & 0x70) >> 4); - switch(value) { - case 0: - param->eEgressMarkingModeOverride= GSW_MARKING_ALL_GREEN; - break; - case 1: - param->eEgressMarkingModeOverride= GSW_MARKING_INTERNAL_MARKING; - break; - case 2: - param->eEgressMarkingModeOverride=GSW_MARKING_DEI; - break; - case 3: - param->eEgressMarkingModeOverride= GSW_MARKING_PCP_8P0D; - break; - case 4: - param->eEgressMarkingModeOverride= GSW_MARKING_PCP_7P1D; - break; - case 5: - param->eEgressMarkingModeOverride= GSW_MARKING_PCP_6P2D; - break; - case 6: - param->eEgressMarkingModeOverride= GSW_MARKING_PCP_5P3D; - break; - case 7: - param->eEgressMarkingModeOverride= GSW_MARKING_DSCP_AF; - break; } } } - - if(param->eMask & GSW_CTP_PORT_CONFIG_FLOW_ENTRY) - { - param->nFirstFlowEntryIndex=(tbl_prog_ctpport_ingress.val[7] & 0x1FC); - param->nNumberOfFlowEntries=(tbl_prog_ctpport_ingress.val[8] & 0x3FC); + + if (param->eMask & GSW_CTP_PORT_CONFIG_FLOW_ENTRY) { + param->nFirstFlowEntryIndex = (tbl_prog_ctpport_ingress.val[7] & 0x1FC); + param->nNumberOfFlowEntries = (tbl_prog_ctpport_ingress.val[8] & 0x3FC); } - - if(param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) - { - param->bIngressLoopbackEnable=((tbl_prog_ctpport_ingress.val[2] & 0x4000) >> 14); - param->bEgressLoopbackEnable=((tbl_prog_ctpport_egress.val[4] & 0x1000) >> 12); - param->bIngressMirrorEnable=((tbl_prog_ctpport_ingress.val[5] & 0x8000) >> 15); - param->bEgressMirrorEnable=((tbl_prog_ctpport_egress.val[5] & 0x8000) >> 15); + + if (param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) { + param->bIngressLoopbackEnable = ((tbl_prog_ctpport_ingress.val[2] & 0x4000) >> 14); + param->bEgressLoopbackEnable = ((tbl_prog_ctpport_egress.val[4] & 0x1000) >> 12); + param->bIngressMirrorEnable = ((tbl_prog_ctpport_ingress.val[5] & 0x8000) >> 15); + param->bEgressMirrorEnable = ((tbl_prog_ctpport_egress.val[5] & 0x8000) >> 15); } - if(param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) - { - param->bIngressDaSaSwapEnable=((tbl_prog_ctpport_ingress.val[4] & 0x1000) >> 12); - param->bEgressDaSaSwapEnable=((tbl_prog_ctpport_egress.val[4] & 0x2000) >> 13); + if (param->eMask & GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR) { + param->bIngressDaSaSwapEnable = ((tbl_prog_ctpport_ingress.val[4] & 0x1000) >> 12); + param->bEgressDaSaSwapEnable = ((tbl_prog_ctpport_egress.val[4] & 0x2000) >> 13); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_CtpPortConfigReset(void *cdev, GSW_CTP_portConfig_t *param) @@ -19985,76 +25025,87 @@ GSW_return_t GSW_CtpPortConfigReset(void *cdev, GSW_CTP_portConfig_t *param) pctbl_prog_t tbl_prog_ctpport_ingress; pctbl_prog_t tbl_prog_ctpport_egress; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u32 FirstIdx,ctp_port; + u32 FirstIdx, ctp_port; u16 ret; GSW_CTP_portAssignment_t ctp_get; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + /*check based on number of logical port*/ if (param->nLogicalPortId >= gswdev->tpnum) { - pr_err("param->nLogicalPortId > gswdev->pnum\n"); - return GSW_statusErr; - } - - /*CTP ports has to assigned/mapped to Logical port before calling + pr_err("param->nLogicalPortId > gswdev->pnum\n"); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*CTP ports has to assigned/mapped to Logical port before calling CTP port configuration. GSW_CTP_PortAssignmentGet will get the info on the assignment Use this info to find whether this CTP port is with in the range this logical port */ - ctp_get.nLogicalPortId=param->nLogicalPortId; - ret=GSW_CTP_PortAssignmentGet(cdev,&ctp_get); - if(ret==GSW_statusErr) - return GSW_statusErr; - + ctp_get.nLogicalPortId = param->nLogicalPortId; + ret = GSW_CTP_PortAssignmentGet(cdev, &ctp_get); + + if (ret == GSW_statusErr) + goto UNLOCK_AND_RETURN; + /*IMPORTANT NOTE : :As per the CTP concept nFirstCtpPortId + nSubIfIdGroup is the expected CTP port*/ - ctp_port=ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; + ctp_port = ctp_get.nFirstCtpPortId + param->nSubIfIdGroup; + if (ctp_port > gswdev->num_of_ctp) { - pr_err("ctp_port %d > gswdev->num_of_ctp\n",ctp_port); - return GSW_statusErr; - } + pr_err("ctp_port %d > gswdev->num_of_ctp\n", ctp_port); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - /*If not with in the Assigned range Return Error*/ - if(ctp_port < ctp_get.nFirstCtpPortId || - ctp_port >=(ctp_get.nFirstCtpPortId +ctp_get.nNumberOfCtpPort)) { + /*If not with in the Assigned range Return Error*/ + if (ctp_port < ctp_get.nFirstCtpPortId || + ctp_port >= (ctp_get.nFirstCtpPortId + ctp_get.nNumberOfCtpPort)) { pr_err("ERROR :CTP port not with in Allocated range\n"); pr_err("Check CTP assignment Get\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } /*This Mask is for DEBUGGING purpose only If GSW_CTP_PORT_CONFIG_MASK_FORCE mask is set It not check index to in-use*/ - if(!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) - { - /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ - if(!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) { - pr_err("ERROR :ctp_port %d Index not in use,CTP not allocated\n",ctp_port); - pr_err("ERROR :ctp_port %d Index can not be deleted",ctp_port); - return GSW_statusErr; - } + if (!(param->eMask & GSW_CTP_PORT_CONFIG_MASK_FORCE)) { + /*Check whether CTP is allocated by GSW_CTP_PortAssignmentAlloc*/ + if (!gswdev->ctpportconfig_idx[ctp_port].IndexInUse) { + pr_err("ERROR :ctp_port %d Index not in use,CTP not allocated\n", ctp_port); + pr_err("ERROR :ctp_port %d Index can not be deleted", ctp_port); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } } /*Some one is still using this CTP port -configuration can be deleted only if that some one releases this CTP port*/ - if(gswdev->ctpportconfig_idx[ctp_port].IndexInUsageCnt) - return GSW_statusErr; - - /*Same ctp port idx for ingress and egress ctp port configuration*/ + if (gswdev->ctpportconfig_idx[ctp_port].IndexInUsageCnt) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*Same ctp port idx for ingress and egress ctp port configuration*/ memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); + CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_egress.pcindex); + CLEAR_U16(tbl_prog_ctpport_egress.pcindex); /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); @@ -20065,155 +25116,155 @@ GSW_return_t GSW_CtpPortConfigReset(void *cdev, GSW_CTP_portConfig_t *param) gsw_pce_table_read(cdev, &tbl_prog_ctpport_egress); param->nBridgePortId = (tbl_prog_ctpport_ingress.val[0] & 0xFF); - if(gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].BrdgPortId == - param->nBridgePortId) - { + + if (gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].BrdgPortId == + param->nBridgePortId) { /*Release this Bridge port from this CTP Port*/ gswdev->brdgeportconfig_idx[param->nBridgePortId].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].BrdgPortId=0; + gswdev->ctpportconfig_idx[ctp_port].BrdgIdPortAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].BrdgPortId = 0; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - - param->nIngressExtendedVlanBlockId=(tbl_prog_ctpport_ingress.val[1] & 0x3FF); - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId == - param->nIngressExtendedVlanBlockId) - { + } + + param->nIngressExtendedVlanBlockId = (tbl_prog_ctpport_ingress.val[1] & 0x3FF); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId == + param->nIngressExtendedVlanBlockId) { /*Release this vlan blk from this CTP Port*/ - FirstIdx=param->nIngressExtendedVlanBlockId; + FirstIdx = param->nIngressExtendedVlanBlockId; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - - param->nIngressExtendedVlanBlockIdIgmp=(tbl_prog_ctpport_ingress.val[5] & 0x3FF); - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId == - param->nIngressExtendedVlanBlockIdIgmp) - { + } + + param->nIngressExtendedVlanBlockIdIgmp = (tbl_prog_ctpport_ingress.val[5] & 0x3FF); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId == + param->nIngressExtendedVlanBlockIdIgmp) { /*Release this vlan blk from this CTP Port*/ - FirstIdx=param->nIngressExtendedVlanBlockIdIgmp; + FirstIdx = param->nIngressExtendedVlanBlockIdIgmp; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } - param->nEgressExtendedVlanBlockId=(tbl_prog_ctpport_egress.val[1] & 0x3FF); - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId == - param->nEgressExtendedVlanBlockId) - { + param->nEgressExtendedVlanBlockId = (tbl_prog_ctpport_egress.val[1] & 0x3FF); + + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId == + param->nEgressExtendedVlanBlockId) { /*Release this vlan blk from this CTP Port*/ - FirstIdx=param->nEgressExtendedVlanBlockId; + FirstIdx = param->nEgressExtendedVlanBlockId; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanNonIgmpBlkId = EXVLAN_ENTRY_INVALID; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } - param->nEgressExtendedVlanBlockIdIgmp=(tbl_prog_ctpport_egress.val[5] & 0x3FF); - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId == - param->nEgressExtendedVlanBlockIdIgmp) - { + param->nEgressExtendedVlanBlockIdIgmp = (tbl_prog_ctpport_egress.val[5] & 0x3FF); + + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId == + param->nEgressExtendedVlanBlockIdIgmp) { /*Release this vlan blk from this CTP Port*/ - FirstIdx=param->nEgressExtendedVlanBlockIdIgmp; + FirstIdx = param->nEgressExtendedVlanBlockIdIgmp; gswdev->extendvlan_idx.vlan_idx[FirstIdx].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId=0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressExVlanIgmpBlkId = EXVLAN_ENTRY_INVALID; } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } + } - param->nIngressTrafficMeterId=((tbl_prog_ctpport_ingress.val[3] & 0x7F00) >> 8); - if(gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId == - param->nIngressTrafficMeterId) - { + param->nIngressTrafficMeterId = ((tbl_prog_ctpport_ingress.val[3] & 0x7F00) >> 8); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId == + param->nIngressTrafficMeterId) { /*Release this meter id from this CTP Port*/ gswdev->meter_idx[param->nIngressTrafficMeterId].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId=0; - + gswdev->ctpportconfig_idx[ctp_port].IngressMeteringAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressTrafficMeterId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - - param->nEgressTrafficMeterId=((tbl_prog_ctpport_egress.val[3] & 0x7F00) >> 8); - if(gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) - { - if(gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId == - param->nEgressTrafficMeterId) - { + } + + param->nEgressTrafficMeterId = ((tbl_prog_ctpport_egress.val[3] & 0x7F00) >> 8); + + if (gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned) { + if (gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId == + param->nEgressTrafficMeterId) { /*Release this meter id from this CTP Port*/ gswdev->meter_idx[param->nEgressTrafficMeterId].IndexInUsageCnt--; - gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId=0; - + gswdev->ctpportconfig_idx[ctp_port].EgressMeteringAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].EgressTrafficMeterId = 0; + } else { /*if assigned and idx does not match with recorded idx. some thing is wrong.This should never happen*/ - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } - } - - param->sPmapper.nPmapperId=(tbl_prog_ctpport_ingress.val[4] & 0xFF); - if(gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) - { - /*Release this p-mapper idx from this CTP Port*/ - gswdev->pmapper_idx[param->sPmapper.nPmapperId].IndexInUse=0; - gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned=0; - gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx=0; - } + } + + param->sPmapper.nPmapperId = (tbl_prog_ctpport_ingress.val[4] & 0xFF); + + if (gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned) { + /*Release this p-mapper idx from this CTP Port*/ + gswdev->pmapper_idx[param->sPmapper.nPmapperId].IndexInUse = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmapperAssigned = 0; + gswdev->ctpportconfig_idx[ctp_port].IngressBridgeBypassPmappperIdx = 0; + } /*Zero the ingress/egress ctp port table index*/ - /*Same ctp port idx for ingress and egress ctp port configuration*/ + /*Same ctp port idx for ingress and egress ctp port configuration*/ memset(&tbl_prog_ctpport_ingress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_ingress.table = PCE_IGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); + CLEAR_U16(tbl_prog_ctpport_ingress.pcindex); /*Table Entry address (ctp port ingress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_ingress.pcindex |= (ctp_port & 0x1FF); - - /*Set Bridge port 127 - The ingress traffic is never assigned to port 127. - The packet may have egress bridge port ID 127 if the traffic is ingress loopback traffic, + + /*Set Bridge port 127 - The ingress traffic is never assigned to port 127. + The packet may have egress bridge port ID 127 if the traffic is ingress loopback traffic, bridge bypass traffic, or mirror copy (either ingress copyor egress copy).*/ tbl_prog_ctpport_ingress.val[0] |= (0x7F); - + memset(&tbl_prog_ctpport_egress, 0, sizeof(pctbl_prog_t)); tbl_prog_ctpport_egress.table = PCE_EGCTP_INDEX; - CLEAR_U16(tbl_prog_ctpport_egress.pcindex); + CLEAR_U16(tbl_prog_ctpport_egress.pcindex); /*Table Entry address (ctp port egress Table index) Bit 8:0 in PCE_TBL_ADDR*/ tbl_prog_ctpport_egress.pcindex |= (ctp_port & 0x1FF); @@ -20224,151 +25275,222 @@ GSW_return_t GSW_CtpPortConfigReset(void *cdev, GSW_CTP_portConfig_t *param) /*Free this ctp port idx*/ //gswdev->ctpportconfig_idx[ctp_port].IndexInUse=0; - - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + return ret; } GSW_return_t GSW_DefaultMacFilterSet(void *cdev, GSW_MACFILTER_default_t *param) { - u16 i=0; + u16 i = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - /* Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), - only index 0-7 is valid. */ - switch(param->eType) - { - case GSW_MACFILTERTYPE_SRC: - for(i=0;i <= 7;i++) - { - gsw_w32(cdev,PCE_SA_FILTER_OFFSET_GET(i), - PCE_SA_FILTER_SHIFT, - PCE_SA_FILTER_SIZE, param->nPortmap[i]); - } - break; - case GSW_MACFILTERTYPE_DEST: - for(i=0;i <= 7;i++) - { - gsw_w32(cdev,PCE_DA_FILTER_OFFSET_GET(i), - PCE_DA_FILTER_SHIFT, - PCE_DA_FILTER_SIZE, param->nPortmap[i]); - } - break; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + /* Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), + only index 0-7 is valid. */ + switch (param->eType) { + case GSW_MACFILTERTYPE_SRC: + for (i = 0; i <= 7; i++) { + gsw_w32(cdev, PCE_SA_FILTER_OFFSET_GET(i), + PCE_SA_FILTER_SHIFT, + PCE_SA_FILTER_SIZE, param->nPortmap[i]); + } + + break; + + case GSW_MACFILTERTYPE_DEST: + for (i = 0; i <= 7; i++) { + gsw_w32(cdev, PCE_DA_FILTER_OFFSET_GET(i), + PCE_DA_FILTER_SHIFT, + PCE_DA_FILTER_SIZE, param->nPortmap[i]); + } + + break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; } GSW_return_t GSW_DefaultMacFilterGet(void *cdev, GSW_MACFILTER_default_t *param) { - u32 i=0,value=0; + u32 i = 0, value = 0; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - /* Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), - only index 0-7 is valid. */ - switch(param->eType) - { - case GSW_MACFILTERTYPE_SRC: - for(i=0;i <= 7;i++) - { - gsw_r32(cdev,PCE_SA_FILTER_OFFSET_GET(i), - PCE_SA_FILTER_SHIFT, - PCE_SA_FILTER_SIZE,&value); - param->nPortmap[i] = value; - } - break; - case GSW_MACFILTERTYPE_DEST: - for(i=0;i <= 7;i++) - { - gsw_r32(cdev,PCE_DA_FILTER_OFFSET_GET(i), - PCE_DA_FILTER_SHIFT, - PCE_DA_FILTER_SIZE, &value); - param->nPortmap[i] = value; - } - break; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + /* Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), + only index 0-7 is valid. */ + switch (param->eType) { + case GSW_MACFILTERTYPE_SRC: + for (i = 0; i <= 7; i++) { + gsw_r32(cdev, PCE_SA_FILTER_OFFSET_GET(i), + PCE_SA_FILTER_SHIFT, + PCE_SA_FILTER_SIZE, &value); + param->nPortmap[i] = value; + } + + break; + + case GSW_MACFILTERTYPE_DEST: + for (i = 0; i <= 7; i++) { + gsw_r32(cdev, PCE_DA_FILTER_OFFSET_GET(i), + PCE_DA_FILTER_SHIFT, + PCE_DA_FILTER_SIZE, &value); + param->nPortmap[i] = value; + } + + break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_QOS_MeterAlloc(void *cdev, GSW_QoS_meterCfg_t *param) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - u16 idx=0,freeidxfound,RetVal; + u16 idx = 0, freeidxfound, ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (param->nMeterId > gswdev->num_of_meters) - return GSW_statusErr; - /*If Meter ID is invalid ,find a new meter index + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_alloc); +#endif + + if (param->nMeterId > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + /*If Meter ID is invalid ,find a new meter index and allocate*/ - if (param->nMeterId == METER_ENTRY_INVALID) - { - for (idx=0;idx < gswdev->num_of_meters && !freeidxfound;idx++) - { - if(!(gswdev->meter_idx[idx].IndexInUse)) - { - gswdev->meter_idx[idx].IndexInUse=1; - param->nMeterId=idx; - freeidxfound=1; + if (param->nMeterId == METER_ENTRY_INVALID) { + for (idx = 0; idx < gswdev->num_of_meters && !freeidxfound; idx++) { + if (!(gswdev->meter_idx[idx].IndexInUse)) { + gswdev->meter_idx[idx].IndexInUse = 1; + param->nMeterId = idx; + freeidxfound = 1; } } + /*No free Slot return Error*/ - if (!freeidxfound) - return GSW_statusErr; - } + if (!freeidxfound) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + } - if (param->nMeterId > gswdev->num_of_meters) - return GSW_statusErr; + if (param->nMeterId > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*If Meter ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!(gswdev->meter_idx[param->nMeterId].IndexInUse)) - return GSW_statusErr; + if (!(gswdev->meter_idx[param->nMeterId].IndexInUse)) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } - /*Change summary of GSW_QoS_MeterCfgSet for GSWIP 3.1 + /*Change summary of GSW_QoS_MeterCfgSet for GSWIP 3.1 1. Meter Color Blind is newly added 2. IBS is byte based */ - RetVal=GSW_QoS_MeterCfgSet(cdev,param); - return RetVal; + ret = GSW_QoS_MeterCfgSet(cdev, param); + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_alloc); +#endif + return ret; } - + GSW_return_t GSW_QOS_MeterFree(void *cdev, GSW_QoS_meterCfg_t *param) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (param->nMeterId > gswdev->num_of_meters) - return GSW_statusErr; - - if (param->nMeterId == METER_ENTRY_INVALID) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_free); +#endif + + if (param->nMeterId > gswdev->num_of_meters) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + if (param->nMeterId == METER_ENTRY_INVALID) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*If Meter ID is valid,Check whether it is InUSE if not InUse,return ERROR*/ - if(!gswdev->meter_idx[param->nMeterId].IndexInUse) - return GSW_statusErr; + if (!gswdev->meter_idx[param->nMeterId].IndexInUse) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } /*If this Meter idx usage count is not zero that means it is still used by some one. This Meter idx can be freed, only if that some one release this Meter ID*/ - if (gswdev->meter_idx[param->nMeterId].IndexInUsageCnt) - return GSW_statusErr; - + if (gswdev->meter_idx[param->nMeterId].IndexInUsageCnt) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + /*Just mark the Meter idx as free*/ - gswdev->meter_idx[param->nMeterId].IndexInUse=0; - return GSW_statusOk; + gswdev->meter_idx[param->nMeterId].IndexInUse = 0; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_free); +#endif + return ret; } GSW_return_t GSW_RMON_ExtendGet(void *cdev, GSW_RMON_extendGet_t *parm) @@ -20376,23 +25498,36 @@ GSW_return_t GSW_RMON_ExtendGet(void *cdev, GSW_RMON_extendGet_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 pidx = parm->nPortId, i; u32 value, data0, data1; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } - if (parm->nPortId >= gswdev->tpnum) - return GSW_statusErr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + + if (parm->nPortId >= gswdev->tpnum) { + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + memset(parm, 0, sizeof(GSW_RMON_extendGet_t)); + for (i = 0; i < GSW_RMON_EXTEND_NUM; i++) { gsw_w32(cdev, BM_RAM_ADDR_ADDR_OFFSET, BM_RAM_ADDR_ADDR_SHIFT, BM_RAM_ADDR_ADDR_SIZE, - (i+REX_TFLOW_CNT_1)); + (i + REX_TFLOW_CNT_1)); + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (pidx >= 8) value = (pidx + 8); else value = pidx; + gsw_w32(cdev, BM_RAM_CTRL_ADDR_OFFSET, BM_RAM_CTRL_ADDR_SHIFT, BM_RAM_CTRL_ADDR_SIZE, value); @@ -20401,6 +25536,7 @@ GSW_return_t GSW_RMON_ExtendGet(void *cdev, GSW_RMON_extendGet_t *parm) BM_RAM_CTRL_ADDR_SHIFT, BM_RAM_CTRL_ADDR_SIZE, pidx); } + gsw_w32(cdev, BM_RAM_CTRL_OPMOD_OFFSET, BM_RAM_CTRL_OPMOD_SHIFT, BM_RAM_CTRL_OPMOD_SIZE, 0); @@ -20408,8 +25544,8 @@ GSW_return_t GSW_RMON_ExtendGet(void *cdev, GSW_RMON_extendGet_t *parm) gsw_w32(cdev, BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, BM_RAM_CTRL_BAS_SIZE, value); - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SHIFT,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SHIFT, RETURN_FROM_FUNCTION); gsw_r32(cdev, BM_RAM_VAL_0_VAL0_OFFSET, BM_RAM_VAL_0_VAL0_SHIFT, BM_RAM_VAL_0_VAL0_SIZE, &data0); @@ -20418,20 +25554,35 @@ GSW_return_t GSW_RMON_ExtendGet(void *cdev, GSW_RMON_extendGet_t *parm) BM_RAM_VAL_1_VAL1_SIZE, &data1); parm->nTrafficFlowCnt[i] = (data1 << 16 | data0); } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 data0, data1, data2, data3, counterMsb = 0, counterLsb = 0; - u32 tflowIndex=0, ctrlRegData = 0, addrRegData = 0; + u32 tflowIndex = 0, ctrlRegData = 0, addrRegData = 0; u8 portType, nBits; //Number of RMON valid bits. GSW_TflowCmodeConf_t cMode; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + //Given absolute couter index to read. if (parm->bIndex) tflowIndex = parm->nIndex; @@ -20439,28 +25590,34 @@ GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) //Compute absolute couter index to read. memset(&cMode, 0, sizeof(GSW_RMON_flowGet_t)); GSW_TflowCountModeGet(cdev, &cMode); - if(cMode.eCountMode == GSW_TFLOW_CMODE_LOGICAL) + + if (cMode.eCountMode == GSW_TFLOW_CMODE_LOGICAL) nBits = 5; else nBits = (cMode.nBrpLsb | cMode.nCtpLsb); //Only one of is valiad. + //Is the given port is among configured MSB port group? if ((parm->nPortId >> (9 - nBits)) == cMode.nPortMsb) { //LS (9-nBits) bits of given port become MS bits of counter index to read. - counterMsb = ((parm->nPortId) & ((1 << (9-nBits)) - 1)); + counterMsb = ((parm->nPortId) & ((1 << (9 - nBits)) - 1)); //LS (nBits) bits of given RMON-Id become LS bits of counter index to read. counterLsb = ((parm->nFlowId) & ((1 << nBits) - 1)); //Absolute counter index to read is. tflowIndex = ((counterMsb << nBits) | counterLsb); parm->nIndex = tflowIndex; } else { - pr_err("ERR:nPortId's MS %d bits are not matching the group %d\n", - (9-(nBits - 1)), cMode.nPortMsb); - return GSW_statusErr; + pr_err("ERR:nPortId's MS %d bits are not matching the group %d\n", + (9 - (nBits - 1)), cMode.nPortMsb); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + //Validate absolute couter index. - if (tflowIndex >= PCE_TABLE_SIZE) //Max index check. - return GSW_statusErr; + if (tflowIndex >= PCE_TABLE_SIZE) { //Max index check. + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } //1.Get PCE Rx counters. portType = GSW_RMON_TFLOW_RX; @@ -20480,8 +25637,8 @@ GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) //Set RAM table to read. gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to read. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, &data0); gsw_r32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, &data1); parm->nRxPkts = (data1 << 16 | data0); @@ -20489,8 +25646,8 @@ GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) //2.Get PCE Tx counters. portType = GSW_RMON_TFLOW_TX; //RMON TFLOW Tx table to read. - CLEAR_FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_ADDR_SHIFT, - BM_RAM_CTRL_ADDR_SIZE, portType); + CLEAR_FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_ADDR_SHIFT, + BM_RAM_CTRL_ADDR_SIZE, portType); //64 bit counter mode. It is not supported in HW at this moment. //FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_64BIT_OPMOD_SHIFT, 1); //Set RAM address to read. @@ -20498,8 +25655,8 @@ GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) //Set RAM table to read. gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to read. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, &data0); gsw_r32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, &data1); parm->nTxPkts = (data1 << 16 | data0); @@ -20510,13 +25667,20 @@ GSW_return_t GSW_RMON_FlowGet(void *cdev, GSW_RMON_flowGet_t *parm) //Set RAM table to read. gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to read. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, &data2); - gsw_r32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, &data3); + gsw_r32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, &data3); parm->nTxPceBypassPkts = (data3 << 16 | data2); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) @@ -20526,10 +25690,17 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) u32 counterMsb = 0, counterLsb = 0; u8 portType, nBits; //Number of RMON valid bits. GSW_TflowCmodeConf_t cMode; + u32 ret; + if (gswdev == NULL) { pr_err("%s:%s:%d\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + //Given absolute couter index to read. if (parm->bIndex) tflowIndex = parm->nIndex; @@ -20537,28 +25708,34 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) //Compute absolute couter index to read. memset(&cMode, 0, sizeof(GSW_RMON_flowGet_t)); GSW_TflowCountModeGet(cdev, &cMode); - if(cMode.eCountMode == GSW_TFLOW_CMODE_LOGICAL) + + if (cMode.eCountMode == GSW_TFLOW_CMODE_LOGICAL) nBits = 5; else nBits = (cMode.nBrpLsb | cMode.nCtpLsb); //Only one of is valiad. + //Is the given port is among configured MSB port group? if ((parm->nPortId >> (9 - nBits)) == cMode.nPortMsb) { //LS (9-nBits) bits of given port become MS bits of counter index to read. - counterMsb = ((parm->nPortId) & ((1 << (9-nBits)) - 1)); + counterMsb = ((parm->nPortId) & ((1 << (9 - nBits)) - 1)); //LS (nBits) bits of given RMON-Id become LS bits of counter index to read. counterLsb = ((parm->nFlowId) & ((1 << nBits) - 1)); //Absolute counter index to read is. tflowIndex = ((counterMsb << nBits) | counterLsb); parm->nIndex = tflowIndex; } else { - pr_err("ERR:nPortId's MS %d bits are not matching the group %d\n", - (9-(nBits - 1)), cMode.nPortMsb); - return GSW_statusErr; + pr_err("ERR:nPortId's MS %d bits are not matching the group %d\n", + (9 - (nBits - 1)), cMode.nPortMsb); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } + //Validate absolute couter index. - if (tflowIndex >= PCE_TABLE_SIZE) //Max index check. - return GSW_statusErr; + if (tflowIndex >= PCE_TABLE_SIZE) { //Max index check. + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } //1.Clear PCE Rx counters. //Populate 'data' register data. @@ -20580,15 +25757,15 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) //Set RAM table counters to clear. gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to write. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); //2.Clear PCE Tx counters. //Populate 'data' register data. portType = GSW_RMON_TFLOW_TX; //RMON TFLOW Tx table to write. - CLEAR_FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_ADDR_SHIFT, - BM_RAM_CTRL_ADDR_SIZE, portType); + CLEAR_FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_ADDR_SHIFT, + BM_RAM_CTRL_ADDR_SIZE, portType); //64 bit counter mode. It is not supported in HW at this moment. //FILL_CTRL_REG(ctrlRegData, BM_RAM_CTRL_64BIT_OPMOD_SHIFT, 1); gsw_w32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, 0); @@ -20596,10 +25773,10 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) //Set RAM address to write. gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, addrRegData); //Set RAM table to write. - gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); + gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to write. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); //3.Clear PCE-Bypass Tx counters. gsw_w32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET, 0); gsw_w32_raw(cdev, BM_RAM_VAL_1_VAL1_OFFSET, 0); @@ -20607,254 +25784,311 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm) addrRegData = addrRegData + 1; gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, addrRegData); //Set RAM table to write. - gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); + gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ctrlRegData); //Wait untill RAM is ready to write. - CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET,BM_RAM_CTRL_BAS_SHIFT, - BM_RAM_CTRL_BAS_SIZE,RETURN_FROM_FUNCTION); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); - return GSW_statusOk; + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_TflowCountModeSet(void *cdev, GSW_TflowCmodeConf_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 numValBits = 0, rxTflowReg = 0, txTflowReg = 0, txBpTflowReg = 0; + u32 ret; + if (gswdev == NULL) { pr_err("%s:%s:%d\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + //Validate TFLOW RMON counter type. if (parm->eCountType > GSW_TFLOW_COUNTER_PCE_BP_Tx) { pr_err("ERR:Invalid couter type\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + //Validate TFLOW RMON counter mode type. if (parm->eCountMode > GSW_TFLOW_CMODE_BRIDGE) { pr_err("ERR:Invalid couter mode type\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } + //Validate 'n' for CTP or Br port type. if (parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) { numValBits = parm->nBrpLsb; - if ((numValBits < GSW_TCM_BRP_VAL_BITS_2) || - (numValBits > GSW_TCM_BRP_VAL_BITS_6)) { + + if ((numValBits < GSW_TCM_BRP_VAL_BITS_2) || + (numValBits > GSW_TCM_BRP_VAL_BITS_6)) { pr_err("ERR:Invalid Br-Port type LSB bits\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } else if (parm->eCountMode == GSW_TFLOW_CMODE_CTP) { numValBits = parm->nCtpLsb; + if ((numValBits > GSW_TCM_CTP_VAL_BITS_6)) { pr_err("ERR:Invalid CTP-Port type LSB bits\n"); - return GSW_statusErr; + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; } } - //Configure registers. + + //Configure registers. switch (parm->eCountMode) { - case GSW_TFLOW_CMODE_BRIDGE: - case GSW_TFLOW_CMODE_CTP: - //1.PCE TFLOW Rx setting. - //Populate PCE TFLOW Rx RMON register. - //Set 'n' i.e port's LSB bits. - FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_LSB_SHIFT, numValBits); - //Set port's MSB bits. - FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_MSB_SHIFT, parm->nPortMsb); - - //2.PCE TFLOW Tx setting. - //Populate PCE TFLOW Tx RMON register. - //Set 'n' i.e port's LSB bits. - FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_LSB_SHIFT, numValBits); - //Set port's MSB bits. - FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_MSB_SHIFT, parm->nPortMsb); - - //3.PCE-Bypass TFLOW Tx setting. - //Populate PCE-Bypass TFLOW Tx RMON register. - //Set 'n' i.e port's LSB bits. - FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_LSB_SHIFT, numValBits); - //Set port's MSB bits. - FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_MSB_SHIFT, parm->nPortMsb); - //break; //Fall through to set mode. - case GSW_TFLOW_CMODE_LOGICAL: - //1.PCE TFLOW Rx setting. - //Populate PCE TFLOW Rx RMON register. - //Set counter mode. - FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_MD_SHIFT, parm->eCountMode); - - //2.PCE TFLOW Tx setting - //Populate PCE TFLOW Tx RMON register. - //Set counter mode. - FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_MD_SHIFT, parm->eCountMode); - - //3.PCE-Bypass TFLOW Tx setting - //Populate PCE-Bypass TFLOW Tx RMON register. - //Set counter mode. - FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_MD_SHIFT, parm->eCountMode); - //break; //Fall through to write into register. - case GSW_TFLOW_CMODE_GLOBAL: - //Write PCE TFLOW Rx RMON register. - if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || - (parm->eCountType == GSW_TFLOW_COUNTER_PCE_Rx)) - gsw_w32_raw(cdev, BM_RXFLOW_RMON_REG_OFFSET, rxTflowReg); - - //Write PCE TFLOW Tx RMON register. - if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || - (parm->eCountType == GSW_TFLOW_COUNTER_PCE_Tx)) - gsw_w32_raw(cdev, BM_TXFLOW_RMON_REG_OFFSET, txTflowReg); - - //Write PCE-Bypass TFLOW Tx RMON register. - if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || - (parm->eCountType == GSW_TFLOW_COUNTER_PCE_BP_Tx)) - gsw_w32_raw(cdev, BM_TXBPFLOW_RMON_REG_OFFSET, txBpTflowReg); - break; - default: - break; + case GSW_TFLOW_CMODE_BRIDGE: + case GSW_TFLOW_CMODE_CTP: + //1.PCE TFLOW Rx setting. + //Populate PCE TFLOW Rx RMON register. + //Set 'n' i.e port's LSB bits. + FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_LSB_SHIFT, numValBits); + //Set port's MSB bits. + FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_MSB_SHIFT, parm->nPortMsb); + + //2.PCE TFLOW Tx setting. + //Populate PCE TFLOW Tx RMON register. + //Set 'n' i.e port's LSB bits. + FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_LSB_SHIFT, numValBits); + //Set port's MSB bits. + FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_MSB_SHIFT, parm->nPortMsb); + + //3.PCE-Bypass TFLOW Tx setting. + //Populate PCE-Bypass TFLOW Tx RMON register. + //Set 'n' i.e port's LSB bits. + FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_LSB_SHIFT, numValBits); + //Set port's MSB bits. + FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_MSB_SHIFT, parm->nPortMsb); + + //break; //Fall through to set mode. + case GSW_TFLOW_CMODE_LOGICAL: + //1.PCE TFLOW Rx setting. + //Populate PCE TFLOW Rx RMON register. + //Set counter mode. + FILL_CTRL_REG(rxTflowReg, BM_RXFLOW_RMON_MD_SHIFT, parm->eCountMode); + + //2.PCE TFLOW Tx setting + //Populate PCE TFLOW Tx RMON register. + //Set counter mode. + FILL_CTRL_REG(txTflowReg, BM_TXFLOW_RMON_MD_SHIFT, parm->eCountMode); + + //3.PCE-Bypass TFLOW Tx setting + //Populate PCE-Bypass TFLOW Tx RMON register. + //Set counter mode. + FILL_CTRL_REG(txBpTflowReg, BM_TXBPFLOW_RMON_MD_SHIFT, parm->eCountMode); + + //break; //Fall through to write into register. + case GSW_TFLOW_CMODE_GLOBAL: + + //Write PCE TFLOW Rx RMON register. + if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || + (parm->eCountType == GSW_TFLOW_COUNTER_PCE_Rx)) + gsw_w32_raw(cdev, BM_RXFLOW_RMON_REG_OFFSET, rxTflowReg); + + //Write PCE TFLOW Tx RMON register. + if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || + (parm->eCountType == GSW_TFLOW_COUNTER_PCE_Tx)) + gsw_w32_raw(cdev, BM_TXFLOW_RMON_REG_OFFSET, txTflowReg); + + //Write PCE-Bypass TFLOW Tx RMON register. + if ((parm->eCountType == GSW_TFLOW_COUNTER_ALL) || + (parm->eCountType == GSW_TFLOW_COUNTER_PCE_BP_Tx)) + gsw_w32_raw(cdev, BM_TXBPFLOW_RMON_REG_OFFSET, txBpTflowReg); + + break; + + default: + break; } - return GSW_statusOk; + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_TflowCountModeGet(void *cdev, GSW_TflowCmodeConf_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 rxTflowReg = 0, txTflowReg = 0, txBpTflowReg = 0; + u32 ret; + if (gswdev == NULL) { pr_err("%s:%s:%d\n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + switch (parm->eCountType) { - case GSW_TFLOW_COUNTER_ALL: - case GSW_TFLOW_COUNTER_PCE_Rx: - //1.PCE TFLOW Rx config. - //Read PCE TFLOW Rx RMON register. - gsw_r32_raw(cdev, BM_RXFLOW_RMON_REG_OFFSET, &rxTflowReg); - //Populate PCE TFLOW Rx RMON structure. - //Get counter mode. - GET_VAL_FROM_REG(parm->eCountMode, BM_RXFLOW_RMON_MD_SHIFT, BM_RXFLOW_RMON_MD_SIZE, rxTflowReg); - //Get port's LSB bits. - if(parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) - GET_VAL_FROM_REG(parm->nBrpLsb, BM_RXFLOW_RMON_LSB_SHIFT, BM_RXFLOW_RMON_LSB_SIZE, rxTflowReg); - if(parm->eCountMode == GSW_TFLOW_CMODE_CTP) - GET_VAL_FROM_REG(parm->nCtpLsb, BM_RXFLOW_RMON_LSB_SHIFT, BM_RXFLOW_RMON_LSB_SIZE, rxTflowReg); - //Get port's MSB bits. - GET_VAL_FROM_REG(parm->nPortMsb, BM_RXFLOW_RMON_MSB_SHIFT, BM_RXFLOW_RMON_MSB_SIZE, rxTflowReg); - break; - case GSW_TFLOW_COUNTER_PCE_Tx: - //2.PCE TFLOW Tx config - //Read PCE TFLOW Tx RMON register. - gsw_r32_raw(cdev, BM_TXFLOW_RMON_REG_OFFSET, &txTflowReg); - //Populate PCE TFLOW Tx RMON structure. - //Get counter mode. - GET_VAL_FROM_REG(parm->eCountMode, BM_TXFLOW_RMON_MD_SHIFT, BM_TXFLOW_RMON_MD_SIZE, txTflowReg); - //Get port's LSB bits. - if(parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) - GET_VAL_FROM_REG(parm->nBrpLsb, BM_TXFLOW_RMON_LSB_SHIFT, BM_TXFLOW_RMON_LSB_SIZE, txTflowReg); - if(parm->eCountMode == GSW_TFLOW_CMODE_CTP) - GET_VAL_FROM_REG(parm->nCtpLsb, BM_TXFLOW_RMON_LSB_SHIFT, BM_TXFLOW_RMON_LSB_SIZE, txTflowReg); - //Get port's MSB bits. - GET_VAL_FROM_REG(parm->nPortMsb, BM_TXFLOW_RMON_MSB_SHIFT, BM_TXFLOW_RMON_MSB_SIZE, txTflowReg); - break; - case GSW_TFLOW_COUNTER_PCE_BP_Tx: - //3.PCE-Bypass TFLOW Tx config - //Write PCE-Bypass TFLOW Tx RMON register. - gsw_r32_raw(cdev, BM_TXBPFLOW_RMON_REG_OFFSET, &txBpTflowReg); - //Populate PCE-Bypass TFLOW Tx RMON structure. - //Get port's LSB bits. - GET_VAL_FROM_REG(parm->eCountMode, BM_TXBPFLOW_RMON_MD_SHIFT, BM_TXBPFLOW_RMON_MD_SIZE, txBpTflowReg); - //Get port's LSB bits. - if(parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) - GET_VAL_FROM_REG(parm->nBrpLsb, BM_TXBPFLOW_RMON_LSB_SHIFT, BM_TXBPFLOW_RMON_LSB_SIZE, txBpTflowReg); - if(parm->eCountMode == GSW_TFLOW_CMODE_CTP) - GET_VAL_FROM_REG(parm->nCtpLsb, BM_TXBPFLOW_RMON_LSB_SHIFT, BM_TXBPFLOW_RMON_LSB_SIZE, txBpTflowReg); - //Get port's MSB bits. - GET_VAL_FROM_REG(parm->nPortMsb, BM_TXBPFLOW_RMON_MSB_SHIFT, BM_TXBPFLOW_RMON_MSB_SIZE, txBpTflowReg); - break; - } - return GSW_statusOk; + case GSW_TFLOW_COUNTER_ALL: + case GSW_TFLOW_COUNTER_PCE_Rx: + //1.PCE TFLOW Rx config. + //Read PCE TFLOW Rx RMON register. + gsw_r32_raw(cdev, BM_RXFLOW_RMON_REG_OFFSET, &rxTflowReg); + //Populate PCE TFLOW Rx RMON structure. + //Get counter mode. + GET_VAL_FROM_REG(parm->eCountMode, BM_RXFLOW_RMON_MD_SHIFT, BM_RXFLOW_RMON_MD_SIZE, rxTflowReg); + + //Get port's LSB bits. + if (parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) + GET_VAL_FROM_REG(parm->nBrpLsb, BM_RXFLOW_RMON_LSB_SHIFT, BM_RXFLOW_RMON_LSB_SIZE, rxTflowReg); + + if (parm->eCountMode == GSW_TFLOW_CMODE_CTP) + GET_VAL_FROM_REG(parm->nCtpLsb, BM_RXFLOW_RMON_LSB_SHIFT, BM_RXFLOW_RMON_LSB_SIZE, rxTflowReg); + + //Get port's MSB bits. + GET_VAL_FROM_REG(parm->nPortMsb, BM_RXFLOW_RMON_MSB_SHIFT, BM_RXFLOW_RMON_MSB_SIZE, rxTflowReg); + break; + + case GSW_TFLOW_COUNTER_PCE_Tx: + //2.PCE TFLOW Tx config + //Read PCE TFLOW Tx RMON register. + gsw_r32_raw(cdev, BM_TXFLOW_RMON_REG_OFFSET, &txTflowReg); + //Populate PCE TFLOW Tx RMON structure. + //Get counter mode. + GET_VAL_FROM_REG(parm->eCountMode, BM_TXFLOW_RMON_MD_SHIFT, BM_TXFLOW_RMON_MD_SIZE, txTflowReg); + + //Get port's LSB bits. + if (parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) + GET_VAL_FROM_REG(parm->nBrpLsb, BM_TXFLOW_RMON_LSB_SHIFT, BM_TXFLOW_RMON_LSB_SIZE, txTflowReg); + + if (parm->eCountMode == GSW_TFLOW_CMODE_CTP) + GET_VAL_FROM_REG(parm->nCtpLsb, BM_TXFLOW_RMON_LSB_SHIFT, BM_TXFLOW_RMON_LSB_SIZE, txTflowReg); + + //Get port's MSB bits. + GET_VAL_FROM_REG(parm->nPortMsb, BM_TXFLOW_RMON_MSB_SHIFT, BM_TXFLOW_RMON_MSB_SIZE, txTflowReg); + break; + + case GSW_TFLOW_COUNTER_PCE_BP_Tx: + //3.PCE-Bypass TFLOW Tx config + //Write PCE-Bypass TFLOW Tx RMON register. + gsw_r32_raw(cdev, BM_TXBPFLOW_RMON_REG_OFFSET, &txBpTflowReg); + //Populate PCE-Bypass TFLOW Tx RMON structure. + //Get port's LSB bits. + GET_VAL_FROM_REG(parm->eCountMode, BM_TXBPFLOW_RMON_MD_SHIFT, BM_TXBPFLOW_RMON_MD_SIZE, txBpTflowReg); + + //Get port's LSB bits. + if (parm->eCountMode == GSW_TFLOW_CMODE_BRIDGE) + GET_VAL_FROM_REG(parm->nBrpLsb, BM_TXBPFLOW_RMON_LSB_SHIFT, BM_TXBPFLOW_RMON_LSB_SIZE, txBpTflowReg); + + if (parm->eCountMode == GSW_TFLOW_CMODE_CTP) + GET_VAL_FROM_REG(parm->nCtpLsb, BM_TXBPFLOW_RMON_LSB_SHIFT, BM_TXBPFLOW_RMON_LSB_SIZE, txBpTflowReg); + + //Get port's MSB bits. + GET_VAL_FROM_REG(parm->nPortMsb, BM_TXBPFLOW_RMON_MSB_SHIFT, BM_TXBPFLOW_RMON_MSB_SIZE, txBpTflowReg); + break; + } + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + return ret; } GSW_return_t GSW_Reset(void *cdev, GSW_reset_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 value; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + gswdev->rst = 1; gswdev->hwinit = 0; -/* Reset the Switch via Switch IP register*/ + /* Reset the Switch via Switch IP register*/ value = 1; gsw_w32(cdev, ETHSW_SWRES_R0_OFFSET, ETHSW_SWRES_R0_SHIFT, ETHSW_SWRES_R0_SIZE, value); - return (CHECK_BUSY(ETHSW_SWRES_R0_OFFSET,ETHSW_SWRES_R0_SHIFT, - ETHSW_SWRES_R0_SIZE,RETURN_ERROR_CODE)); + ret = CHECK_BUSY(ETHSW_SWRES_R0_OFFSET, ETHSW_SWRES_R0_SHIFT, + ETHSW_SWRES_R0_SIZE, RETURN_ERROR_CODE); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + return ret; + } GSW_return_t GSW_VersionGet(void *cdev, GSW_version_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + if (parm->nId == 0) { memcpy(parm->cName, VERSION_NAME, sizeof(VERSION_NAME)); memcpy(parm->cVersion, VERSION_NUMBER, sizeof(VERSION_NUMBER)); } else if (parm->nId == 1) { memcpy(parm->cName, MICRO_CODE_VERSION_NAME, - sizeof(MICRO_CODE_VERSION_NAME)); + sizeof(MICRO_CODE_VERSION_NAME)); memcpy(parm->cVersion, MICRO_CODE_VERSION_NUMBER, - sizeof(MICRO_CODE_VERSION_NUMBER)); + sizeof(MICRO_CODE_VERSION_NUMBER)); } else { memcpy(parm->cName, "", 0); memcpy(parm->cVersion, "", 0); } - return GSW_statusOk; -} -#if 0 -int platform_device_init(void *cdev) -{ - u32 reg_val, phy_reg; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev->gipver == LTQ_GSWIP_2_0) { - /* Set Port 6 RBUF_BYPASS mode */ - gsw_r32(cdev, - (MAC_LPITMER0_TMLSB_OFFSET + (6 * 0xC)), - PHY_ADDR_4_ADDR_SHIFT, - PHY_ADDR_4_ADDR_SIZE, &phy_reg); - phy_reg |= (1 << 6); - gsw_w32(cdev, - (MAC_LPITMER0_TMLSB_OFFSET + (6 * 0xC)), - PHY_ADDR_4_ADDR_SHIFT, - PHY_ADDR_4_ADDR_SIZE, phy_reg); - gsw_w32(cdev, - (PMAC_RX_IPG_IPG_CNT_OFFSET + GSW_TREG_OFFSET), - PMAC_RX_IPG_IPG_CNT_SHIFT, - PMAC_RX_IPG_IPG_CNT_SIZE, 0xB); - } - return GSW_statusOk; + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + + return ret; + } -#endif /* if 0*/ -GSW_return_t GSW_Enable(void *cdev) +static GSW_return_t GSW_Enable_Legacy(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 j; - + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; } -/* if (gswdev->hwinit == 0) */ -/* platform_device_init(cdev); */ + + +#if defined(CONFIG_USE_EMULATOR) && defined(__KERNEL__) + for (j = 0; j < gswdev->tpnum; j++) { - gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), - FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 1); - gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 1); - /*Enable All RMON Counters*/ - gsw_w32(cdev, (BM_PCFG_CNTEN_OFFSET + (j * 2)), - BM_PCFG_CNTEN_SHIFT, BM_PCFG_CNTEN_SIZE, 1); -#if defined(CONFIG_USE_EMULATOR) && CONFIG_USE_EMULATOR if (gswdev->gipver == LTQ_GSWIP_3_0) { gsw_w32(cdev, (MAC_CTRL_0_FDUP_OFFSET + (0xC * j)), @@ -20864,38 +26098,40 @@ GSW_return_t GSW_Enable(void *cdev) MAC_CTRL_0_GMII_SHIFT, MAC_CTRL_0_GMII_SIZE, 2); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_SPEED_OFFSET - + (j * 4)) + GSW30_TOP_OFFSET), + + (j * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_SPEED_SHIFT, GSWT_PHY_ADDR_1_SPEED_SIZE, 2); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_FDUP_OFFSET - + (j * 4)) + GSW30_TOP_OFFSET), + + (j * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_FDUP_SHIFT, GSWT_PHY_ADDR_1_FDUP_SIZE, 1); gsw_w32(cdev, ((GSWT_PHY_ADDR_1_LNKST_OFFSET - + (j * 4)) + GSW30_TOP_OFFSET), + + (j * 4)) + GSW30_TOP_OFFSET), GSWT_PHY_ADDR_1_LNKST_SHIFT, GSWT_PHY_ADDR_1_LNKST_SIZE, 1); } else { gsw_w32(cdev, ((PHY_ADDR_0_SPEED_OFFSET - j) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_SPEED_SHIFT, PHY_ADDR_0_SPEED_SIZE, 2); gsw_w32(cdev, ((PHY_ADDR_0_FDUP_OFFSET - j) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_FDUP_SHIFT, PHY_ADDR_0_FDUP_SIZE, 1); gsw_w32(cdev, ((PHY_ADDR_0_LNKST_OFFSET - j) - + GSW_TREG_OFFSET), + + GSW_TREG_OFFSET), PHY_ADDR_0_LNKST_SHIFT, PHY_ADDR_0_LNKST_SIZE, 1); } -#endif } + +#endif + if (gswdev->gipver == LTQ_GSWIP_3_0) { for (j = 0; j < gswdev->tpnum; j++) { gsw_w32(cdev, (BM_PCFG_CNTEN_OFFSET + (j * 2)), @@ -20903,6 +26139,7 @@ GSW_return_t GSW_Enable(void *cdev) gsw_w32(cdev, (BM_RMON_CTRL_BCAST_CNT_OFFSET + (j * 0x2)), BM_RMON_CTRL_BCAST_CNT_SHIFT, BM_RMON_CTRL_BCAST_CNT_SIZE, 1); } + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { gsw_w32(cdev, PCE_TFCR_NUM_NUM_OFFSET, PCE_TFCR_NUM_NUM_SHIFT, @@ -20910,22 +26147,78 @@ GSW_return_t GSW_Enable(void *cdev) } } - if (gswdev->gipver == LTQ_GSWIP_3_1) { + return GSW_statusOk; + +} + +GSW_return_t GSW_Enable(void *cdev) +{ + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u8 j; + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + + for (j = 0; j < gswdev->tpnum; j++) { + gsw_w32(cdev, + (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), + FDMA_PCTRL_EN_SHIFT, + FDMA_PCTRL_EN_SIZE, 1); + gsw_w32(cdev, + (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), + SDMA_PCTRL_PEN_SHIFT, + SDMA_PCTRL_PEN_SIZE, 1); + /*Enable All RMON Counters*/ + gsw_w32(cdev, + (BM_PCFG_CNTEN_OFFSET + (j * 2)), + BM_PCFG_CNTEN_SHIFT, + BM_PCFG_CNTEN_SIZE, 1); + } + + if (IS_VRSN_NOT_31(gswdev->gipver)) { + GSW_Enable_Legacy(cdev); + } + +#if defined(CONFIG_MAC) && CONFIG_MAC + + if (IS_VRSN_31(gswdev->gipver)) { struct adap_ops *ops = get_adap_ops(gswdev); ops->ss_core_en(ops, 1); } - return GSW_statusOk; +#endif + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + + return ret; + } GSW_return_t GSW_Disable(void *cdev) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u8 j; + u32 ret; + if (gswdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return GSW_statusErr; } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_misc); +#endif + /* Disable all physical port */ for (j = 0; j < gswdev->tpnum; j++) { gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), @@ -20933,7 +26226,14 @@ GSW_return_t GSW_Disable(void *cdev) gsw_w32(cdev, (SDMA_PCTRL_PEN_OFFSET + (j * 0x6)), SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); } - return GSW_statusOk; + + ret = GSW_statusOk; + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_misc); +#endif + + return ret; } @@ -20963,19 +26263,19 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_swmac_ops.MAC_TableEntryRemove = GSW_MAC_TableEntryRemove; ops->gsw_swmac_ops.MAC_DefaultFilterSet = GSW_DefaultMacFilterSet; ops->gsw_swmac_ops.MAC_DefaultFilterGet = GSW_DefaultMacFilterGet; - + /*Extended Vlan operations*/ ops->gsw_extvlan_ops.ExtendedVlan_Alloc = GSW_ExtendedVlanAlloc; ops->gsw_extvlan_ops.ExtendedVlan_Set = GSW_ExtendedVlanSet; ops->gsw_extvlan_ops.ExtendedVlan_Get = GSW_ExtendedVlanGet; - ops->gsw_extvlan_ops.ExtendedVlan_Free = GSW_ExtendedVlanFree; - + ops->gsw_extvlan_ops.ExtendedVlan_Free = GSW_ExtendedVlanFree; + /*Vlan Filter operations*/ ops->gsw_vlanfilter_ops.VlanFilter_Alloc = GSW_VlanFilterAlloc; ops->gsw_vlanfilter_ops.VlanFilter_Set = GSW_VlanFilterSet; ops->gsw_vlanfilter_ops.VlanFilter_Get = GSW_VlanFilterGet; ops->gsw_vlanfilter_ops.VlanFilter_Free = GSW_VlanFilterFree; - + /*CTP operations*/ ops->gsw_ctp_ops.CTP_PortAssignmentAlloc = GSW_CTP_PortAssignmentAlloc; ops->gsw_ctp_ops.CTP_PortAssignmentFree = GSW_CTP_PortAssignmentFree; @@ -21001,7 +26301,7 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_tflow_ops.TFLOW_PceRuleDelete = GSW_PceRuleDelete; ops->gsw_tflow_ops.TFLOW_PceRuleRead = GSW_PceRuleRead; ops->gsw_tflow_ops.TFLOW_PceRuleWrite = GSW_PceRuleWrite; - + /*QOS operations*/ ops->gsw_qos_ops.QoS_MeterCfgGet = GSW_QoS_MeterCfgGet; ops->gsw_qos_ops.QoS_MeterCfgSet = GSW_QoS_MeterCfgSet; @@ -21046,7 +26346,7 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_qos_ops.QoS_QueueBufferReserveCfgGet = GSW_QoS_QueueBufferReserveCfgGet; ops->gsw_qos_ops.QoS_QueueBufferReserveCfgSet = GSW_QoS_QueueBufferReserveCfgSet; ops->gsw_qos_ops.QoS_Meter_Act = GSW_QoS_Meter_Act; - ops->gsw_qos_ops.QOS_ColorMarkingTableGet = GSW_QOS_ColorMarkingTableSet; + ops->gsw_qos_ops.QOS_ColorMarkingTableGet = GSW_QOS_ColorMarkingTableSet; ops->gsw_qos_ops.QOS_ColorMarkingTableSet = GSW_QOS_ColorMarkingTableGet; ops->gsw_qos_ops.QOS_ColorReMarkingTableSet = GSW_QOS_ColorReMarkingTableSet; ops->gsw_qos_ops.QOS_ColorReMarkingTableGet = GSW_QOS_ColorReMarkingTableGet; @@ -21060,29 +26360,29 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_qos_ops.QoS_SVLAN_ClassPCP_PortSet = GSW_QoS_SVLAN_ClassPCP_PortSet; ops->gsw_qos_ops.QoS_SVLAN_PCP_ClassGet = GSW_QoS_SVLAN_PCP_ClassGet; ops->gsw_qos_ops.QoS_SVLAN_PCP_ClassSet = GSW_QoS_SVLAN_PCP_ClassSet; - + /*STP operations*/ ops->gsw_stp_ops.STP_BPDU_RuleGet = GSW_STP_BPDU_RuleGet; ops->gsw_stp_ops.STP_BPDU_RuleSet = GSW_STP_BPDU_RuleSet; ops->gsw_stp_ops.STP_PortCfgGet = GSW_STP_PortCfgGet; ops->gsw_stp_ops.STP_PortCfgSet = GSW_STP_PortCfgSet; - + /*8021x operations*/ ops->gsw_8021x_ops.EAPOL_RuleGet = GSW_8021X_EAPOL_RuleGet; ops->gsw_8021x_ops.EAPOL_RuleGet_RuleSet = GSW_8021X_EAPOL_RuleSet; ops->gsw_8021x_ops.EAPOL_RuleGet_PortCfgGet = GSW_8021X_PortCfgGet; ops->gsw_8021x_ops.EAPOL_RuleGet_PortCfgSet = GSW_8021X_PortCfgSet; - + /*multicast operations*/ ops->gsw_multicast_ops.Multicast_RouterPortAdd = GSW_MulticastRouterPortAdd; ops->gsw_multicast_ops.Multicast_RouterPortRead = GSW_MulticastRouterPortRead; - ops->gsw_multicast_ops.Multicast_RouterPortRemove=GSW_MulticastRouterPortRemove; + ops->gsw_multicast_ops.Multicast_RouterPortRemove = GSW_MulticastRouterPortRemove; ops->gsw_multicast_ops.Multicast_SnoopCfgGet = GSW_MulticastSnoopCfgGet; ops->gsw_multicast_ops.Multicast_SnoopCfgSet = GSW_MulticastSnoopCfgSet; ops->gsw_multicast_ops.Multicast_TableEntryAdd = GSW_MulticastTableEntryAdd; ops->gsw_multicast_ops.Multicast_TableEntryRead = GSW_MulticastTableEntryRead; - ops->gsw_multicast_ops.Multicast_TableEntryRemove=GSW_MulticastTableEntryRemove; - + ops->gsw_multicast_ops.Multicast_TableEntryRemove = GSW_MulticastTableEntryRemove; + /*Trunking operations*/ ops->gsw_trunking_ops.Trunking_CfgGet = GSW_TrunkingCfgGet; ops->gsw_trunking_ops.Trunking_CfgSet = GSW_TrunkingCfgSet; @@ -21094,7 +26394,7 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_wol_ops.WoL_CfgSet = GSW_WoL_CfgSet; ops->gsw_wol_ops.WoL_PortCfgGet = GSW_WoL_PortCfgGet; ops->gsw_wol_ops.WoL_PortCfgSet = GSW_WoL_PortCfgSet; - + /*Common switch operations*/ ops->gsw_common_ops.RegisterGet = GSW_RegisterGet; ops->gsw_common_ops.RegisterSet = GSW_RegisterSet; @@ -21148,7 +26448,7 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_pmac_ops.Pmac_Eg_CfgSet = GSW_PMAC_EG_CfgSet; ops->gsw_pmac_ops.Pmac_Eg_CfgGet = GSW_PMAC_EG_CfgGet; - /*VLAN operation*/ + /*VLAN operation*/ ops->gsw_vlan_ops.VLAN_Member_Init = GSW_VLAN_Member_Init; ops->gsw_vlan_ops.VLAN_IdCreate = GSW_VLAN_IdCreate; ops->gsw_vlan_ops.VLAN_IdDelete = GSW_VLAN_IdDelete; @@ -21168,7 +26468,8 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_vlan_ops.SVLAN_CfgSet = GSW_SVLAN_CfgSet; ops->gsw_vlan_ops.SVLAN_PortCfgGet = GSW_SVLAN_PortCfgGet; ops->gsw_vlan_ops.SVLAN_PortCfgSet = GSW_SVLAN_PortCfgSet; - + +#ifdef __KERNEL__ /*PAE operation*/ ops->gsw_pae_ops.ROUTE_SessionEntryAdd = GSW_ROUTE_SessionEntryAdd; ops->gsw_pae_ops.ROUTE_SessionEntryDel = GSW_ROUTE_SessionEntryDel; @@ -21180,6 +26481,7 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_pae_ops.ROUTE_L2NATCfgRead = GSW_ROUTE_L2NATCfgRead; ops->gsw_pae_ops.ROUTE_SessHitOp = GSW_ROUTE_SessHitOp; ops->gsw_pae_ops.ROUTE_SessDestModify = GSW_ROUTE_SessDestModify; +#endif /*Debug operation*/ ops->gsw_debug_ops.DEBUG_CtpTableStatus = GSW_Debug_CtpTableStatus; @@ -21197,9 +26499,19 @@ static void gsw_init_fn_ptrs(struct core_ops *ops) ops->gsw_debug_ops.DEBUG_Def_PceBypQmap = GSW_Debug_PceBypassTable; ops->gsw_debug_ops.DEBUG_GetLpStatistics = GSW_Debug_GetLpStatistics; ops->gsw_debug_ops.DEBUG_GetCtpStatistics = GSW_Debug_GetCtpStatistics; - ops->gsw_debug_ops.Xgmac = GSW_XgmacCfg; - ops->gsw_debug_ops.Gswss = GSW_GswssCfg; - ops->gsw_debug_ops.Lmac = GSW_LmacCfg; - + ops->gsw_debug_ops.Xgmac = GSW_XgmacCfg; + ops->gsw_debug_ops.Gswss = GSW_GswssCfg; + ops->gsw_debug_ops.Lmac = GSW_LmacCfg; + ops->gsw_debug_ops.DEBUG_PrintPceIrqList = GSW_Debug_PrintPceIrqList; + ops->gsw_debug_ops.Macsec = GSW_MacsecCfg; + ops->gsw_debug_ops.DEBUG_RMON_Port_Get = GSW_Debug_RMON_Port_Get; + ops->gsw_debug_ops.DumpMem = GSW_DumpTable; + + /*IRQ Operation*/ + ops->gsw_irq_ops.IRQ_Register = GSW_Irq_register; + ops->gsw_irq_ops.IRQ_UnRegister = GSW_Irq_unregister; + ops->gsw_irq_ops.IRQ_Enable = GSW_Irq_enable; + ops->gsw_irq_ops.IRQ_Disable = GSW_Irq_disable; + } diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.h b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.h index 6660486601fc187dec424d44bbac2eb4c40162b5..a798795ab835c26362b53fad61c7df5dc0d5b319 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_core.h @@ -13,22 +13,27 @@ #ifndef _LTQ_FLOW_CORE_H_ #define _LTQ_FLOW_CORE_H_ + +#ifdef __KERNEL__ #include <net/switch_api/gsw_flow_ops.h> +#else +#include <gsw_flow_ops.h> +#endif #define PCE_ASSERT(t) if ((t)) { \ - printk("%s:%s:%d (" # t ")\n", __FILE__, __func__, __LINE__); \ - return -1; } + printk("%s:%s:%d (" # t ")\n", __FILE__, __func__, __LINE__); \ + return -1; } #ifndef GSW_RETURN_PCE - #define GSW_RETURN_PCE \ - { \ - printk("ERROR:\n\tFile %s\n\tLine %d\n", __FILE__, __LINE__); \ - return -1; \ - } +#define GSW_RETURN_PCE \ + { \ + printk("ERROR:\n\tFile %s\n\tLine %d\n", __FILE__, __LINE__); \ + return -1; \ + } #endif -/* Below are two macros -For FILL_CTRL_REG make sure init 'outVal' to zeor before filling +/* Below are two macros +For FILL_CTRL_REG make sure init 'outVal' to zeor before filling Where as CLEAR_FILL_CTRL_REG takes care of clear then fill. */ //Set the value at given offset. @@ -37,7 +42,7 @@ Where as CLEAR_FILL_CTRL_REG takes care of clear then fill. //Clear first then set value at given offset. #define CLEAR_FILL_CTRL_REG(outVal, shift, size, inVal) \ outVal = ((outVal & (~(((1 << size)-1) << shift))) |\ - ((inVal & ((1 << size)-1)) << shift)) + ((inVal & ((1 << size)-1)) << shift)) //Get the value at given offset. #define GET_VAL_FROM_REG(outVal, shift, size, inVal) \ outVal = ((inVal >> shift) & ((1 << size)-1)) @@ -51,35 +56,54 @@ Where as CLEAR_FILL_CTRL_REG takes care of clear then fill. #define RETURN_FROM_FUNCTION 1 #define CHECK_BUSY(reg, shift, size, action) ({ \ -int retCode = GSW_statusOk; \ -do{ \ - u32 busyRetry=MAX_BUSY_RETRY, value=0; \ - do{ \ - gsw_r32(cdev, reg, shift, size, &value); \ - }while (value && --busyRetry); \ - if(value && !busyRetry) \ - { \ - pr_err("ERROR: Hardware busy for too long\n"); \ - pr_err("%s %s %d (Register=0x%x)\n",__FILE__, __func__, __LINE__,reg);\ - if(RETURN_FROM_FUNCTION == action) \ - return GSW_statusErr; \ - retCode = GSW_statusErr; \ - } \ -}while(0); \ -retCode; \ -}) \ + int retCode = GSW_statusOk; \ + do{ \ + u32 busyRetry=MAX_BUSY_RETRY, value=0; \ + do{ \ + gsw_r32(cdev, reg, shift, size, &value); \ + }while (value && --busyRetry); \ + if(value && !busyRetry) \ + { \ + pr_err("ERROR: Hardware busy for too long\n"); \ + pr_err("%s %s %d (Register=0x%x)\n",__FILE__, __func__, __LINE__,reg);\ + if(RETURN_FROM_FUNCTION == action) \ + return GSW_statusErr; \ + retCode = GSW_statusErr; \ + } \ + }while(0); \ + retCode; \ + }) \ + +#ifdef __KERNEL__ + +#define CHECK_BUSY_MDIO(reg, shift, size, action) ({ \ + int retCode = GSW_statusOk; \ + do{ \ + u32 value=0; \ + do{ \ + udelay(1); \ + gsw_r32(cdev, reg, shift, size, &value); \ + }while (value); \ + }while(0); \ + retCode; \ + }) \ + +#endif + +#if defined(WIN_PC_MODE) && WIN_PC_MODE #define CHECK_BUSY_MDIO(reg, shift, size, action) ({ \ -int retCode = GSW_statusOk; \ -do{ \ - u32 value=0; \ - do{ \ - udelay(1); \ - gsw_r32(cdev, reg, shift, size, &value); \ - }while (value); \ -}while(0); \ -retCode; \ -}) \ + int retCode = GSW_statusOk; \ + do{ \ + u32 value=0; \ + do{ \ + gsw_r32(cdev, reg, shift, size, &value); \ + }while (value); \ + }while(0); \ + retCode; \ + }) \ + +#endif #define PORT_STATE_LISTENING 0 @@ -98,13 +122,15 @@ retCode; \ #define VLAN_FILTER_TABLE_SIZE 1024 #define BRDG_CONF_TABLE_SIZE 64 #define CTP_PORTCONF_TABLE_SIZE 288 -#define BRDG_PORTCONF_TABLE_SIZE 128 +#define BRDG_PORTCONF_TABLE_SIZE 128 #define METER_TABLE_SIZE 128 #define SHAPER_TABLE_SIZE 32 #define PMAPPER_TABLE_SIZE 32 #define CLEAR_U16(var) var &= ((u16)~(0xFFFF)) /*-------------------------------------*/ +#define PCE_INNER_PCP_DFL_ENTRIES 8 +#define PCE_INNER_PCP_MAX_ENTRIES 16 #define VLAN_ACTIVE_TABLE_SIZE 64 /* #define MAC_TABLE_SIZE 2048 */ @@ -146,6 +172,14 @@ retCode; \ #define LTQ_GSWIP_3_0 0x030 #define LTQ_GSWIP_3_1 0x031 +#define IS_VRSN_30_31(ver) \ + ((ver == LTQ_GSWIP_3_0) || (ver == LTQ_GSWIP_3_1)) + +#define IS_VRSN_31(ver) \ + ((ver == LTQ_GSWIP_3_1)) + +#define IS_VRSN_NOT_31(ver) \ + ((ver != LTQ_GSWIP_3_1)) /*PHY Reg 0x4 */ #define PHY_AN_ADV_10HDX 0x20 @@ -398,14 +432,6 @@ typedef struct { u16 val_0; } pce_uc_row_t; -typedef struct { - u16 val[8]; - u16 ptaddr; - u16 ptcaddr; - u16 op_mode; - u16 pmacId; -/* u16 valid:1; */ -} pmtbl_prog_t; typedef enum { /** Parser microcode table */ @@ -493,100 +519,6 @@ typedef enum { LTQ_FLOW_DEV_MAX } gsw_devtype_t; -typedef enum { - CTP_PORT_RX_RMON = 0x00, - CTP_PORT_TX_RMON = 0x01, - BRIDGE_PORT_RX_RMON = 0x02, - BRIDGE_PORT_TX_RMON = 0x03, - CTP_PORT_PCE_BYPASS_TX_RMON = 0x04, - FLOW_RX_RMON = 0x05, - FLOW_TX_RMON = 0x06, - WFQ_PARAM = 0x08, - PQM_THRESHOLD = 0x09, - PQM_PACKET_PTR = 0x0A, - SSL_NEXT_PTR_MEM = 0x0B, - SSL_HEADER_DES_MEM1 = 0x0C, - SSL_HEADER_DES_MEM2 = 0x0D, - BUF_MGR_Q_MAP_TABLE = 0x0E, - METER_RMON_COUNTER = 0x19, - ROUTING_RMON_COUNTER = 0x1B, - PMAC_RMON_COUNTER = 0x1C, -} BM_Table_ID; - -typedef union { -u16 raw; -#if CONFIG_CPU_BIG_ENDIAN -//MIPS - struct { u16 b15:1,b14:1,b13:1,b12:1,b11:1,b10:1,b9:1,b8:1, - b7:1,b6:1,b5:1,b4:1,b3:1,b2:1,b1:1,b0:1;} bits; - struct { u16 portOffset:10, counterOffset:6; } rmon; - struct { u16 nQueueId:6, reserved0:10; } wfq; - struct { u16 reserved1:7, nQueueId:6,mode:1, color_or_submode:2; } pqmThr; - struct { u16 reserved2:5,ptr:11; } pqmPtr; - struct { u16 reserved3:6,ptr:10; } ssl; - struct { u16 reserved4:10,nQueueId:6; } qMapTbl; - struct { u16 reserved6:6, color:2, reserved5:1, meterNo:7; } meterRmon; - struct { u16 reserved7:8, counterType:4,portNo:4 ; } routingRmon; - struct { u16 reserved8:5,pmacNo:3,count:3,channel_or_port:5; } pmacRmon; -#else - //x86 - struct { u16 b0:1,b1:1,b2:1,b3:1,b4:1,b5:1,b6:1,b7:1, - b8:1,b9:1,b10:1,b11:1,b12:1,b13:1,b14:1,b15:1; } bits; - struct { u16 counterOffset:6, portOffset:10; } rmon; - struct { u16 nQueueId:6, reserved0:10; } wfq; - struct { u16 color_or_submode:2, mode:1, nQueueId:6, reserved1:7; } pqmThr; - struct { u16 ptr:11, reserved2:5; } pqmPtr; - struct { u16 ptr:10,reserved3:6; } ssl; - struct { u16 nQueueId:6,reserved4:10; } qMapTbl; - struct { u16 meterNo:7,reserved5:1, color:2, reserved6:6; } meterRmon; - struct { u16 portNo:4,counterType:4, reserved7:8; } routingRmon; - struct { u16 channel_or_port:5,count:3, pmacNo:3, reserved8:5; } pmacRmon; -#endif -} BM_Table_Address ; - - -typedef struct { - BM_Table_ID tableID; - BM_Table_Address adr; - u32 value[10]; - ltq_bool_t b64bitMode; - u32 numValues; -} bmtbl_prog_t; - - -/*GSWIP 3.0*/ -#if 0 -typedef struct { - u16 key[21]; - u16 mask[4]; - u16 val[25]; - u16 table; - u16 pcindex; - u16 op_mode:2; - u16 extop:1; - u16 kformat:1; - u16 type:1; - u16 valid:1; - u16 group:4; -} pctbl_prog_t; -#endif - -typedef struct { - u16 key[22]; - u16 mask[4]; - u16 val[25]; - u16 table; - u16 pcindex; - u16 op_mode:2; - u16 extop:1; - u16 kformat:1; - u16 type:1; - u16 valid:1; - u16 group:4; -} pctbl_prog_t; - - - typedef struct { u16 pkg_lng; u16 pkg_lng_rng; @@ -617,8 +549,8 @@ typedef struct { typedef struct { u16 payload_data; u16 mask_range; - u8 mask_range_type:1; - u8 valid:1; + u8 mask_range_type: 1; + u8 valid: 1; } payload_tbl_t; /* IP DA/SA MSB Table */ @@ -649,31 +581,31 @@ typedef struct { } pce_ppoe_tbl_t; typedef struct { - u16 pkt_lng_idx:8; - u16 dst_mac_addr_idx:8; - u16 src_mac_addr_idx:8; - u16 dst_appl_fld_idx:8; - u16 src_appl_fld_idx:8; - u16 dip_msb_idx:8; - u16 dip_lsb_idx:8; - u16 sip_msb_idx:8; - u16 sip_lsb_idx:8; - u16 inr_dip_msb_idx:8; - u16 inr_dip_lsb_idx:8; - u16 inr_sip_msb_idx:8; - u16 inr_sip_lsb_idx:8; - u16 ip_prot_idx:8; - u16 ethertype_idx:8; - u16 pppoe_idx:8; - u16 vlan_idx:8; - u16 svlan_idx:8; - u16 payload1_idx:8; - u16 payload2_idx:8; - u16 ppp_prot_idx:8; - u16 parse_lsb_idx:8; - u16 parse_msb_idx:8; - u16 parse1_lsb_idx:8; - u16 parse1_msb_idx:8; + u16 pkt_lng_idx: 8; + u16 dst_mac_addr_idx: 8; + u16 src_mac_addr_idx: 8; + u16 dst_appl_fld_idx: 8; + u16 src_appl_fld_idx: 8; + u16 dip_msb_idx: 8; + u16 dip_lsb_idx: 8; + u16 sip_msb_idx: 8; + u16 sip_lsb_idx: 8; + u16 inr_dip_msb_idx: 8; + u16 inr_dip_lsb_idx: 8; + u16 inr_sip_msb_idx: 8; + u16 inr_sip_lsb_idx: 8; + u16 ip_prot_idx: 8; + u16 ethertype_idx: 8; + u16 pppoe_idx: 8; + u16 vlan_idx: 8; + u16 svlan_idx: 8; + u16 payload1_idx: 8; + u16 payload2_idx: 8; + u16 ppp_prot_idx: 8; + u16 parse_lsb_idx: 8; + u16 parse_msb_idx: 8; + u16 parse1_lsb_idx: 8; + u16 parse1_msb_idx: 8; } pce_table_t; typedef struct { @@ -728,9 +660,9 @@ typedef struct { /* Port Enable */ ltq_bool_t penable; /* Learning Limit Action */ -/* ltq_bool_t laction; */ + /* ltq_bool_t laction; */ /* Automatic MAC address table learning locking */ -/* ltq_bool_t lplock; */ + /* ltq_bool_t lplock; */ /* Automatic MAC address table learning limitation */ u16 llimit; /* Port State */ @@ -853,9 +785,9 @@ typedef struct { u16 EgressVlanFilter1BlkId; u8 EgressVlanFilter2Assigned; u16 EgressVlanFilter2BlkId; - GSW_STP_PortState_t StpState; - GSW_8021X_portState_t P8021xState; - u16 LearningLimit; + GSW_STP_PortState_t StpState; + GSW_8021X_portState_t P8021xState; + u16 LearningLimit; } gsw_brdgportconfig_t; typedef struct { @@ -926,7 +858,24 @@ typedef struct { const u32 *value; } gsw_pce_tbl_reg_t; - +/*Switch IRQ related structures*/ +typedef struct gsw_pce_irq gsw_pce_irq; +struct gsw_pce_irq { + gsw_pce_irq *pNext; + char Port_ier_enabled; + unsigned short P_IER_MASK; + char Event_ier_enable; + unsigned short E_IER_MASK; + unsigned short P_ISR_MASK; + unsigned short E_ISR_MASK; + void *call_back; + void *param; +} ; + +struct pce_irq_linklist { + gsw_pce_irq *first_ptr; + gsw_pce_irq *last_ptr; +}; typedef struct { gsw_devtype_t sdev; @@ -959,7 +908,7 @@ typedef struct { u8 msw_rinx; u8 cport; u8 gsw_dev; - + u16 mrtpcnt; /* multicast router port count */ u16 meter_cnt; u16 num_of_queues; /* Number of priority queues . */ @@ -993,33 +942,53 @@ typedef struct { u16 num_of_ctp; /*Number of CTP port - Applicable for 3.1 */ u16 num_of_extendvlan; /*Number of extended VLAN tagging operation index in table - Applicable for 3.1 */ u16 num_of_vlanfilter; /*Number of VLAN Filter index in table - Applicable for 3.1 */ - u16 num_of_pmapper; /*Number of pmapper index in table - Applicable for 3.1 + u16 num_of_pmapper; /*Number of pmapper index in table - Applicable for 3.1 p-mapper total entry 2336/73=32 number of index (i.e) each pmapper idx has 73 entries*/ u16 mcsthw_snoop; /*Multicast HW snooping feature */ + + u16 gipver; void *gswl_base; /*Base address GSWIP-L */ void *gswr_base; /*Base address GSWIP-R */ void *gsw_base; /*Base address GSWITCH */ +#ifdef __KERNEL__ + spinlock_t lock_pce; + spinlock_t lock_bm; + spinlock_t lock_pmac; + spinlock_t lock_misc; + spinlock_t lock_pae; + spinlock_t lock_alloc; + spinlock_t lock_free; + spinlock_t lock_irq; + spinlock_t lock_mdio; + spinlock_t lock_mmd; + struct tasklet_struct gswip_tasklet; +#endif + u16 num_of_pce_tbl; const gsw_pce_tbl_info_t *pce_tbl_info; gsw_pce_tbl_reg_t pce_tbl_reg; - + /*IRQ*/ + struct pce_irq_linklist *PceIrqList; + u32 irq_num; /**Switch Opertations**/ struct core_ops ops; } ethsw_api_dev_t; + + u8 find_active_vlan_index(void *cdev, u16 vid); int find_msb_tbl_entry(pcetbl_prog_t *ptbl, - pce_dasa_msb_t *parm); + pce_dasa_msb_t *parm); int pce_dasa_msb_tbl_write(void *cdev, pcetbl_prog_t *ptbl, - pce_dasa_msb_t *parm); + pce_dasa_msb_t *parm); int find_dasa_tbl_entry(pcetbl_prog_t *ptbl, - pce_dasa_lsb_t *parm); + pce_dasa_lsb_t *parm); int pce_dasa_lsb_tbl_write(void *cdev, pcetbl_prog_t *ptbl, - pce_dasa_lsb_t *parm); + pce_dasa_lsb_t *parm); int pce_table_init(ltq_pce_table_t *pchndl); int ip_dasa_msb_tbl_del(void *cdev, pcetbl_prog_t *ptbl, u32 index); int ip_dasa_lsb_tbl_del(void *cdev, pcetbl_prog_t *ptbl, u32 index); @@ -1029,11 +998,9 @@ int pce_pattern_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index); int ipdslsb_tblidx_del(pcetbl_prog_t *ptbl, u32 index); int pce_action_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index); int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, - GSW_PCE_rule_t *parm); + GSW_PCE_rule_t *parm); int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, - GSW_PCE_rule_t *parm); -int gsw_pce_table_write(void *cdev, pctbl_prog_t *ptdata); -int gsw_pce_table_read(void *cdev, pctbl_prog_t *ptdata); + GSW_PCE_rule_t *parm); int gsw_pce_table_key_write(void *cdev, pctbl_prog_t *ptdata); int gsw_pce_table_key_read(void *cdev, pctbl_prog_t *ptdata); diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_pce.c b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_pce.c index b64e6e81e9f003294d3736e9733005b5fcf0cb3f..b9d3669edee170977ec8a841b1dc6a07b096de65 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_flow_pce.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_flow_pce.c @@ -11,528 +11,528 @@ -#include "gsw_init.h" +#include <gsw_init.h> #define PCE_MC_M3(val, msk, ns, out, len, type, flags, ipv4_len) \ - { val, msk, (ns << 8 | out << 0),\ - (len | type << 5 | flags << 8 | ipv4_len << 7)} + { val, msk, (ns << 8 | out << 0),\ + (len | type << 5 | flags << 8 | ipv4_len << 7)} const PCE_MICROCODE pce_mc_max_ifx_tag_m_31 = {/* V31_01 */ - PCE_MC_M3(0x88C3 , 0xFFFF , 1 , OUT_ITAG0 , 4 , INSTR , FLAG_ITAG , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 4 , OUT_1VTAG0 , 2 , INSTR , FLAG_1VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 4 , OUT_1VTAG0 , 2 , INSTR , FLAG_1VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 12 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 7 , OUT_2VTAG0 , 2 , INSTR , FLAG_2VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 7 , OUT_2VTAG0 , 2 , INSTR , FLAG_2VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 12 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 10 , OUT_3VTAG0 , 2 , INSTR , FLAG_3VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 10 , OUT_3VTAG0 , 2 , INSTR , FLAG_3VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 12 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 10 , OUT_NONE , 2 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 10 , OUT_NONE , 2 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0000 , 0xF800 , 14 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 20 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0x0600 , 20 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 16 , OUT_ETYPE , 1 , INSTR , FLAG_LEN , 0), - PCE_MC_M3(0xAAAA , 0xFFFF , 18 , OUT_APP0 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 80 , OUT_APP0 , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0300 , 0xFF00 , 20 , OUT_APP1 , 2 , INSTR , FLAG_SNAP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 80 , OUT_APP1 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8864 , 0xFFFF , 25 , OUT_ETYPE , 4 , INSTR , FLAG_PPPOES , 0), - PCE_MC_M3(0x0800 , 0xFFFF , 28 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x86DD , 0xFFFF , 35 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x888E , 0xFFFF , 79 , OUT_ETYPE , 1 , INSTR , FLAG_EAPOL , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0021 , 0xFFFF , 28 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0057 , 0xFFFF , 35 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 29 , OUT_1IP0 , 4 , INSTR , FLAG_1IPV4 , 1), - PCE_MC_M3(0x0011 , 0x00FF , 77 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0006 , 0x00FF , 74 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0002 , 0x00FF , 78 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0029 , 0x00FF , 59 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0004 , 0x00FF , 54 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 36 , OUT_1IP0 , 3 , INSTR , FLAG_1IPV6 , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 77 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 74 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0400 , 0xFF00 , 54 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2900 , 0xFF00 , 59 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 44 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 44 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 44 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x00F8 , 46 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 44 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 44 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 44 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 77 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 74 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0400 , 0xFF00 , 54 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x2900 , 0xFF00 , 59 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 55 , OUT_2IP0 , 4 , INSTR , FLAG_2IPV4 , 1), - PCE_MC_M3(0x0011 , 0x00FF , 77 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0006 , 0x00FF , 74 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0002 , 0x00FF , 78 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 60 , OUT_2IP0 , 3 , INSTR , FLAG_2IPV6 , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 77 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 74 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 66 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 66 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 66 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x00F8 , 68 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 66 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 66 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 66 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 77 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 74 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 79 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 75 , OUT_APP0 , 6 , INSTR , FLAG_TCP , 0), - PCE_MC_M3(0x0010 , 0x0010 , 80 , OUT_APP6 , 4 , INSTR , FLAG_TCPACK , 0), - PCE_MC_M3(0x0000 , 0x0010 , 80 , OUT_APP6 , 4 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 80 , OUT_APP0 , 4 , INSTR , FLAG_1UDP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 80 , OUT_APP0 , 4 , INSTR , FLAG_IGMP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 80 , OUT_APP0 , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 81 , OUT_1PL , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_2PL , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 82 , OUT_NONE , 0 , INSTR , FLAG_END , 0), + PCE_MC_M3(0x88C3, 0xFFFF, 1, OUT_ITAG0, 4, INSTR, FLAG_ITAG, 0), + PCE_MC_M3(0x8100, 0xFFFF, 4, OUT_1VTAG0, 2, INSTR, FLAG_1VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 4, OUT_1VTAG0, 2, INSTR, FLAG_1VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 12, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 7, OUT_2VTAG0, 2, INSTR, FLAG_2VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 7, OUT_2VTAG0, 2, INSTR, FLAG_2VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 12, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 10, OUT_3VTAG0, 2, INSTR, FLAG_3VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 10, OUT_3VTAG0, 2, INSTR, FLAG_3VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 12, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 10, OUT_NONE, 2, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 10, OUT_NONE, 2, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0000, 0xF800, 14, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 20, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0x0600, 20, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 16, OUT_ETYPE, 1, INSTR, FLAG_LEN, 0), + PCE_MC_M3(0xAAAA, 0xFFFF, 18, OUT_APP0, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 80, OUT_APP0, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0300, 0xFF00, 20, OUT_APP1, 2, INSTR, FLAG_SNAP, 0), + PCE_MC_M3(0x0000, 0x0000, 80, OUT_APP1, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8864, 0xFFFF, 25, OUT_ETYPE, 4, INSTR, FLAG_PPPOES, 0), + PCE_MC_M3(0x0800, 0xFFFF, 28, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x86DD, 0xFFFF, 35, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x888E, 0xFFFF, 79, OUT_ETYPE, 1, INSTR, FLAG_EAPOL, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0021, 0xFFFF, 28, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0057, 0xFFFF, 35, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 29, OUT_1IP0, 4, INSTR, FLAG_1IPV4, 1), + PCE_MC_M3(0x0011, 0x00FF, 77, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0006, 0x00FF, 74, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0002, 0x00FF, 78, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0029, 0x00FF, 59, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0004, 0x00FF, 54, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 36, OUT_1IP0, 3, INSTR, FLAG_1IPV6, 0), + PCE_MC_M3(0x1100, 0xFF00, 77, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0xFF00, 74, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0400, 0xFF00, 54, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2900, 0xFF00, 59, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 44, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2B00, 0xFF00, 44, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x3C00, 0xFF00, 44, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x00F8, 46, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 44, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x2B00, 0xFF00, 44, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x3C00, 0xFF00, 44, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x1100, 0xFF00, 77, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0600, 0xFF00, 74, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0400, 0xFF00, 54, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x2900, 0xFF00, 59, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 55, OUT_2IP0, 4, INSTR, FLAG_2IPV4, 1), + PCE_MC_M3(0x0011, 0x00FF, 77, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0006, 0x00FF, 74, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0002, 0x00FF, 78, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 60, OUT_2IP0, 3, INSTR, FLAG_2IPV6, 0), + PCE_MC_M3(0x1100, 0xFF00, 77, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0xFF00, 74, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 66, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2B00, 0xFF00, 66, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x3C00, 0xFF00, 66, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x00F8, 68, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 66, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x2B00, 0xFF00, 66, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x3C00, 0xFF00, 66, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x1100, 0xFF00, 77, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0600, 0xFF00, 74, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 79, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 75, OUT_APP0, 6, INSTR, FLAG_TCP, 0), + PCE_MC_M3(0x0010, 0x0010, 80, OUT_APP6, 4, INSTR, FLAG_TCPACK, 0), + PCE_MC_M3(0x0000, 0x0010, 80, OUT_APP6, 4, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 80, OUT_APP0, 4, INSTR, FLAG_1UDP, 0), + PCE_MC_M3(0x0000, 0x0000, 80, OUT_APP0, 4, INSTR, FLAG_IGMP, 0), + PCE_MC_M3(0x0000, 0x0000, 80, OUT_APP0, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 81, OUT_1PL, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_2PL, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 82, OUT_NONE, 0, INSTR, FLAG_END, 0), }; const PCE_MICROCODE pce_mc_max_ifx_tag_m_30 = {/* V30_13 */ - PCE_MC_M3(0x88C3 , 0xFFFF , 1 , OUT_ITAG0 , 4 , INSTR , FLAG_ITAG , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 4 , OUT_1VTAG0 , 2 , INSTR , FLAG_1VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 4 , OUT_1VTAG0 , 2 , INSTR , FLAG_1VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 15 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 7 , OUT_2VTAG0 , 2 , INSTR , FLAG_2VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 7 , OUT_2VTAG0 , 2 , INSTR , FLAG_2VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 15 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 10 , OUT_3VTAG0 , 2 , INSTR , FLAG_3VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 10 , OUT_3VTAG0 , 2 , INSTR , FLAG_3VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 15 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 13 , OUT_4VTAG0 , 2 , INSTR , FLAG_4VLAN , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 13 , OUT_4VTAG0 , 2 , INSTR , FLAG_4VLAN , 0), - PCE_MC_M3(0x0000 , 0x0000 , 15 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 13 , OUT_NONE , 2 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x88A8 , 0xFFFF , 13 , OUT_NONE , 2 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0000 , 0xF800 , 17 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 23 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0x0600 , 23 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 19 , OUT_ETYPE , 1 , INSTR , FLAG_LEN , 0), - PCE_MC_M3(0xAAAA , 0xFFFF , 21 , OUT_APP0 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP0 , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0300 , 0xFF00 , 23 , OUT_APP1 , 2 , INSTR , FLAG_SNAP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP1 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8864 , 0xFFFF , 28 , OUT_ETYPE , 4 , INSTR , FLAG_PPPOES , 0), - PCE_MC_M3(0x0800 , 0xFFFF , 31 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x86DD , 0xFFFF , 54 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x888E , 0xFFFF , 180 , OUT_ETYPE , 1 , INSTR , FLAG_EAPOL , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_ETYPE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0021 , 0xFFFF , 31 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0057 , 0xFFFF , 54 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_PPP , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x4000 , 0xF000 , 33 , OUT_NONE , 0 , INSTR , FLAG_1IPV4 , 1), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0500 , 0x0F00 , 36 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 35 , OUT_NONE , 0 , INSTR , FLAG_IPV4OPT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 36 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0003 , 0x0003 , 38 , OUT_1IP0 , 3 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 38 , OUT_1IP0 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x3FFF , 40 , OUT_1IP3 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 40 , OUT_1IP3 , 1 , INSTR , FLAG_IPFRAG , 0), - PCE_MC_M3(0x0000 , 0xFE00 , 41 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0011 , 0x00FF , 118 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0006 , 0x00FF , 106 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0002 , 0x00FF , 123 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0029 , 0x00FF , 90 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0004 , 0x00FF , 80 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x002F , 0x00FF , 140 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0032 , 0x00FF , 49 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_1IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 50 , OUT_APP0 , 4 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x4000 , 0xF000 , 52 , OUT_NONE , 6 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 53 , OUT_NONE , 10 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_1PL , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_1PL , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x6000 , 0xF000 , 56 , OUT_NONE , 0 , INSTR , FLAG_1IPV6 , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0030 , 0x0030 , 58 , OUT_1IP0 , 3 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 58 , OUT_1IP0 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x00FE , 59 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 118 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 106 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 62 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0400 , 0xFF00 , 80 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2900 , 0xFF00 , 90 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2F00 , 0xFF00 , 140 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x3200 , 0xFF00 , 49 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 70 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 70 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 70 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_1IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x00F8 , 72 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 70 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 70 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 70 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 118 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 106 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0400 , 0xFF00 , 80 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x2900 , 0xFF00 , 90 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_1LNH , 1 , IPV6 , FLAG_1IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 81 , OUT_NONE , 0 , INSTR , FLAG_2IPV4 , 1), - PCE_MC_M3(0x0500 , 0x0F00 , 83 , OUT_2IP0 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 84 , OUT_2IP0 , 3 , INSTR , FLAG_IPV4OPT , 0), - PCE_MC_M3(0x0000 , 0x3FFF , 85 , OUT_2IP3 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 85 , OUT_2IP3 , 1 , INSTR , FLAG_IPFRAG , 0), - PCE_MC_M3(0x0000 , 0xFE00 , 86 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0011 , 0x00FF , 122 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0006 , 0x00FF , 106 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0002 , 0x00FF , 123 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 91 , OUT_2IP0 , 3 , INSTR , FLAG_2IPV6 , 0), - PCE_MC_M3(0x0000 , 0x00FE , 92 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 122 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 106 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 98 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 98 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 98 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x00F8 , 100 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0xFF00 , 98 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x2B00 , 0xFF00 , 98 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x3C00 , 0xFF00 , 98 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 122 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 106 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_2LNH , 1 , IPV6 , FLAG_2IPV6EXT , 0), - PCE_MC_M3(0x0000 , 0x0000 , 107 , OUT_APP0 , 6 , INSTR , FLAG_TCP , 0), - PCE_MC_M3(0x0040 , 0x0040 , 108 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0080 , 0x0080 , 109 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0020 , 0x0020 , 110 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0008 , 0x0008 , 111 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0001 , 0x0001 , 112 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0001 , 0x0001 , 113 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0004 , 0x0004 , 114 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0004 , 0x0004 , 115 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0002 , 0x0002 , 116 , OUT_NONE , 0 , INSTR , FLAG_LROEXP , 0), - PCE_MC_M3(0x0010 , 0x0010 , 183 , OUT_APP6 , 4 , INSTR , FLAG_TCPACK , 0), - PCE_MC_M3(0x0000 , 0x0010 , 183 , OUT_APP6 , 4 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 119 , OUT_APP0 , 1 , INSTR , FLAG_1UDP , 0), - PCE_MC_M3(0x06A5 , 0xFFFF , 124 , OUT_APP1 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x147F , 0xFFFF , 136 , OUT_APP1 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP1 , 3 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP0 , 4 , INSTR , FLAG_2UDP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP0 , 4 , INSTR , FLAG_IGMP , 0), - PCE_MC_M3(0x0000 , 0xCA00 , 131 , OUT_NONE , 3 , INSTR , FLAG_L2TP , 0), - PCE_MC_M3(0x4000 , 0xCA00 , 131 , OUT_NONE , 4 , INSTR , FLAG_L2TP , 0), - PCE_MC_M3(0x0200 , 0xCA00 , 129 , OUT_NONE , 3 , INSTR , FLAG_L2TP , 0), - PCE_MC_M3(0x4200 , 0xCA00 , 129 , OUT_NONE , 4 , INSTR , FLAG_L2TP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 0 , INSTR , FLAG_L2TP , 0), - PCE_MC_M3(0x0000 , 0xFFFF , 131 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0xFF03 , 0xFFFF , 133 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0021 , 0xFFFF , 80 , OUT_NONE , 1 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0057 , 0xFFFF , 90 , OUT_NONE , 1 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0010 , 0x00F8 , 138 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x01F8 , 181 , OUT_NONE , 0 , INSTR , FLAG_CAPWAP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x2000 , 0xFFFF , 143 , OUT_NONE , 1 , INSTR , FLAG_GREK , 0), - PCE_MC_M3(0x0000 , 0xFFFF , 161 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x6558 , 0xFFFF , 147 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x0800 , 0xFFFF , 159 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x86DD , 0xFFFF , 160 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 148 , OUT_1PL , 2 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 149 , OUT_NONE , 6 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 151 , OUT_NONE , 2 , INSTR , FLAG_GRE_VLAN1 , 0), - PCE_MC_M3(0x0000 , 0x0000 , 152 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x8100 , 0xFFFF , 152 , OUT_NONE , 2 , INSTR , FLAG_GRE_VLAN2 , 0), - PCE_MC_M3(0x8864 , 0xFFFF , 156 , OUT_NONE , 4 , INSTR , FLAG_GRE_PPPOE , 0), - PCE_MC_M3(0x0800 , 0xFFFF , 165 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x86DD , 0xFFFF , 174 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0021 , 0xFFFF , 165 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0057 , 0xFFFF , 174 , OUT_NONE , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 165 , OUT_1PL , 2 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 174 , OUT_1PL , 2 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x6558 , 0xFFFF , 148 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x0800 , 0xFFFF , 165 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x86DD , 0xFFFF , 174 , OUT_NONE , 1 , INSTR , FLAG_GRE , 0), - PCE_MC_M3(0x0000 , 0x0000 , 180 , OUT_NONE , 0 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 166 , OUT_NONE , 0 , INSTR , FLAG_2IPV4 , 1), - PCE_MC_M3(0x0500 , 0x0F00 , 168 , OUT_2IP0 , 3 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 169 , OUT_2IP0 , 3 , INSTR , FLAG_IPV4OPT , 0), - PCE_MC_M3(0x0000 , 0x3FFF , 170 , OUT_2IP3 , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 170 , OUT_2IP3 , 1 , INSTR , FLAG_IPFRAG , 0), - PCE_MC_M3(0x0000 , 0xFE00 , 171 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x0011 , 0x00FF , 179 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0006 , 0x00FF , 106 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_2IP4 , 6 , LENACCU , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 175 , OUT_2IP0 , 3 , INSTR , FLAG_2IPV6 , 0), - PCE_MC_M3(0x0000 , 0x00FE , 176 , OUT_NONE , 0 , INSTR , FLAG_ROUTEXP , 0), - PCE_MC_M3(0x1100 , 0xFF00 , 179 , OUT_2IP3 , 17 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0600 , 0xFF00 , 106 , OUT_2IP3 , 17 , INSTR , FLAG_L2TPNEXP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_2IP3 , 17 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_APP0 , 4 , INSTR , FLAG_2UDP , 0), - PCE_MC_M3(0x0000 , 0x0000 , 181 , OUT_APP0 , 2 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 182 , OUT_1PL , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_2PL , 1 , INSTR , FLAG_NO , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), - PCE_MC_M3(0x0000 , 0x0000 , 183 , OUT_NONE , 0 , INSTR , FLAG_END , 0), + PCE_MC_M3(0x88C3, 0xFFFF, 1, OUT_ITAG0, 4, INSTR, FLAG_ITAG, 0), + PCE_MC_M3(0x8100, 0xFFFF, 4, OUT_1VTAG0, 2, INSTR, FLAG_1VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 4, OUT_1VTAG0, 2, INSTR, FLAG_1VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 15, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 7, OUT_2VTAG0, 2, INSTR, FLAG_2VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 7, OUT_2VTAG0, 2, INSTR, FLAG_2VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 15, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 10, OUT_3VTAG0, 2, INSTR, FLAG_3VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 10, OUT_3VTAG0, 2, INSTR, FLAG_3VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 15, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 13, OUT_4VTAG0, 2, INSTR, FLAG_4VLAN, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 13, OUT_4VTAG0, 2, INSTR, FLAG_4VLAN, 0), + PCE_MC_M3(0x0000, 0x0000, 15, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 13, OUT_NONE, 2, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x88A8, 0xFFFF, 13, OUT_NONE, 2, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0000, 0xF800, 17, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 23, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0x0600, 23, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 19, OUT_ETYPE, 1, INSTR, FLAG_LEN, 0), + PCE_MC_M3(0xAAAA, 0xFFFF, 21, OUT_APP0, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP0, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0300, 0xFF00, 23, OUT_APP1, 2, INSTR, FLAG_SNAP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP1, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8864, 0xFFFF, 28, OUT_ETYPE, 4, INSTR, FLAG_PPPOES, 0), + PCE_MC_M3(0x0800, 0xFFFF, 31, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x86DD, 0xFFFF, 54, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x888E, 0xFFFF, 180, OUT_ETYPE, 1, INSTR, FLAG_EAPOL, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_ETYPE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0021, 0xFFFF, 31, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0057, 0xFFFF, 54, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_PPP, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x4000, 0xF000, 33, OUT_NONE, 0, INSTR, FLAG_1IPV4, 1), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0500, 0x0F00, 36, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 35, OUT_NONE, 0, INSTR, FLAG_IPV4OPT, 0), + PCE_MC_M3(0x0000, 0x0000, 36, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0003, 0x0003, 38, OUT_1IP0, 3, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 38, OUT_1IP0, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x3FFF, 40, OUT_1IP3, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 40, OUT_1IP3, 1, INSTR, FLAG_IPFRAG, 0), + PCE_MC_M3(0x0000, 0xFE00, 41, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0011, 0x00FF, 118, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0006, 0x00FF, 106, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0002, 0x00FF, 123, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0029, 0x00FF, 90, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0004, 0x00FF, 80, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x002F, 0x00FF, 140, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0032, 0x00FF, 49, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_1IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 50, OUT_APP0, 4, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x4000, 0xF000, 52, OUT_NONE, 6, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 53, OUT_NONE, 10, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_1PL, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_1PL, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x6000, 0xF000, 56, OUT_NONE, 0, INSTR, FLAG_1IPV6, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0030, 0x0030, 58, OUT_1IP0, 3, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 58, OUT_1IP0, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x00FE, 59, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x1100, 0xFF00, 118, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0xFF00, 106, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 62, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0400, 0xFF00, 80, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2900, 0xFF00, 90, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2F00, 0xFF00, 140, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x3200, 0xFF00, 49, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 70, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2B00, 0xFF00, 70, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x3C00, 0xFF00, 70, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_1IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x00F8, 72, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 70, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x2B00, 0xFF00, 70, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x3C00, 0xFF00, 70, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x1100, 0xFF00, 118, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0600, 0xFF00, 106, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0400, 0xFF00, 80, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x2900, 0xFF00, 90, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_1LNH, 1, IPV6, FLAG_1IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 81, OUT_NONE, 0, INSTR, FLAG_2IPV4, 1), + PCE_MC_M3(0x0500, 0x0F00, 83, OUT_2IP0, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 84, OUT_2IP0, 3, INSTR, FLAG_IPV4OPT, 0), + PCE_MC_M3(0x0000, 0x3FFF, 85, OUT_2IP3, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 85, OUT_2IP3, 1, INSTR, FLAG_IPFRAG, 0), + PCE_MC_M3(0x0000, 0xFE00, 86, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0011, 0x00FF, 122, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0006, 0x00FF, 106, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0002, 0x00FF, 123, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 91, OUT_2IP0, 3, INSTR, FLAG_2IPV6, 0), + PCE_MC_M3(0x0000, 0x00FE, 92, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x1100, 0xFF00, 122, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0600, 0xFF00, 106, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 98, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2B00, 0xFF00, 98, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x3C00, 0xFF00, 98, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x00F8, 100, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0xFF00, 98, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x2B00, 0xFF00, 98, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x3C00, 0xFF00, 98, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x1100, 0xFF00, 122, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0600, 0xFF00, 106, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_2LNH, 1, IPV6, FLAG_2IPV6EXT, 0), + PCE_MC_M3(0x0000, 0x0000, 107, OUT_APP0, 6, INSTR, FLAG_TCP, 0), + PCE_MC_M3(0x0040, 0x0040, 108, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0080, 0x0080, 109, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0020, 0x0020, 110, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0008, 0x0008, 111, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0001, 0x0001, 112, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0001, 0x0001, 113, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0004, 0x0004, 114, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0004, 0x0004, 115, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0002, 0x0002, 116, OUT_NONE, 0, INSTR, FLAG_LROEXP, 0), + PCE_MC_M3(0x0010, 0x0010, 183, OUT_APP6, 4, INSTR, FLAG_TCPACK, 0), + PCE_MC_M3(0x0000, 0x0010, 183, OUT_APP6, 4, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 119, OUT_APP0, 1, INSTR, FLAG_1UDP, 0), + PCE_MC_M3(0x06A5, 0xFFFF, 124, OUT_APP1, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x147F, 0xFFFF, 136, OUT_APP1, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP1, 3, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP0, 4, INSTR, FLAG_2UDP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP0, 4, INSTR, FLAG_IGMP, 0), + PCE_MC_M3(0x0000, 0xCA00, 131, OUT_NONE, 3, INSTR, FLAG_L2TP, 0), + PCE_MC_M3(0x4000, 0xCA00, 131, OUT_NONE, 4, INSTR, FLAG_L2TP, 0), + PCE_MC_M3(0x0200, 0xCA00, 129, OUT_NONE, 3, INSTR, FLAG_L2TP, 0), + PCE_MC_M3(0x4200, 0xCA00, 129, OUT_NONE, 4, INSTR, FLAG_L2TP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 0, INSTR, FLAG_L2TP, 0), + PCE_MC_M3(0x0000, 0xFFFF, 131, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0xFF03, 0xFFFF, 133, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0021, 0xFFFF, 80, OUT_NONE, 1, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0057, 0xFFFF, 90, OUT_NONE, 1, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0010, 0x00F8, 138, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x01F8, 181, OUT_NONE, 0, INSTR, FLAG_CAPWAP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x2000, 0xFFFF, 143, OUT_NONE, 1, INSTR, FLAG_GREK, 0), + PCE_MC_M3(0x0000, 0xFFFF, 161, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x6558, 0xFFFF, 147, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x0800, 0xFFFF, 159, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x86DD, 0xFFFF, 160, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 148, OUT_1PL, 2, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 149, OUT_NONE, 6, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 151, OUT_NONE, 2, INSTR, FLAG_GRE_VLAN1, 0), + PCE_MC_M3(0x0000, 0x0000, 152, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x8100, 0xFFFF, 152, OUT_NONE, 2, INSTR, FLAG_GRE_VLAN2, 0), + PCE_MC_M3(0x8864, 0xFFFF, 156, OUT_NONE, 4, INSTR, FLAG_GRE_PPPOE, 0), + PCE_MC_M3(0x0800, 0xFFFF, 165, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x86DD, 0xFFFF, 174, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0021, 0xFFFF, 165, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0057, 0xFFFF, 174, OUT_NONE, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 165, OUT_1PL, 2, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 174, OUT_1PL, 2, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x6558, 0xFFFF, 148, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x0800, 0xFFFF, 165, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x86DD, 0xFFFF, 174, OUT_NONE, 1, INSTR, FLAG_GRE, 0), + PCE_MC_M3(0x0000, 0x0000, 180, OUT_NONE, 0, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 166, OUT_NONE, 0, INSTR, FLAG_2IPV4, 1), + PCE_MC_M3(0x0500, 0x0F00, 168, OUT_2IP0, 3, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 169, OUT_2IP0, 3, INSTR, FLAG_IPV4OPT, 0), + PCE_MC_M3(0x0000, 0x3FFF, 170, OUT_2IP3, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 170, OUT_2IP3, 1, INSTR, FLAG_IPFRAG, 0), + PCE_MC_M3(0x0000, 0xFE00, 171, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x0011, 0x00FF, 179, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0006, 0x00FF, 106, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_2IP4, 6, LENACCU, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 175, OUT_2IP0, 3, INSTR, FLAG_2IPV6, 0), + PCE_MC_M3(0x0000, 0x00FE, 176, OUT_NONE, 0, INSTR, FLAG_ROUTEXP, 0), + PCE_MC_M3(0x1100, 0xFF00, 179, OUT_2IP3, 17, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0600, 0xFF00, 106, OUT_2IP3, 17, INSTR, FLAG_L2TPNEXP, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_2IP3, 17, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_APP0, 4, INSTR, FLAG_2UDP, 0), + PCE_MC_M3(0x0000, 0x0000, 181, OUT_APP0, 2, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 182, OUT_1PL, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_2PL, 1, INSTR, FLAG_NO, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), + PCE_MC_M3(0x0000, 0x0000, 183, OUT_NONE, 0, INSTR, FLAG_END, 0), }; @@ -613,6 +613,7 @@ const PCE_MICROCODE pce_mc_max_ifx_tag_m = { static int tbl_write(void *tstart, u16 *rcnt, void *parm, u32 tsize, u32 tnum) { int i; + /* search if the entry is already available and can be re-used */ for (i = 0; i < tnum; i++) { if (rcnt[i] > 0) { @@ -624,6 +625,7 @@ static int tbl_write(void *tstart, u16 *rcnt, void *parm, u32 tsize, u32 tnum) } } } + /* find an empty entry and add information */ for (i = 0; i < tnum; i++) { if (rcnt[i] == 0) { @@ -633,6 +635,7 @@ static int tbl_write(void *tstart, u16 *rcnt, void *parm, u32 tsize, u32 tnum) return i; } } + /* table is full, return an error */ pr_err("ERROR:\n\tFile %s\n\tLine %d\n", __FILE__, __LINE__); return -1; @@ -641,1254 +644,23 @@ static int tbl_write(void *tstart, u16 *rcnt, void *parm, u32 tsize, u32 tnum) static int tbl_idx_delete(u16 *rcnt, u32 index, u32 tsize) { PCE_ASSERT(index >= tsize); + if (rcnt[index] > 0) rcnt[index]--; - return GSW_statusOk; -} - -int gsw_pce_table_write(void *cdev, pctbl_prog_t *ptdata) -{ -#if 1 - u32 ctrlval; - u16 i, j; - //pr_err("Enter table write\n"); - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - gsw_w32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, ptdata->pcindex); - /*TABLE ADDRESS*/ - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_ADWR); - /*KEY REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_key; - if (ptdata->kformat) - j *= 4; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); - } - /*MASK REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_mask; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.mask[i], ptdata->mask[i]); - } - /*VAL REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_val; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.value[i], ptdata->val[i]); - } - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, - PCE_TBL_CTRL_KEYFORM_SIZE, ptdata->kformat); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, ptdata->type); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, ptdata->valid); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, ptdata->group); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); - //pr_err("Exit table write\n"); -#else - u32 value; - u16 udata; - - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value); - - /*INDEX:ENYRY ADDRESS*/ - value = ptdata->pcindex; - pr_err("PCE WRITE\n"); - pr_err("ptdata->pcindex =%d\n",ptdata->pcindex); - pr_err("ptdata->table =%d\n",ptdata->table); - // getchar(); - gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, - PCE_TBL_ADDR_ADDR_SHIFT, PCE_TBL_ADDR_ADDR_SIZE, value); - /*TABLE ADDRESS*/ - udata = ptdata->table; - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, - PCE_TBL_CTRL_ADDR_SHIFT, PCE_TBL_CTRL_ADDR_SIZE, udata); - value = PCE_OP_MODE_ADWR; - gsw_w32(cdev, PCE_TBL_CTRL_OPMOD_OFFSET, - PCE_TBL_CTRL_OPMOD_SHIFT, PCE_TBL_CTRL_OPMOD_SIZE, value); - - /*KEY REG*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_w32(cdev, PCE_TBL_KEY_21_KEY21_OFFSET, - PCE_TBL_KEY_21_KEY21_SHIFT, - PCE_TBL_KEY_21_KEY21_SIZE, ptdata->key[21]); - gsw_w32(cdev, PCE_TBL_KEY_20_KEY20_OFFSET, - PCE_TBL_KEY_20_KEY20_SHIFT, - PCE_TBL_KEY_20_KEY20_SIZE, ptdata->key[20]); - gsw_w32(cdev, PCE_TBL_KEY_19_KEY19_OFFSET, - PCE_TBL_KEY_19_KEY19_SHIFT, - PCE_TBL_KEY_19_KEY19_SIZE, ptdata->key[19]); - gsw_w32(cdev, PCE_TBL_KEY_18_KEY18_OFFSET, - PCE_TBL_KEY_18_KEY18_SHIFT, - PCE_TBL_KEY_18_KEY18_SIZE, ptdata->key[18]); - gsw_w32(cdev, PCE_TBL_KEY_17_KEY17_OFFSET, - PCE_TBL_KEY_17_KEY17_SHIFT, - PCE_TBL_KEY_17_KEY17_SIZE, ptdata->key[17]); - gsw_w32(cdev, PCE_TBL_KEY_16_KEY16_OFFSET, - PCE_TBL_KEY_16_KEY16_SHIFT, - PCE_TBL_KEY_16_KEY16_SIZE, ptdata->key[16]); - } - - gsw_w32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, ptdata->key[15]); - gsw_w32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, ptdata->key[14]); - gsw_w32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, ptdata->key[13]); - gsw_w32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, ptdata->key[12]); - gsw_w32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, ptdata->key[11]); - gsw_w32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, ptdata->key[10]); - gsw_w32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, ptdata->key[9]); - gsw_w32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, ptdata->key[8]); - gsw_w32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, ptdata->key[7]); - gsw_w32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, ptdata->key[6]); - gsw_w32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, ptdata->key[5]); - gsw_w32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, ptdata->key[4]); - gsw_w32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, ptdata->key[3]); - gsw_w32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, ptdata->key[2]); - gsw_w32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, ptdata->key[1]); - gsw_w32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, ptdata->key[0]); - - /*MASK REG*/ - gsw_w32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, ptdata->mask[0]); - gsw_w32(cdev, PCE_TBL_MASK_1_MASK1_OFFSET, - PCE_TBL_MASK_1_MASK1_SHIFT, - PCE_TBL_MASK_1_MASK1_SIZE, ptdata->mask[1]); - gsw_w32(cdev, PCE_TBL_MASK_2_MASK2_OFFSET, - PCE_TBL_MASK_2_MASK2_SHIFT, - PCE_TBL_MASK_2_MASK2_SIZE, ptdata->mask[2]); - gsw_w32(cdev, PCE_TBL_MASK_3_MASK3_OFFSET, - PCE_TBL_MASK_3_MASK3_SHIFT, - PCE_TBL_MASK_3_MASK3_SIZE, ptdata->mask[3]); - - /*VAL REG*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_w32(cdev, PCE_TBL_VAL_25_VAL25_OFFSET, - PCE_TBL_VAL_25_VAL25_SHIFT, - PCE_TBL_VAL_25_VAL25_SIZE, ptdata->val[25]); - gsw_w32(cdev, PCE_TBL_VAL_24_VAL24_OFFSET, - PCE_TBL_VAL_24_VAL24_SHIFT, - PCE_TBL_VAL_24_VAL24_SIZE, ptdata->val[24]); - gsw_w32(cdev, PCE_TBL_VAL_23_VAL23_OFFSET, - PCE_TBL_VAL_23_VAL23_SHIFT, - PCE_TBL_VAL_23_VAL23_SIZE, ptdata->val[23]); - gsw_w32(cdev, PCE_TBL_VAL_22_VAL22_OFFSET, - PCE_TBL_VAL_22_VAL22_SHIFT, - PCE_TBL_VAL_22_VAL22_SIZE, ptdata->val[21]); - gsw_w32(cdev, PCE_TBL_VAL_21_VAL21_OFFSET, - PCE_TBL_VAL_21_VAL21_SHIFT, - PCE_TBL_VAL_21_VAL21_SIZE, ptdata->val[21]); - gsw_w32(cdev, PCE_TBL_VAL_20_VAL20_OFFSET, - PCE_TBL_VAL_20_VAL20_SHIFT, - PCE_TBL_VAL_20_VAL20_SIZE, ptdata->val[20]); - gsw_w32(cdev, PCE_TBL_VAL_19_VAL19_OFFSET, - PCE_TBL_VAL_19_VAL19_SHIFT, - PCE_TBL_VAL_19_VAL19_SIZE, ptdata->val[19]); - gsw_w32(cdev, PCE_TBL_VAL_18_VAL18_OFFSET, - PCE_TBL_VAL_18_VAL18_SHIFT, - PCE_TBL_VAL_18_VAL18_SIZE, ptdata->val[18]); - gsw_w32(cdev, PCE_TBL_VAL_17_VAL17_OFFSET, - PCE_TBL_VAL_17_VAL17_SHIFT, - PCE_TBL_VAL_17_VAL17_SIZE, ptdata->val[17]); - gsw_w32(cdev, PCE_TBL_VAL_16_VAL16_OFFSET, - PCE_TBL_VAL_16_VAL16_SHIFT, - PCE_TBL_VAL_16_VAL16_SIZE, ptdata->val[16]); - } - - gsw_w32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, ptdata->val[15]); - gsw_w32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, ptdata->val[14]); - gsw_w32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, ptdata->val[13]); - gsw_w32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, ptdata->val[12]); - gsw_w32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, ptdata->val[11]); - gsw_w32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, ptdata->val[10]); - gsw_w32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, ptdata->val[9]); - gsw_w32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, ptdata->val[8]); - gsw_w32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, ptdata->val[7]); - gsw_w32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, ptdata->val[6]); - gsw_w32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, ptdata->val[5]); - gsw_w32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, ptdata->val[4]); - gsw_w32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, ptdata->val[3]); - gsw_w32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, ptdata->val[2]); - gsw_w32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, ptdata->val[1]); - gsw_w32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, ptdata->val[0]); - - value = ptdata->kformat; - gsw_w32(cdev, PCE_TBL_CTRL_KEYFORM_OFFSET, - PCE_TBL_CTRL_KEYFORM_SHIFT, - PCE_TBL_CTRL_KEYFORM_SIZE, value); - - value = ptdata->type; - gsw_w32(cdev, PCE_TBL_CTRL_TYPE_OFFSET, - PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, value); - - value = ptdata->valid; - gsw_w32(cdev, PCE_TBL_CTRL_VLD_OFFSET, - PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, value); - - value = ptdata->group; - gsw_w32(cdev, PCE_TBL_CTRL_GMAP_OFFSET, - PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, value); - - gsw_w32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); -/* gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, 0, 15, &value); */ -#endif - return GSW_statusOk; -} - -int gsw_pce_table_read(void *cdev, pctbl_prog_t *ptdata) -{ -#if 1 - u32 ctrlval, value; - u16 i, j; - //pr_err("Enter table read\n"); - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - gsw_w32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, ptdata->pcindex); - /*TABLE ADDRESS*/ - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_ADRD); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, - PCE_TBL_CTRL_KEYFORM_SIZE, ptdata->kformat); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - /*KEY REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_key; - if (ptdata->kformat) - j *= 4; - for (i=0; i<j; i++) { - gsw_r32_raw(cdev, gswdev->pce_tbl_reg.key[i], &value); - ptdata->key[i] = value; - } - /*MASK REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_mask; - for (i=0; i<j; i++) { - gsw_r32_raw(cdev, gswdev->pce_tbl_reg.mask[i], &value); - ptdata->mask[i] = value; - } - /*VAL REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_val; - for (i=0; i<j; i++) { - gsw_r32_raw(cdev, gswdev->pce_tbl_reg.value[i], &value); - ptdata->val[i] = value; - } - - ptdata->type = gsw_field_r32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE); - ptdata->valid = gsw_field_r32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE); - ptdata->group = gsw_field_r32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE); - gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); - //pr_err("Exit table read\n"); -#else - u32 value; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - pr_err("PCE READ\n"); - pr_err("ptdata->pcinde =%d\n",ptdata->pcindex); - pr_err("ptdata->table =%d\n",ptdata->table); - - - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, PCE_TBL_ADDR_ADDR_SHIFT, - PCE_TBL_ADDR_ADDR_SIZE, ptdata->pcindex); - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - gsw_w32(cdev, PCE_TBL_CTRL_OPMOD_OFFSET, PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_ADRD); - gsw_w32(cdev, PCE_TBL_CTRL_BAS_OFFSET, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - - - /*KEY REG*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_r32(cdev, PCE_TBL_KEY_21_KEY21_OFFSET, - PCE_TBL_KEY_21_KEY21_SHIFT, - PCE_TBL_KEY_21_KEY21_SIZE, &value); - ptdata->key[21] = value; - - gsw_r32(cdev, PCE_TBL_KEY_20_KEY20_OFFSET, - PCE_TBL_KEY_20_KEY20_SHIFT, - PCE_TBL_KEY_20_KEY20_SIZE, &value); - ptdata->key[20] = value; - - gsw_r32(cdev, PCE_TBL_KEY_19_KEY19_OFFSET, - PCE_TBL_KEY_19_KEY19_SHIFT, - PCE_TBL_KEY_19_KEY19_SIZE, &value); - ptdata->key[19] = value; - - gsw_r32(cdev, PCE_TBL_KEY_18_KEY18_OFFSET, - PCE_TBL_KEY_18_KEY18_SHIFT, - PCE_TBL_KEY_18_KEY18_SIZE, &value); - ptdata->key[18] = value; - - gsw_r32(cdev, PCE_TBL_KEY_17_KEY17_OFFSET, - PCE_TBL_KEY_17_KEY17_SHIFT, - PCE_TBL_KEY_17_KEY17_SIZE, &value); - ptdata->key[17] = value; - - gsw_r32(cdev, PCE_TBL_KEY_16_KEY16_OFFSET, - PCE_TBL_KEY_16_KEY16_SHIFT, - PCE_TBL_KEY_16_KEY16_SIZE, &value); - ptdata->key[16] = value; - } - - gsw_r32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, &value); - ptdata->key[15] = value; - gsw_r32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, &value); - ptdata->key[14] = value; - gsw_r32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, &value); - ptdata->key[13] = value; - gsw_r32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, &value); - ptdata->key[12] = value; - gsw_r32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, &value); - ptdata->key[11] = value; - gsw_r32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, &value); - ptdata->key[10] = value; - gsw_r32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, &value); - ptdata->key[9] = value; - gsw_r32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, &value); - ptdata->key[8] = value; - gsw_r32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, &value); - ptdata->key[7] = value; - gsw_r32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, &value); - ptdata->key[6] = value; - gsw_r32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, &value); - ptdata->key[5] = value; - gsw_r32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, &value); - ptdata->key[4] = value; - gsw_r32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, &value); - ptdata->key[3] = value; - gsw_r32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, &value); - ptdata->key[2] = value; - gsw_r32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, &value); - ptdata->key[1] = value; - gsw_r32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, &value); - ptdata->key[0] = value; - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_r32(cdev, PCE_TBL_VAL_25_VAL25_OFFSET, - PCE_TBL_VAL_25_VAL25_SHIFT, - PCE_TBL_VAL_25_VAL25_SIZE, &value); - ptdata->val[25] = value; - - gsw_r32(cdev, PCE_TBL_VAL_24_VAL24_OFFSET, - PCE_TBL_VAL_24_VAL24_SHIFT, - PCE_TBL_VAL_24_VAL24_SIZE, &value); - ptdata->val[24] = value; - - gsw_r32(cdev, PCE_TBL_VAL_23_VAL23_OFFSET, - PCE_TBL_VAL_23_VAL23_SHIFT, - PCE_TBL_VAL_23_VAL23_SIZE, &value); - ptdata->val[23] = value; - - gsw_r32(cdev, PCE_TBL_VAL_22_VAL22_OFFSET, - PCE_TBL_VAL_22_VAL22_SHIFT, - PCE_TBL_VAL_22_VAL22_SIZE, &value); - ptdata->val[22] = value; - - gsw_r32(cdev, PCE_TBL_VAL_21_VAL21_OFFSET, - PCE_TBL_VAL_21_VAL21_SHIFT, - PCE_TBL_VAL_21_VAL21_SIZE, &value); - ptdata->val[21] = value; - - gsw_r32(cdev, PCE_TBL_VAL_20_VAL20_OFFSET, - PCE_TBL_VAL_20_VAL20_SHIFT, - PCE_TBL_VAL_20_VAL20_SIZE, &value); - ptdata->val[20] = value; - - gsw_r32(cdev, PCE_TBL_VAL_19_VAL19_OFFSET, - PCE_TBL_VAL_19_VAL19_SHIFT, - PCE_TBL_VAL_19_VAL19_SIZE, &value); - ptdata->val[19] = value; - - gsw_r32(cdev, PCE_TBL_VAL_18_VAL18_OFFSET, - PCE_TBL_VAL_18_VAL18_SHIFT, - PCE_TBL_VAL_18_VAL18_SIZE, &value); - ptdata->val[18] = value; - - gsw_r32(cdev, PCE_TBL_VAL_17_VAL17_OFFSET, - PCE_TBL_VAL_17_VAL17_SHIFT, - PCE_TBL_VAL_17_VAL17_SIZE, &value); - ptdata->val[17] = value; - - gsw_r32(cdev, PCE_TBL_VAL_16_VAL16_OFFSET, - PCE_TBL_VAL_16_VAL16_SHIFT, - PCE_TBL_VAL_16_VAL16_SIZE, &value); - ptdata->val[16] = value; - } - - gsw_r32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, &value); - ptdata->val[15] = value; - gsw_r32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, &value); - ptdata->val[14] = value; - gsw_r32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, &value); - ptdata->val[13] = value; - gsw_r32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, &value); - ptdata->val[12] = value; - gsw_r32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, &value); - ptdata->val[11] = value; - gsw_r32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, &value); - ptdata->val[10] = value; - gsw_r32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, &value); - ptdata->val[9] = value; - gsw_r32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, &value); - ptdata->val[8] = value; - gsw_r32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, &value); - ptdata->val[7] = value; - gsw_r32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, &value); - ptdata->val[6] = value; - gsw_r32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, &value); - ptdata->val[5] = value; - gsw_r32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, &value); - ptdata->val[4] = value; - gsw_r32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, &value); - ptdata->val[3] = value; - gsw_r32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, &value); - ptdata->val[2] = value; - gsw_r32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, &value); - ptdata->val[1] = value; - gsw_r32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, &value); - ptdata->val[0] = value; - gsw_r32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, &value); - ptdata->mask[0] = value; - gsw_r32(cdev, PCE_TBL_MASK_1_MASK1_OFFSET, - PCE_TBL_MASK_1_MASK1_SHIFT, - PCE_TBL_MASK_1_MASK1_SIZE, &value); - ptdata->mask[1] = value; - gsw_r32(cdev, PCE_TBL_MASK_2_MASK2_OFFSET, - PCE_TBL_MASK_2_MASK2_SHIFT, - PCE_TBL_MASK_2_MASK2_SIZE, &value); - ptdata->mask[2] = value; - gsw_r32(cdev, PCE_TBL_MASK_3_MASK3_OFFSET, - PCE_TBL_MASK_3_MASK3_SHIFT, - PCE_TBL_MASK_3_MASK3_SIZE, &value); - ptdata->mask[3] = value; - gsw_r32(cdev, PCE_TBL_CTRL_TYPE_OFFSET, - PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, &value); - ptdata->type = value; - gsw_r32(cdev, PCE_TBL_CTRL_VLD_OFFSET, - PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, &value); - ptdata->valid = value; - gsw_r32(cdev, PCE_TBL_CTRL_GMAP_OFFSET, - PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, &value); - ptdata->group = value; - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); -#endif - return GSW_statusOk; -} - -int gsw_pce_table_key_read(void *cdev, pctbl_prog_t *ptdata) -{ -#if 1 - u32 ctrlval, value; - u16 i, j; - //pr_err("Enter table key read\n"); - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - - /*KEY REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_key; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); - } - - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSRD); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, - PCE_TBL_CTRL_KEYFORM_SIZE, 0); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - /*VAL REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_val; - for (i=0; i<j; i++) { - gsw_r32_raw(cdev, gswdev->pce_tbl_reg.value[i], &value); - ptdata->val[i] = value; - } - - ptdata->type = gsw_field_r32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE); - ptdata->valid = gsw_field_r32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE); - ptdata->group = gsw_field_r32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE); - gsw_r32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, &value); - ptdata->pcindex = value; - gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); - //pr_err("Exit table key read\n"); -#else - u32 value; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - - value = ptdata->table; - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, - PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, value); - - /*KEY REG*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - value = ptdata->key[21]; - gsw_w32(cdev, PCE_TBL_KEY_21_KEY21_OFFSET, - PCE_TBL_KEY_21_KEY21_SHIFT, - PCE_TBL_KEY_21_KEY21_SIZE, value); - - value = ptdata->key[20]; - gsw_w32(cdev, PCE_TBL_KEY_20_KEY20_OFFSET, - PCE_TBL_KEY_20_KEY20_SHIFT, - PCE_TBL_KEY_20_KEY20_SIZE, value); - - value = ptdata->key[19]; - gsw_w32(cdev, PCE_TBL_KEY_19_KEY19_OFFSET, - PCE_TBL_KEY_19_KEY19_SHIFT, - PCE_TBL_KEY_19_KEY19_SIZE, value); - - value = ptdata->key[18]; - gsw_w32(cdev, PCE_TBL_KEY_18_KEY18_OFFSET, - PCE_TBL_KEY_18_KEY18_SHIFT, - PCE_TBL_KEY_18_KEY18_SIZE, value); - - value = ptdata->key[17]; - gsw_w32(cdev, PCE_TBL_KEY_17_KEY17_OFFSET, - PCE_TBL_KEY_17_KEY17_SHIFT, - PCE_TBL_KEY_17_KEY17_SIZE, value); - - value = ptdata->key[16]; - gsw_w32(cdev, PCE_TBL_KEY_16_KEY16_OFFSET, - PCE_TBL_KEY_16_KEY16_SHIFT, - PCE_TBL_KEY_16_KEY16_SIZE, value); - } - - value = ptdata->key[15]; - gsw_w32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, value); - value = ptdata->key[14]; - gsw_w32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, value); - value = ptdata->key[13]; - gsw_w32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, value); - value = ptdata->key[12]; - gsw_w32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, value); - value = ptdata->key[11]; - gsw_w32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, value); - value = ptdata->key[10]; - gsw_w32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, value); - value = ptdata->key[9]; - gsw_w32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, value); - value = ptdata->key[8]; - gsw_w32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, value); - value = ptdata->key[7]; - gsw_w32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, value); - value = ptdata->key[6]; - gsw_w32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, value); - value = ptdata->key[5]; - gsw_w32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, value); - value = ptdata->key[4]; - gsw_w32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, value); - value = ptdata->key[3]; - gsw_w32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, value); - value = ptdata->key[2]; - gsw_w32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, value); - value = ptdata->key[1]; - gsw_w32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, value); - value = ptdata->key[0]; - gsw_w32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, value); - - gsw_w32(cdev, PCE_TBL_CTRL_OPMOD_OFFSET, - PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSRD); - gsw_w32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_r32(cdev, PCE_TBL_VAL_25_VAL25_OFFSET, - PCE_TBL_VAL_25_VAL25_SHIFT, - PCE_TBL_VAL_25_VAL25_SIZE, &value); - ptdata->val[25] = value; - - gsw_r32(cdev, PCE_TBL_VAL_24_VAL24_OFFSET, - PCE_TBL_VAL_24_VAL24_SHIFT, - PCE_TBL_VAL_24_VAL24_SIZE, &value); - ptdata->val[24] = value; - - gsw_r32(cdev, PCE_TBL_VAL_23_VAL23_OFFSET, - PCE_TBL_VAL_23_VAL23_SHIFT, - PCE_TBL_VAL_23_VAL23_SIZE, &value); - ptdata->val[23] = value; - - gsw_r32(cdev, PCE_TBL_VAL_22_VAL22_OFFSET, - PCE_TBL_VAL_22_VAL22_SHIFT, - PCE_TBL_VAL_22_VAL22_SIZE, &value); - ptdata->val[22] = value; - - gsw_r32(cdev, PCE_TBL_VAL_21_VAL21_OFFSET, - PCE_TBL_VAL_21_VAL21_SHIFT, - PCE_TBL_VAL_21_VAL21_SIZE, &value); - ptdata->val[21] = value; - - gsw_r32(cdev, PCE_TBL_VAL_20_VAL20_OFFSET, - PCE_TBL_VAL_20_VAL20_SHIFT, - PCE_TBL_VAL_20_VAL20_SIZE, &value); - ptdata->val[20] = value; - - gsw_r32(cdev, PCE_TBL_VAL_19_VAL19_OFFSET, - PCE_TBL_VAL_19_VAL19_SHIFT, - PCE_TBL_VAL_19_VAL19_SIZE, &value); - ptdata->val[19] = value; - - gsw_r32(cdev, PCE_TBL_VAL_18_VAL18_OFFSET, - PCE_TBL_VAL_18_VAL18_SHIFT, - PCE_TBL_VAL_18_VAL18_SIZE, &value); - ptdata->val[18] = value; - - gsw_r32(cdev, PCE_TBL_VAL_17_VAL17_OFFSET, - PCE_TBL_VAL_17_VAL17_SHIFT, - PCE_TBL_VAL_17_VAL17_SIZE, &value); - ptdata->val[17] = value; - - gsw_r32(cdev, PCE_TBL_VAL_16_VAL16_OFFSET, - PCE_TBL_VAL_16_VAL16_SHIFT, - PCE_TBL_VAL_16_VAL16_SIZE, &value); - ptdata->val[16] = value; - } - - gsw_r32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, &value); - ptdata->val[15] = value; - gsw_r32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, &value); - ptdata->val[14] = value; - gsw_r32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, &value); - ptdata->val[13] = value; - gsw_r32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, &value); - ptdata->val[12] = value; - gsw_r32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, &value); - ptdata->val[11] = value; - gsw_r32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, &value); - ptdata->val[10] = value; - gsw_r32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, &value); - ptdata->val[9] = value; - gsw_r32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, &value); - ptdata->val[8] = value; - gsw_r32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, &value); - ptdata->val[7] = value; - gsw_r32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, &value); - ptdata->val[6] = value; - gsw_r32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, &value); - ptdata->val[5] = value; - gsw_r32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, &value); - ptdata->val[4] = value; - gsw_r32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, &value); - ptdata->val[3] = value; - gsw_r32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, &value); - ptdata->val[2] = value; - gsw_r32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, &value); - ptdata->val[1] = value; - gsw_r32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, &value); - ptdata->val[0] = value; - gsw_r32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, &value); - ptdata->mask[0] = value; - gsw_r32(cdev, PCE_TBL_MASK_1_MASK1_OFFSET, - PCE_TBL_MASK_1_MASK1_SHIFT, - PCE_TBL_MASK_1_MASK1_SIZE, &value); - ptdata->mask[1] = value; - gsw_r32(cdev, PCE_TBL_MASK_2_MASK2_OFFSET, - PCE_TBL_MASK_2_MASK2_SHIFT, - PCE_TBL_MASK_2_MASK2_SIZE, &value); - ptdata->mask[2] = value; - gsw_r32(cdev, PCE_TBL_MASK_3_MASK3_OFFSET, - PCE_TBL_MASK_3_MASK3_SHIFT, - PCE_TBL_MASK_3_MASK3_SIZE, &value); - ptdata->mask[3] = value; - gsw_r32(cdev, PCE_TBL_CTRL_TYPE_OFFSET, - PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, &value); - ptdata->type = value; - gsw_r32(cdev, PCE_TBL_CTRL_VLD_OFFSET, - PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, &value); - ptdata->valid = value; - gsw_r32(cdev, PCE_TBL_CTRL_GMAP_OFFSET, - PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, &value); - ptdata->group = value; - gsw_r32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, - PCE_TBL_ADDR_ADDR_SHIFT, PCE_TBL_ADDR_ADDR_SIZE, &value); - ptdata->pcindex = value; - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); -#endif - return GSW_statusOk; -} -int gsw_pce_table_key_write(void *cdev, pctbl_prog_t *ptdata) -{ -#if 1 - u32 ctrlval; - u16 i, j; - //pr_err("Enter table key write\n"); - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - - /*TABLE ADDRESS*/ - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSWR); - - /*KEY REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_key; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); - } - /*MASK REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_mask; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.mask[i], ptdata->mask[i]); - } - /*VAL REG*/ - j = gswdev->pce_tbl_info[ptdata->table].num_val; - for (i=0; i<j; i++) { - gsw_w32_raw(cdev, gswdev->pce_tbl_reg.value[i], ptdata->val[i]); - } - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, - PCE_TBL_CTRL_KEYFORM_SIZE, 0); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, ptdata->type); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, ptdata->valid); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, ptdata->group); - ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); - - do { - gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); - } while(gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE)); - gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); - //pr_err("Exit table key write\n"); -#else - u32 value; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - - if (gswdev == NULL) { - pr_err("\n%s:%s:%d",__FILE__, __func__, __LINE__); - return GSW_statusErr; - } - - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, - PCE_TBL_CTRL_ADDR_SHIFT, - PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); - gsw_w32(cdev, PCE_TBL_CTRL_OPMOD_OFFSET, - PCE_TBL_CTRL_OPMOD_SHIFT, - PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSWR); - - /*KEY REG*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - gsw_w32(cdev, PCE_TBL_KEY_21_KEY21_OFFSET, - PCE_TBL_KEY_21_KEY21_SHIFT, - PCE_TBL_KEY_21_KEY21_SIZE, ptdata->key[21]); - gsw_w32(cdev, PCE_TBL_KEY_20_KEY20_OFFSET, - PCE_TBL_KEY_20_KEY20_SHIFT, - PCE_TBL_KEY_20_KEY20_SIZE, ptdata->key[20]); - gsw_w32(cdev, PCE_TBL_KEY_19_KEY19_OFFSET, - PCE_TBL_KEY_19_KEY19_SHIFT, - PCE_TBL_KEY_19_KEY19_SIZE, ptdata->key[19]); - gsw_w32(cdev, PCE_TBL_KEY_18_KEY18_OFFSET, - PCE_TBL_KEY_18_KEY18_SHIFT, - PCE_TBL_KEY_18_KEY18_SIZE, ptdata->key[18]); - gsw_w32(cdev, PCE_TBL_KEY_17_KEY17_OFFSET, - PCE_TBL_KEY_17_KEY17_SHIFT, - PCE_TBL_KEY_17_KEY17_SIZE, ptdata->key[17]); - gsw_w32(cdev, PCE_TBL_KEY_16_KEY16_OFFSET, - PCE_TBL_KEY_16_KEY16_SHIFT, - PCE_TBL_KEY_16_KEY16_SIZE, ptdata->key[16]); - } - - value = ptdata->key[15]; - gsw_w32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, value); - value = ptdata->key[14]; - gsw_w32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, value); - value = ptdata->key[13]; - gsw_w32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, value); - value = ptdata->key[12]; - gsw_w32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, value); - value = ptdata->key[11]; - gsw_w32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, value); - value = ptdata->key[10]; - gsw_w32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, value); - value = ptdata->key[9]; - gsw_w32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, value); - value = ptdata->key[8]; - gsw_w32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, value); - value = ptdata->key[7]; - gsw_w32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, value); - value = ptdata->key[6]; - gsw_w32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, value); - value = ptdata->key[5]; - gsw_w32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, value); - value = ptdata->key[4]; - gsw_w32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, value); - value = ptdata->key[3]; - gsw_w32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, value); - value = ptdata->key[2]; - gsw_w32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, value); - value = ptdata->key[1]; - gsw_w32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, value); - value = ptdata->key[0]; - gsw_w32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, value); - value = ptdata->mask[0]; - gsw_w32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, value); - value = ptdata->mask[1]; - gsw_w32(cdev, PCE_TBL_MASK_1_MASK1_OFFSET, - PCE_TBL_MASK_1_MASK1_SHIFT, - PCE_TBL_MASK_1_MASK1_SIZE, value); - value = ptdata->mask[2]; - gsw_w32(cdev, PCE_TBL_MASK_2_MASK2_OFFSET, - PCE_TBL_MASK_2_MASK2_SHIFT, - PCE_TBL_MASK_2_MASK2_SIZE, value); - value = ptdata->mask[3]; - gsw_w32(cdev, PCE_TBL_MASK_3_MASK3_OFFSET, - PCE_TBL_MASK_3_MASK3_SHIFT, - PCE_TBL_MASK_3_MASK3_SIZE, value); - value = ptdata->val[15]; - gsw_w32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, value); - value = ptdata->val[14]; - gsw_w32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, value); - value = ptdata->val[13]; - gsw_w32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, value); - value = ptdata->val[12]; - gsw_w32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, value); - value = ptdata->val[11]; - gsw_w32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, value); - value = ptdata->val[10]; - gsw_w32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, value); - value = ptdata->val[9]; - gsw_w32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, value); - value = ptdata->val[8]; - gsw_w32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, value); - value = ptdata->val[7]; - gsw_w32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, value); - value = ptdata->val[6]; - gsw_w32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, value); - value = ptdata->val[5]; - gsw_w32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, value); - value = ptdata->val[4]; - gsw_w32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, value); - value = ptdata->val[3]; - gsw_w32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, value); - value = ptdata->val[2]; - gsw_w32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, value); - value = ptdata->val[1]; - gsw_w32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, value); - value = ptdata->val[0]; - gsw_w32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, value); - value = ptdata->type; - gsw_w32(cdev, PCE_TBL_CTRL_TYPE_OFFSET, - PCE_TBL_CTRL_TYPE_SHIFT, - PCE_TBL_CTRL_TYPE_SIZE, value); - value = ptdata->valid; - gsw_w32(cdev, PCE_TBL_CTRL_VLD_OFFSET, - PCE_TBL_CTRL_VLD_SHIFT, - PCE_TBL_CTRL_VLD_SIZE, value); - value = ptdata->group; - gsw_w32(cdev, PCE_TBL_CTRL_GMAP_OFFSET, - PCE_TBL_CTRL_GMAP_SHIFT, - PCE_TBL_CTRL_GMAP_SIZE, ptdata->group); - gsw_w32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_TBL_CTRL_BAS_OFFSET, - PCE_TBL_CTRL_BAS_SHIFT, - PCE_TBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); -#endif return GSW_statusOk; } /* Packet Length Table write same for both 3.0 and 3.1*/ static int pce_tm_pkg_lng_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_pkt_length_t *parm) + pcetbl_prog_t *pthandle, pce_pkt_length_t *parm) { int status; pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->pkg_lng_tbl, - pthandle->pkg_lng_tbl_cnt, - parm, sizeof(pce_pkt_length_t), PCE_PKG_LNG_TBL_SIZE); + pthandle->pkg_lng_tbl_cnt, + parm, sizeof(pce_pkt_length_t), PCE_PKG_LNG_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PACKET_INDEX; @@ -1897,6 +669,7 @@ static int pce_tm_pkg_lng_tbl_write(void *cdev, ptbl.mask[0] = parm->pkg_lng_rng; ptbl.valid = 1; status = gsw_pce_table_write(cdev, &ptbl); + if (status == GSW_statusOk) return pcindex; else @@ -1905,31 +678,35 @@ static int pce_tm_pkg_lng_tbl_write(void *cdev, /* Packet Length Table delete */ static int pce_tm_pkg_lng_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { int status; pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_PKG_LNG_TBL_SIZE); + if (pthandle->pkg_lng_tbl_cnt[index] > 0) pthandle->pkg_lng_tbl_cnt[index]--; + if (pthandle->pkg_lng_tbl_cnt[index] == 0) { memset((((char *)pthandle->pkg_lng_tbl) - + (index * sizeof(pce_pkt_length_t))), - 0, sizeof(pce_pkt_length_t)); + + (index * sizeof(pce_pkt_length_t))), + 0, sizeof(pce_pkt_length_t)); /* initialize the data structure before using it */ memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PACKET_INDEX; ptbl.pcindex = index; status = gsw_pce_table_write(cdev, &ptbl); + if (status == GSW_statusErr) return status; } + return GSW_statusOk; } /* Packet Length Table read */ static int pce_tm_pkg_lng_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_pkt_length_t *parm) + int index, pce_pkt_length_t *parm) { PCE_ASSERT(index >= PCE_PKG_LNG_TBL_SIZE); memcpy(parm, &pthandle->pkg_lng_tbl[index], sizeof(pce_pkt_length_t)); @@ -1938,13 +715,13 @@ static int pce_tm_pkg_lng_tbl_read(pcetbl_prog_t *pthandle, /* MAC DA Table index write */ static int pce_da_mac_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_da_prog_t *parm) + pcetbl_prog_t *pthandle, pce_da_prog_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->da_mac_tbl, - pthandle->da_mac_tbl_cnt, parm, - sizeof(pce_da_prog_t), PCE_DASA_MAC_TBL_SIZE); + pthandle->da_mac_tbl_cnt, parm, + sizeof(pce_da_prog_t), PCE_DASA_MAC_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_MACDA_INDEX; @@ -1960,13 +737,13 @@ static int pce_da_mac_tbl_write(void *cdev, /* MAC SA Table index write */ static int pce_sa_mac_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_sa_prog_t *parm) + pcetbl_prog_t *pthandle, pce_sa_prog_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->sa_mac_tbl, - pthandle->sa_mac_tbl_cnt, parm, - sizeof(pce_sa_prog_t), PCE_DASA_MAC_TBL_SIZE); + pthandle->sa_mac_tbl_cnt, parm, + sizeof(pce_sa_prog_t), PCE_DASA_MAC_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_MACSA_INDEX; @@ -1974,7 +751,7 @@ static int pce_sa_mac_tbl_write(void *cdev, ptbl.key[0] = (parm->mac[4] << 8 | parm->mac[5]); ptbl.key[1] = (parm->mac[2] << 8 | parm->mac[3]); ptbl.key[2] = (parm->mac[0] << 8 | parm->mac[1]); - ptbl.mask[0]= parm->mac_mask; + ptbl.mask[0] = parm->mac_mask; ptbl.valid = 1; gsw_pce_table_write(cdev, &ptbl); return pcindex; @@ -1982,49 +759,55 @@ static int pce_sa_mac_tbl_write(void *cdev, /* MAC SA Table delete */ static int pce_tm_sa_mac_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_DASA_MAC_TBL_SIZE); + if (pthandle->sa_mac_tbl_cnt[index] > 0) pthandle->sa_mac_tbl_cnt[index]--; + if (pthandle->sa_mac_tbl_cnt[index] == 0) { memset((((char *)pthandle->sa_mac_tbl) - + (index * sizeof(pce_sa_prog_t))), - 0, sizeof(pce_sa_prog_t)); + + (index * sizeof(pce_sa_prog_t))), + 0, sizeof(pce_sa_prog_t)); /* initialize the data structure before using it */ memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_MACSA_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* MAC DA Table delete */ static int pce_tm_da_mac_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_DASA_MAC_TBL_SIZE); + if (pthandle->da_mac_tbl_cnt[index] > 0) pthandle->da_mac_tbl_cnt[index]--; + if (pthandle->da_mac_tbl_cnt[index] == 0) { memset((((char *)pthandle->da_mac_tbl) - + (index * sizeof(pce_da_prog_t))), - 0, sizeof(pce_sa_prog_t)); + + (index * sizeof(pce_da_prog_t))), + 0, sizeof(pce_sa_prog_t)); /* initialize the data structure before using it */ memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_MACDA_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* MAC DA Table Read */ static int pce_tm_da_mac_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_da_prog_t *parm) + int index, pce_da_prog_t *parm) { PCE_ASSERT(index >= PCE_DASA_MAC_TBL_SIZE); memcpy(parm, &pthandle->da_mac_tbl[index], sizeof(pce_da_prog_t)); @@ -2033,7 +816,7 @@ static int pce_tm_da_mac_tbl_read(pcetbl_prog_t *pthandle, /* MAC SA Table Read */ static int pce_tm_sa_mac_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_sa_prog_t *parm) + int index, pce_sa_prog_t *parm) { PCE_ASSERT(index >= PCE_DASA_MAC_TBL_SIZE); memcpy(parm, &pthandle->sa_mac_tbl[index], sizeof(pce_sa_prog_t)); @@ -2042,12 +825,12 @@ static int pce_tm_sa_mac_tbl_read(pcetbl_prog_t *pthandle, /* Application Table write */ static int pce_appl_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, app_tbl_t *parm) + pcetbl_prog_t *pthandle, app_tbl_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->appl_tbl, pthandle->appl_tbl_cnt, parm, - sizeof(app_tbl_t), PCE_APPL_TBL_SIZE); + sizeof(app_tbl_t), PCE_APPL_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_APPLICATION_INDEX; @@ -2062,7 +845,7 @@ static int pce_appl_tbl_write(void *cdev, /* Flags Table write */ static int pce_flags_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, flag_tbl_t *parm) + pcetbl_prog_t *pthandle, flag_tbl_t *parm) { pctbl_prog_t ptbl; int pcindex, i; @@ -2071,112 +854,128 @@ static int pce_flags_tbl_write(void *cdev, u16 key_val = parm->parser_flag_data; u16 bit_mask = parm->mask_value; pcindex = tbl_write(pthandle->flags_tbl, - pthandle->flags_tbl_cnt, parm, - sizeof(flag_tbl_t), PCE_FLAGS_TBL_SIZE); + pthandle->flags_tbl_cnt, parm, + sizeof(flag_tbl_t), PCE_FLAGS_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PARSER_FLAGS_INDEX; ptbl.pcindex = pcindex; for (i = 0; i < 4; i++) { - mask_section = ((bit_mask >> (i*4)) & 0xF); - key_section = ((key_val >> (i*4)) & 0xF); + mask_section = ((bit_mask >> (i * 4)) & 0xF); + key_section = ((key_val >> (i * 4)) & 0xF); bit_pos = key_section; column[i] = (1 << bit_pos); if ((mask_section & 0x1) == 1) { bit_pos = key_section & 0xe; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x1); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 1) & 0x1) == 1) { bit_pos = key_section & 0xd; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x2); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0x3) == 0x3) { bit_pos = key_section & 0xc; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x3); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 2) & 0x1) == 0x1) { bit_pos = key_section & 0xb; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x4); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0x5) == 0x5) { bit_pos = key_section & 0xa; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x5); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 1) & 0x3) == 0x3) { bit_pos = key_section & 0x9; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x6); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0x7) == 0x7) { bit_pos = key_section & 0x8; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x7); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 3) & 0x1) == 0x1) { bit_pos = key_section & 0x7; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x8); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0x9) == 0x9) { bit_pos = key_section & 0x6; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0x9); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0xa) == 0xa) { bit_pos = key_section & 0x5; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xa); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 2) & 0x3) == 0x3) { bit_pos = key_section & 0x3; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xc); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0xb) == 0xb) { bit_pos = key_section & 0x4; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xb); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0xd) == 0xd) { bit_pos = key_section & 0x2; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xd); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 1) & 0x7) == 0x7) { bit_pos = key_section & 0x1; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xe); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } + if (((mask_section >> 0) & 0xf) == 0xf) { bit_pos = key_section & 0x0; - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); bit_pos = (key_section | 0xf); - column[i] |= (1 << bit_pos); + column[i] |= (1 << bit_pos); } } + for (i = 0; i < 4; i++) ptbl.key[i] = column[i]; + ptbl.valid = 1; ptbl.kformat = 1; gsw_pce_table_write(cdev, &ptbl); @@ -2188,13 +987,13 @@ static int pce_flags_tbl_write(void *cdev, /* Payload Table write */ static int pce_payload_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, payload_tbl_t *parm) + pcetbl_prog_t *pthandle, payload_tbl_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->payload_tbl, - pthandle->payload_tbl_cnt, parm, - sizeof(payload_tbl_t), PCE_PAYLOAD_TBL_SIZE); + pthandle->payload_tbl_cnt, parm, + sizeof(payload_tbl_t), PCE_PAYLOAD_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PAYLOAD_INDEX; @@ -2209,69 +1008,78 @@ static int pce_payload_tbl_write(void *cdev, /* Application Table Delete */ static int pce_tm_appl_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_APPL_TBL_SIZE); + if (pthandle->appl_tbl_cnt[index] > 0) pthandle->appl_tbl_cnt[index]--; + if (pthandle->appl_tbl_cnt[index] == 0) { memset((((char *)pthandle->appl_tbl) - + (index * sizeof(app_tbl_t))), - 0, sizeof(app_tbl_t)); + + (index * sizeof(app_tbl_t))), + 0, sizeof(app_tbl_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_APPLICATION_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* Flags Table Delete */ static int pce_tm_flags_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_FLAGS_TBL_SIZE); + if (pthandle->flags_tbl_cnt[index] > 0) pthandle->flags_tbl_cnt[index]--; + if (pthandle->flags_tbl_cnt[index] == 0) { memset((((char *)pthandle->flags_tbl) - + (index * sizeof(flag_tbl_t))), - 0, sizeof(flag_tbl_t)); + + (index * sizeof(flag_tbl_t))), + 0, sizeof(flag_tbl_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PARSER_FLAGS_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* Payload Table Delete */ static int pce_tm_payload_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_PAYLOAD_TBL_SIZE); + if (pthandle->payload_tbl_cnt[index] > 0) pthandle->payload_tbl_cnt[index]--; + if (pthandle->payload_tbl_cnt[index] == 0) { memset((((char *)pthandle->payload_tbl) - + (index * sizeof(payload_tbl_t))), - 0, sizeof(payload_tbl_t)); + + (index * sizeof(payload_tbl_t))), + 0, sizeof(payload_tbl_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PAYLOAD_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* Application Table Read */ static int pce_tm_appl_tbl_read(pcetbl_prog_t *pthandle, - int index, app_tbl_t *parm) + int index, app_tbl_t *parm) { PCE_ASSERT(index >= PCE_APPL_TBL_SIZE); memcpy(parm, &pthandle->appl_tbl[index], sizeof(app_tbl_t)); @@ -2280,7 +1088,7 @@ static int pce_tm_appl_tbl_read(pcetbl_prog_t *pthandle, /* Flags Table Read */ static int pce_tm_flags_tbl_read(pcetbl_prog_t *pthandle, - int index, flag_tbl_t *parm) + int index, flag_tbl_t *parm) { PCE_ASSERT(index >= PCE_FLAGS_TBL_SIZE); memcpy(parm, &pthandle->flags_tbl[index], sizeof(flag_tbl_t)); @@ -2289,7 +1097,7 @@ static int pce_tm_flags_tbl_read(pcetbl_prog_t *pthandle, /* Payload Table Read */ static int pce_tm_payload_tbl_read(pcetbl_prog_t *pthandle, - int index, payload_tbl_t *parm) + int index, payload_tbl_t *parm) { PCE_ASSERT(index >= PCE_PAYLOAD_TBL_SIZE); memcpy(parm, &pthandle->payload_tbl[index], sizeof(payload_tbl_t)); @@ -2298,19 +1106,23 @@ static int pce_tm_payload_tbl_read(pcetbl_prog_t *pthandle, /* IP DA/SA msb Table write */ int pce_dasa_msb_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_dasa_msb_t *parm) + pcetbl_prog_t *pthandle, pce_dasa_msb_t *parm) { pctbl_prog_t ptbl; int pcindex, i; pcindex = tbl_write(pthandle->ip_dasa_msb_tbl, pthandle->ipmsbtcnt, parm, - sizeof(pce_dasa_msb_t), IP_DASA_PC_MSIZE); + sizeof(pce_dasa_msb_t), IP_DASA_PC_MSIZE); + if (pcindex < 0) return pcindex; + memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_IP_DASA_MSB_INDEX; ptbl.pcindex = pcindex; + for (i = 0; i < 4; i++) - ptbl.key[i] = ((parm->imsb[((i*2)+1)] << 8) | parm->imsb[(i*2)]); + ptbl.key[i] = ((parm->imsb[((i * 2) + 1)] << 8) | parm->imsb[(i * 2)]); + ptbl.mask[0] = parm->mask[0]; ptbl.mask[1] = parm->mask[1]; ptbl.mask[2] = parm->mask[2]; @@ -2322,12 +1134,14 @@ int pce_dasa_msb_tbl_write(void *cdev, /* IP DA/SA msb Table delete */ int ip_dasa_msb_tbl_del(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= IP_DASA_PC_MSIZE); + if (pthandle->ipmsbtcnt[index] > 0) pthandle->ipmsbtcnt[index]--; + if (pthandle->ipmsbtcnt[index] == 0) { memset((((char *)pthandle->ip_dasa_msb_tbl) + (index * sizeof(pce_dasa_msb_t))), 0, sizeof(pce_dasa_msb_t)); @@ -2336,12 +1150,13 @@ int ip_dasa_msb_tbl_del(void *cdev, ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* IP DA/SA msb Table read */ static int pce_dasa_msb_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_dasa_msb_t *parm) + int index, pce_dasa_msb_t *parm) { PCE_ASSERT(index >= IP_DASA_PC_MSIZE); memcpy(parm, &pthandle->ip_dasa_msb_tbl[index], sizeof(pce_dasa_msb_t)); @@ -2349,50 +1164,54 @@ static int pce_dasa_msb_tbl_read(pcetbl_prog_t *pthandle, } static int get_tbl_index(void *tstart, void *parm, - u32 tsize, u32 tnum) + u32 tsize, u32 tnum) { int i; + /* search if the entry is already available and can be re-used */ for (i = 0; i < tnum; i++) { /* entry is used, check if the entry content fits */ if (memcmp(((char *)tstart) - + i * tsize, parm, (u8)tsize) == 0) + + i * tsize, parm, (u8)tsize) == 0) return i; } + return 0xFF; } /* Static Function Declaration */ int find_dasa_tbl_entry(pcetbl_prog_t *pthandle, - pce_dasa_lsb_t *parm) + pce_dasa_lsb_t *parm) { return get_tbl_index(pthandle->ip_dasa_lsb_tbl, parm, - sizeof(pce_dasa_lsb_t), IP_DASA_PC_LSIZE); + sizeof(pce_dasa_lsb_t), IP_DASA_PC_LSIZE); } /* Static Function Declaration */ int find_msb_tbl_entry(pcetbl_prog_t *pthandle, - pce_dasa_msb_t *parm) + pce_dasa_msb_t *parm) { return get_tbl_index(pthandle->ip_dasa_msb_tbl, parm, - sizeof(pce_dasa_msb_t), IP_DASA_PC_MSIZE); + sizeof(pce_dasa_msb_t), IP_DASA_PC_MSIZE); } /* IP DA/SA lsb Table Write */ int pce_dasa_lsb_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_dasa_lsb_t *parm) + pcetbl_prog_t *pthandle, pce_dasa_lsb_t *parm) { pctbl_prog_t ptbl; int pcindex, i; pcindex = tbl_write(pthandle->ip_dasa_lsb_tbl, pthandle->iplsbtcnt, parm, - sizeof(pce_dasa_lsb_t), IP_DASA_PC_LSIZE); + sizeof(pce_dasa_lsb_t), IP_DASA_PC_LSIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_IP_DASA_LSB_INDEX; ptbl.pcindex = pcindex; + for (i = 0; i < 4; i++) - ptbl.key[i] = ((parm->ilsb[((i*2)+1)] << 8) - | parm->ilsb[(i*2)]); + ptbl.key[i] = ((parm->ilsb[((i * 2) + 1)] << 8) + | parm->ilsb[(i * 2)]); + ptbl.mask[0] = parm->mask[0]; ptbl.mask[1] = parm->mask[1]; ptbl.mask[2] = parm->mask[2]; @@ -2404,12 +1223,14 @@ int pce_dasa_lsb_tbl_write(void *cdev, /* IP DA/SA lsb Table delete */ int ip_dasa_lsb_tbl_del(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= IP_DASA_PC_LSIZE); + if (pthandle->iplsbtcnt[index] > 0) pthandle->iplsbtcnt[index]--; + if (pthandle->iplsbtcnt[index] == 0) { memset((((char *)pthandle->ip_dasa_lsb_tbl) + (index * sizeof(pce_dasa_lsb_t))), 0, sizeof(pce_dasa_lsb_t)); @@ -2418,28 +1239,29 @@ int ip_dasa_lsb_tbl_del(void *cdev, ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* IP DA/SA lsb Table index delete */ int ipdslsb_tblidx_del(pcetbl_prog_t *pthandle, - u32 index) + u32 index) { return tbl_idx_delete(pthandle->iplsbtcnt, - index, IP_DASA_PC_LSIZE); + index, IP_DASA_PC_LSIZE); } /* IP DA/SA msb Table index delete */ int ipdsmsb_tblidx_del(pcetbl_prog_t *pthandle, - u32 index) + u32 index) { return tbl_idx_delete(pthandle->ipmsbtcnt, - index, IP_DASA_PC_MSIZE); + index, IP_DASA_PC_MSIZE); } /* IP DA/SA lsb Table read */ int pce_dasa_lsb_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_dasa_lsb_t *parm) + int index, pce_dasa_lsb_t *parm) { PCE_ASSERT(index >= IP_DASA_PC_LSIZE); memcpy(parm, &pthandle->ip_dasa_lsb_tbl[index], sizeof(pce_dasa_lsb_t)); @@ -2448,13 +1270,13 @@ int pce_dasa_lsb_tbl_read(pcetbl_prog_t *pthandle, /* Protocal Table write */ static int pce_ptcl_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, prtcol_tbl_t *parm) + pcetbl_prog_t *pthandle, prtcol_tbl_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->ptcl_tbl, - pthandle->ptcl_tbl_cnt, parm, - sizeof(prtcol_tbl_t), PCE_PTCL_TBL_SIZE); + pthandle->ptcl_tbl_cnt, parm, + sizeof(prtcol_tbl_t), PCE_PTCL_TBL_SIZE); PCE_ASSERT(pcindex < 0); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PROTOCOL_INDEX; @@ -2469,6 +1291,7 @@ static int pce_ptcl_tbl_write(void *cdev, int gavlan_tbl_index(pcetbl_prog_t *pthandle, u8 index) { PCE_ASSERT(index >= PCE_VLAN_ACT_TBL_SIZE); + if (pthandle->vlan_act_tbl_cnt[index] == 0) return GSW_statusOk; else @@ -2477,27 +1300,30 @@ int gavlan_tbl_index(pcetbl_prog_t *pthandle, u8 index) /* Protocal Table delete */ static int pce_tm_ptcl_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_PTCL_TBL_SIZE); + if (pthandle->ptcl_tbl_cnt[index] > 0) pthandle->ptcl_tbl_cnt[index]--; + if (pthandle->ptcl_tbl_cnt[index] == 0) { memset((((char *)pthandle->ptcl_tbl) - + (index * sizeof(prtcol_tbl_t))), - 0, sizeof(prtcol_tbl_t)); + + (index * sizeof(prtcol_tbl_t))), + 0, sizeof(prtcol_tbl_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PROTOCOL_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* Protocal Table Read */ static int pce_tm_ptcl_tbl_read(pcetbl_prog_t *pthandle, - int index, prtcol_tbl_t *parm) + int index, prtcol_tbl_t *parm) { PCE_ASSERT(index >= PCE_PTCL_TBL_SIZE); memcpy(parm, &pthandle->ptcl_tbl[index], sizeof(prtcol_tbl_t)); @@ -2506,15 +1332,17 @@ static int pce_tm_ptcl_tbl_read(pcetbl_prog_t *pthandle, /* PPPoE Table Write */ static int pce_tm_pppoe_tbl_write(void *cdev, - pcetbl_prog_t *pthandle, pce_ppoe_tbl_t *parm) + pcetbl_prog_t *pthandle, pce_ppoe_tbl_t *parm) { pctbl_prog_t ptbl; int pcindex; pcindex = tbl_write(pthandle->pppoe_tbl, - pthandle->pppoe_tbl_cnt, - parm, sizeof(pce_ppoe_tbl_t), PCE_PPPOE_TBL_SIZE); + pthandle->pppoe_tbl_cnt, + parm, sizeof(pce_ppoe_tbl_t), PCE_PPPOE_TBL_SIZE); + if (pcindex < 0) return pcindex; + /* initialize the data structure before using it */ memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PPPOE_INDEX; @@ -2527,27 +1355,30 @@ static int pce_tm_pppoe_tbl_write(void *cdev, /* PPPoE Table Delete */ static int pce_tm_pppoe_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { pctbl_prog_t ptbl; PCE_ASSERT(index >= PCE_PPPOE_TBL_SIZE); + if (pthandle->pppoe_tbl_cnt[index] > 0) pthandle->pppoe_tbl_cnt[index]--; + if (pthandle->pppoe_tbl_cnt[index] == 0) { memset((((char *)pthandle->pppoe_tbl) - + (index * sizeof(pce_ppoe_tbl_t))), - 0, sizeof(pce_ppoe_tbl_t)); + + (index * sizeof(pce_ppoe_tbl_t))), + 0, sizeof(pce_ppoe_tbl_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_PPPOE_INDEX; ptbl.pcindex = index; gsw_pce_table_write(cdev, &ptbl); } + return GSW_statusOk; } /* PPPoE Table Read */ static int pce_tm_pppoe_tbl_read(pcetbl_prog_t *pthandle, - int index, pce_ppoe_tbl_t *parm) + int index, pce_ppoe_tbl_t *parm) { PCE_ASSERT(index >= PCE_PPPOE_TBL_SIZE); memcpy(parm, &pthandle->pppoe_tbl[index], sizeof(pce_ppoe_tbl_t)); @@ -2556,52 +1387,61 @@ static int pce_tm_pppoe_tbl_read(pcetbl_prog_t *pthandle, /* VLAN Table Delete */ static int pce_tm_vlan_act_tbl_delete(void *cdev, - pcetbl_prog_t *pthandle, u32 index) + pcetbl_prog_t *pthandle, u32 index) { PCE_ASSERT(index >= PCE_VLAN_ACT_TBL_SIZE); + if (pthandle->vlan_act_tbl_cnt[index] > 0) pthandle->vlan_act_tbl_cnt[index]--; + return GSW_statusOk; } static u32 act_vlan_id_create(void *cdev, u16 vid, - int range_flag, u16 range_val) + int range_flag, u16 range_val) { pctbl_prog_t ptbl; u32 index, vid_index = 0x7F; + for (index = 0; index < PCE_VLAN_ACT_TBL_SIZE; index++) { memset(&ptbl, 0, sizeof(pctbl_prog_t)); ptbl.table = PCE_ACTVLAN_INDEX; ptbl.pcindex = index; gsw_pce_table_read(cdev, &ptbl); + if (ptbl.valid == 0) { ptbl.pcindex = index; vid_index = index; ptbl.table = PCE_ACTVLAN_INDEX; ptbl.key[0] = vid; + if (range_flag) ptbl.mask[0] = range_val; else ptbl.mask[0] = 0; + ptbl.valid = 1; ptbl.type = range_flag; gsw_pce_table_write(cdev, &ptbl); break; } } + return vid_index; } static int pce_vid_index(void *cdev, - pcetbl_prog_t *pthandle, u16 vid) + pcetbl_prog_t *pthandle, u16 vid) { pctbl_prog_t pcetable_vlan; int index, vid_index = 0x7F; + for (index = 0; index < PCE_VLAN_ACT_TBL_SIZE; index++) { memset(&pcetable_vlan, 0, sizeof(pctbl_prog_t)); pcetable_vlan.table = PCE_ACTVLAN_INDEX; pcetable_vlan.pcindex = index; gsw_pce_table_read(cdev, &pcetable_vlan); + if (pcetable_vlan.valid == 1) { if (pcetable_vlan.key[0] == vid) { vid_index = index; @@ -2610,19 +1450,22 @@ static int pce_vid_index(void *cdev, } } } + return vid_index; } static int pce_vlan_id_fid_index(void *cdev, - pcetbl_prog_t *pthandle, avlan_tbl_t *vatable) + pcetbl_prog_t *pthandle, avlan_tbl_t *vatable) { pctbl_prog_t pcetable_vlan; int index, vid_index = 0x7F; + for (index = 0; index < PCE_VLAN_ACT_TBL_SIZE; index++) { memset(&pcetable_vlan, 0, sizeof(pctbl_prog_t)); pcetable_vlan.table = PCE_ACTVLAN_INDEX; pcetable_vlan.pcindex = index; gsw_pce_table_read(cdev, &pcetable_vlan); + if (pcetable_vlan.valid == 1) { if (pcetable_vlan.key[0] == vatable->vid) { vid_index = index; @@ -2632,6 +1475,7 @@ static int pce_vlan_id_fid_index(void *cdev, } } } + return vid_index; } @@ -2643,8 +1487,10 @@ int pce_table_init(ltq_pce_table_t *ptable) memset(&ptable->pce_sub_tbl, 0, sizeof(pcetbl_prog_t)); memset(&ptable->pce_tbl, 0, sizeof(pce_table_t)); memset(&ptable->pce_act, 0, sizeof(GSW_PCE_action_t)); + for (i = 0; i < PCE_TABLE_SIZE; i++) ptable->ptblused[i] = 0; + return GSW_statusOk; } @@ -2655,13 +1501,15 @@ int gsw_pmicro_code_init(void *cdev) pctbl_prog_t tbl_entry; u16 i, j; u8 Gl_Mod_Size = 0; - u32 no_ports=0; - if (gswdev->gipver == LTQ_GSWIP_3_1) + u32 no_ports = 0; + + if (IS_VRSN_31(gswdev->gipver)) no_ports = gswdev->tpnum; - else + else no_ports = gswdev->pnum; - + printk("Enter PCE micro-code init\n"); + /* Disable all physical port */ for (j = 0; j < no_ports; j++) { gsw_w32(cdev, (FDMA_PCTRL_EN_OFFSET + (j * 0x6)), @@ -2673,7 +1521,7 @@ int gsw_pmicro_code_init(void *cdev) if (gswdev->gipver == LTQ_GSWIP_3_0) { /*GSWIP 3.0*/ gsw_w32(cdev, (GSWT_GCTRL_SE_OFFSET + 0xF00), - GSWT_GCTRL_SE_SHIFT, GSWT_GCTRL_SE_SIZE, 1); + GSWT_GCTRL_SE_SHIFT, GSWT_GCTRL_SE_SIZE, 1); /*Micro code set invalid*/ gsw_w32(cdev, PCE_GCTRL_0_MC_VALID_OFFSET, PCE_GCTRL_0_MC_VALID_SHIFT, PCE_GCTRL_0_MC_VALID_SIZE, 0x0); @@ -2690,12 +1538,12 @@ int gsw_pmicro_code_init(void *cdev) gsw_pce_table_write(cdev, &tbl_entry); //pr_err("%d\t%x\t%x\t%x\t%x\n",i, tbl_entry.val[0], tbl_entry.val[1], tbl_entry.val[2], tbl_entry.val[3]); } - }else if(gswdev->gipver == LTQ_GSWIP_3_1) { + } else if (IS_VRSN_31(gswdev->gipver)) { /*GSWIP 3.1*/ /*Micro code set invalid*/ gsw_w32(cdev, PCE_GCTRL_0_MC_VALID_OFFSET, PCE_GCTRL_0_MC_VALID_SHIFT, PCE_GCTRL_0_MC_VALID_SIZE, 0x0); - + /* Download the microcode */ for (i = 0; i < 256 /*PCE_MICRO_TABLE_SIZE*/; i++) { memset(&tbl_entry, 0, sizeof(pctbl_prog_t)); @@ -2708,7 +1556,7 @@ int gsw_pmicro_code_init(void *cdev) gsw_pce_table_write(cdev, &tbl_entry); //pr_err("%d\t%x\t%x\t%x\t%x\n",i, tbl_entry.val[0], tbl_entry.val[1], tbl_entry.val[2], tbl_entry.val[3]); } - + } else { /*GSWIP 2.2*/ gsw_w32(cdev, (GLOB_CTRL_SE_OFFSET + 0xC40), @@ -2728,12 +1576,13 @@ int gsw_pmicro_code_init(void *cdev) tbl_entry.table = PCE_PARS_INDEX; gsw_pce_table_write(cdev, &tbl_entry); } + gsw_w32(cdev, PCE_PMAP_2_DMCPMAP_OFFSET, PCE_PMAP_2_DMCPMAP_SHIFT, PCE_PMAP_2_DMCPMAP_SIZE, 0x7F); gsw_w32(cdev, PCE_PMAP_3_UUCMAP_OFFSET, PCE_PMAP_3_UUCMAP_SHIFT, PCE_PMAP_3_UUCMAP_SIZE, 0x7F); } - + /*Micro code set valid*/ gsw_w32(cdev, PCE_GCTRL_0_MC_VALID_OFFSET, PCE_GCTRL_0_MC_VALID_SHIFT, PCE_GCTRL_0_MC_VALID_SIZE, 0x1); @@ -2744,19 +1593,20 @@ int gsw_pmicro_code_init(void *cdev) gsw_w32(cdev, (BM_PCFG_CNTEN_OFFSET + (j * 0x2)), BM_PCFG_CNTEN_SHIFT, BM_PCFG_CNTEN_SIZE, 1); } + for (j = 0; j < gswdev->pnum; j++) { gsw_w32(cdev, (BM_RMON_CTRL_BCAST_CNT_OFFSET + (j * 0x2)), BM_RMON_CTRL_BCAST_CNT_SHIFT, BM_RMON_CTRL_BCAST_CNT_SIZE, 1); } } - - if ((gswdev->gipver == LTQ_GSWIP_2_2) || - (gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE2; + + if ((gswdev->gipver == LTQ_GSWIP_2_2) || + (gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE2; else - Gl_Mod_Size=BM_QUEUE_GCTRL_GL_MOD_SIZE; - + Gl_Mod_Size = BM_QUEUE_GCTRL_GL_MOD_SIZE; + gsw_w32(cdev, BM_QUEUE_GCTRL_GL_MOD_OFFSET, BM_QUEUE_GCTRL_GL_MOD_SHIFT, Gl_Mod_Size, 0); @@ -2769,7 +1619,7 @@ int pce_action_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index) pctbl_prog_t ptbl; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); PCE_ASSERT(index >= PCE_TABLE_SIZE); - memset(&ptbl, 0, sizeof(pctbl_prog_t)); + memset(&ptbl, 0, sizeof(pctbl_prog_t)); memset(&pthandle->pce_act[index], 0, sizeof(GSW_PCE_action_t)); /* Remove rule action from HW */ ptbl.pcindex = index; @@ -2777,15 +1627,18 @@ int pce_action_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index) ptbl.table = PCE_TFLOW_INDEX; //pr_err("\n Before pce table read in %s 0x%x", __func__, cdev); gsw_pce_table_read(cdev, &ptbl); + if (ptbl.valid == 1) { if (((ptbl.val[0] >> 1) & 0x1) && (gswdev->gipver == LTQ_GSWIP_3_0)) { u32 index = (ptbl.val[2] & 0x3F); pr_err("\n VLAN action delete at % index in %s", index, __func__); + if (pthandle->pce_sub_tbl.vlan_act_tbl_cnt[index] > 0) pthandle->pce_sub_tbl.vlan_act_tbl_cnt[index]--; } } - memset(&ptbl, 0, sizeof(pctbl_prog_t)); + + memset(&ptbl, 0, sizeof(pctbl_prog_t)); /* Remove rule action from HW */ ptbl.pcindex = index; /* Traffic-Flow table type */ @@ -2797,96 +1650,100 @@ int pce_action_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index) } #define IFX_PCE_TM_IDX_DELETE(x, y, z) { if (x != y) \ - if (0 != z(cdev, &pthandle->pce_sub_tbl, y)) \ - GSW_RETURN_PCE; } + if (0 != z(cdev, &pthandle->pce_sub_tbl, y)) \ + GSW_RETURN_PCE; } int pce_pattern_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index) { pce_table_t *ptable; - ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + PCE_ASSERT(index >= PCE_TABLE_SIZE); + /* Check if an entry is currently programmed and remove it. */ if (pthandle->ptblused[index] == 0) return GSW_statusOk; + ptable = &(pthandle->pce_tbl[index]); /* Packet length */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->pkt_lng_idx, - pce_tm_pkg_lng_tbl_delete) + pce_tm_pkg_lng_tbl_delete) /* Destination MAC address */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->dst_mac_addr_idx, - pce_tm_da_mac_tbl_delete) + pce_tm_da_mac_tbl_delete) /* Source MAC address */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->src_mac_addr_idx, - pce_tm_sa_mac_tbl_delete) + pce_tm_sa_mac_tbl_delete) /* Destination Application field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->dst_appl_fld_idx, - pce_tm_appl_tbl_delete) + pce_tm_appl_tbl_delete) /* Source Application field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->src_appl_fld_idx, - pce_tm_appl_tbl_delete) + pce_tm_appl_tbl_delete) /* Parer flags field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->parse_lsb_idx, - pce_tm_flags_tbl_delete) + pce_tm_flags_tbl_delete) /* Parer flags field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->parse_msb_idx, - pce_tm_flags_tbl_delete) + pce_tm_flags_tbl_delete) /* Parer flags field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->parse1_lsb_idx, - pce_tm_flags_tbl_delete) + pce_tm_flags_tbl_delete) /* Parer flags field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->parse1_msb_idx, - pce_tm_flags_tbl_delete) + pce_tm_flags_tbl_delete) /* Payload1 field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->payload1_idx, - pce_tm_payload_tbl_delete) + pce_tm_payload_tbl_delete) /* payload2 field */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->payload2_idx, - pce_tm_payload_tbl_delete) + pce_tm_payload_tbl_delete) /* DIP MSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->dip_msb_idx, - ip_dasa_msb_tbl_del) + ip_dasa_msb_tbl_del) /* Inner DIP MSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->inr_dip_msb_idx, - ip_dasa_msb_tbl_del) + ip_dasa_msb_tbl_del) /* DIP LSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->dip_lsb_idx, - ip_dasa_lsb_tbl_del) + ip_dasa_lsb_tbl_del) /* Inner DIP LSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->inr_dip_lsb_idx, - ip_dasa_lsb_tbl_del) + ip_dasa_lsb_tbl_del) /* SIP MSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->sip_msb_idx, - ip_dasa_msb_tbl_del) + ip_dasa_msb_tbl_del) /* Inner SIP MSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->inr_sip_msb_idx, - ip_dasa_msb_tbl_del) + ip_dasa_msb_tbl_del) /* SIP LSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->sip_lsb_idx, - ip_dasa_lsb_tbl_del) + ip_dasa_lsb_tbl_del) /* Inner SIP LSB */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->inr_sip_lsb_idx, - ip_dasa_lsb_tbl_del) + ip_dasa_lsb_tbl_del) /* IP protocol */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->ip_prot_idx, - pce_tm_ptcl_tbl_delete) + pce_tm_ptcl_tbl_delete) /* Ethertype */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->ethertype_idx, - pce_tm_ptcl_tbl_delete) + pce_tm_ptcl_tbl_delete) /* PPP Protocol */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->ppp_prot_idx, - pce_tm_ptcl_tbl_delete) + pce_tm_ptcl_tbl_delete) /* PPPoE */ IFX_PCE_TM_IDX_DELETE(0xFF, ptable->pppoe_idx, - pce_tm_pppoe_tbl_delete) + pce_tm_pppoe_tbl_delete) + if (gswdev->gipver == LTQ_GSWIP_3_0) { - /* VLAN */ - IFX_PCE_TM_IDX_DELETE(0x7F, ptable->vlan_idx, - pce_tm_vlan_act_tbl_delete) - /* SVLAN */ - IFX_PCE_TM_IDX_DELETE(0x7F, ptable->svlan_idx, - pce_tm_vlan_act_tbl_delete) + /* VLAN */ + IFX_PCE_TM_IDX_DELETE(0x7F, ptable->vlan_idx, + pce_tm_vlan_act_tbl_delete) + /* SVLAN */ + IFX_PCE_TM_IDX_DELETE(0x7F, ptable->svlan_idx, + pce_tm_vlan_act_tbl_delete) } + /* Mark this TFLOW entry as unused */ pthandle->ptblused[index] = 0; /* Mark all tables in TFLOW to invalid */ @@ -2894,14 +1751,8 @@ int pce_pattern_delete(void *cdev, ltq_pce_table_t *pthandle, u32 index) /* Delete the action for this rule */ pce_action_delete(cdev, pthandle, index); //Delete the associated counters if any. -#if 0 //Commented as we need to know the associated counter index to delete. - GSW_RMON_extendGet_t parm; - memset(&parm, 0, sizeof(GSW_RMON_extendGet_t)); - parm.nPortId = index; - parm.b64BitMode = 1; - GSW_RmonTflowClear(cdev, &parm); -#endif -return GSW_statusOk; + + return GSW_statusOk; } int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) @@ -2909,77 +1760,104 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); u32 i, j, idx = parm->pattern.nIndex; pce_table_t *ptable; - pctbl_prog_t ptbl; + static pctbl_prog_t ptbl; PCE_ASSERT(idx >= PCE_TABLE_SIZE); /* Initialize to zero */ memset(parm, 0, sizeof(GSW_PCE_rule_t)); memset(&ptbl, 0, sizeof(pctbl_prog_t)); parm->pattern.nIndex = idx; //Table entry to read + if (pthandle->ptblused[idx] == 0) return GSW_statusOk; //Return if entry is not in use else parm->pattern.bEnable = 1; - + ptbl.table = PCE_TFLOW_INDEX; //TFLOW table type to read ptbl.pcindex = idx; //Table entry to read gsw_pce_table_read(cdev, &ptbl); //Read given entry + /* Exclude flags */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if ((ptbl.key[15] >> 0) & 0x1) parm->pattern.bDstMAC_Exclude = 1; + if ((ptbl.key[15] >> 1) & 0x1) parm->pattern.bCTAG_PCP_DEI_Exclude = 1; + if ((ptbl.key[15] >> 2) & 0x1) parm->pattern.bSTAG_PCP_DEI_Exclude = 1; + if ((ptbl.key[15] >> 3) & 0x1) parm->pattern.bDSCP_Exclude = 1; + if ((ptbl.key[15] >> 4) & 0x1) parm->pattern.bPktLng_Exclude = 1; + if ((ptbl.key[15] >> 5) & 0x1) parm->pattern.bSessionId_Exclude = 1; + if ((ptbl.key[15] >> 6) & 0x1) parm->pattern.bSLANVid_Exclude = 1; + if ((ptbl.key[15] >> 7) & 0x1) parm->pattern.bPPP_Protocol_Exclude = 1; + if ((ptbl.key[15] >> 8) & 0x1) parm->pattern.bInnerDSCP_Exclude = 1; + if ((ptbl.key[15] >> 9) & 0x1) parm->pattern.bInnerSrcIP_Exclude = 1; + if ((ptbl.key[15] >> 10) & 0x1) parm->pattern.bInnerDstIP_Exclude = 1; + if ((ptbl.key[15] >> 11) & 0x1) parm->pattern.bParserFlagLSB_Exclude = 1; + if ((ptbl.key[15] >> 12) & 0x1) - parm->pattern.bParserFlagMSB_Exclude = 1; + parm->pattern.bParserFlagMSB_Exclude = 1; + if ((ptbl.key[15] >> 13) & 0x1) parm->pattern.bPayload1_Exclude = 1; + if ((ptbl.key[15] >> 14) & 0x1) parm->pattern.bPayload2_Exclude = 1; + if ((ptbl.key[15] >> 15) & 0x1) parm->pattern.bSubIfId_Exclude = 1; - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if ((ptbl.key[14] >> 5) & 0x1) parm->pattern.bParserFlag1LSB_Exclude = 1; + if ((ptbl.key[14] >> 6) & 0x1) parm->pattern.bParserFlag1MSB_Exclude = 1; - } + } + if ((ptbl.key[14] >> 7) & 0x1) parm->pattern.bPortId_Exclude = 1; + if ((ptbl.key[14] >> 8) & 0x1) parm->pattern.bVid_Exclude = 1; + if ((ptbl.key[14] >> 9) & 0x1) parm->pattern.bEtherType_Exclude = 1; + if ((ptbl.key[14] >> 10) & 0x1) parm->pattern.bProtocol_Exclude = 1; + if ((ptbl.key[14] >> 11) & 0x1) parm->pattern.bSrcIP_Exclude = 1; + if ((ptbl.key[14] >> 12) & 0x1) parm->pattern.bDstIP_Exclude = 1; + if ((ptbl.key[14] >> 13) & 0x1) parm->pattern.bAppMSB_Exclude = 1; + if ((ptbl.key[14] >> 14) & 0x1) parm->pattern.bAppLSB_Exclude = 1; + if ((ptbl.key[14] >> 15) & 0x1) parm->pattern.bSrcMAC_Exclude = 1; @@ -2992,26 +1870,28 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /*Sub -Interface id 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if ((ptbl.key[17] & 0x1FF) != 0x1FF) { //Is pattern enabled? parm->pattern.nSubIfId = ptbl.key[17] & 0xFF; parm->pattern.bSubIfIdEnable = 1; - if((ptbl.key[17] >> 9) & 0x1) - parm->pattern.eSubIfIdType = - GSW_PCE_SUBIFID_TYPE_BRIDGEPORT; + + if ((ptbl.key[17] >> 9) & 0x1) + parm->pattern.eSubIfIdType = + GSW_PCE_SUBIFID_TYPE_BRIDGEPORT; else parm->pattern.eSubIfIdType = GSW_PCE_SUBIFID_TYPE_GROUP; } + /* CPU injected traffic flag */ if (((ptbl.key[17] >> 10) & 0x3) != 3) { parm->pattern.bInsertionFlag_Enable = 1; - parm->pattern.nInsertionFlag = ((ptbl.key[17] >> 10) & 0x3); + parm->pattern.nInsertionFlag = ((ptbl.key[17] >> 10) & 0x3); } } } - + /* Port ID field value */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if ((ptbl.key[0] & 0x1F) != 0x1F) { //Is pattern enabled? parm->pattern.nPortId = ptbl.key[0] & 0xF; parm->pattern.bPortIdEnable = 1; @@ -3022,34 +1902,36 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) parm->pattern.bPortIdEnable = 1; } } + /* Outer DSCP field value */ if (((ptbl.key[6] >> 8) & 0x7F) != 0x7F) { //Is pattern enabled? parm->pattern.nDSCP = (ptbl.key[6] >> 8) & 0x3F; parm->pattern.bDSCP_Enable = 1; } - - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { /* Inner DSCP field value */ if (((ptbl.key[9] >> 8) & 0x7F) != 0x7F) { //Is pattern enabled? parm->pattern.nInnerDSCP = (ptbl.key[9] >> 8) & 0x3F; parm->pattern.bInner_DSCP_Enable = 1; } - + /* Port filer type action value */ parm->action.ePortFilterType_Action = (ptbl.val[7] >> 1) & 0x3F; - if(parm->action.ePortFilterType_Action == 4) + + if (parm->action.ePortFilterType_Action == 4) parm->action.ePortFilterType_Action = GSW_PCE_PORT_FILTER_ACTION_3; - else if(parm->action.ePortFilterType_Action == 8) + else if (parm->action.ePortFilterType_Action == 8) parm->action.ePortFilterType_Action = GSW_PCE_PORT_FILTER_ACTION_4; - else if(parm->action.ePortFilterType_Action == 16) + else if (parm->action.ePortFilterType_Action == 16) parm->action.ePortFilterType_Action = GSW_PCE_PORT_FILTER_ACTION_5; - else if(parm->action.ePortFilterType_Action == 32) + else if (parm->action.ePortFilterType_Action == 32) parm->action.ePortFilterType_Action = GSW_PCE_PORT_FILTER_ACTION_6; //GEt the port-member map. if (parm->action.ePortFilterType_Action) { - for(i = 0; i <= 7; i++) - parm->action.nForwardPortMap[i] = ptbl.val[i+10]; + for (i = 0; i <= 7; i++) + parm->action.nForwardPortMap[i] = ptbl.val[i + 10]; } /* Processing path type action value */ @@ -3057,32 +1939,38 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) parm->action.eProcessPath_Action = (ptbl.val[8] >> 1) & 0x3; /* L3 Routing type action value */ - if (gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { parm->action.bRtCtrlEna_Action = ptbl.val[9] & 0x1; parm->action.bRtAccelEna_Action = (ptbl.val[9] >> 1) & 0x1; parm->action.bRtInnerIPasKey_Action = (ptbl.val[9] >> 2) & 0x1; + if ((ptbl.val[9] >> 3) & 0x1) parm->action.bRtSrcIpMaskCmp_Action = 0; else parm->action.bRtSrcIpMaskCmp_Action = 1; + if ((ptbl.val[9] >> 4) & 0x1) parm->action.bRtDstIpMaskCmp_Action = 0; else parm->action.bRtDstIpMaskCmp_Action = 1; + if ((ptbl.val[9] >> 5) & 0x1) parm->action.bRtSrcPortMaskCmp_Action = 0; else parm->action.bRtSrcPortMaskCmp_Action = 1; + if ((ptbl.val[9] >> 6) & 0x1) parm->action.bRtDstPortMaskCmp_Action = 0; else parm->action.bRtDstPortMaskCmp_Action = 1; + if (((ptbl.val[9] >> 8) & 0xFF) != 0xFF) { parm->action.bRoutExtId_Action = 1; parm->action.nRoutExtId = (ptbl.val[9] >> 8) & 0xFF; } } + /* Flow ID action value */ if ((ptbl.val[4] >> 4) & 0x1) { parm->action.bFlowID_Action = 1; @@ -3095,29 +1983,31 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) parm->action.bPortTrunkAction = (ptbl.val[5] >> 0) & 0x1; /* Cross VLAN action value */ - if ((ptbl.val[0] >> 4) & 0x1) { - if((ptbl.val[3] >> 15) & 0x1) - parm->action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_CROSS; - else - parm->action.eVLAN_CrossAction = - GSW_PCE_ACTION_CROSS_VLAN_REGULAR; - } - + if ((ptbl.val[0] >> 4) & 0x1) { + if ((ptbl.val[3] >> 15) & 0x1) + parm->action.eVLAN_CrossAction = + GSW_PCE_ACTION_CROSS_VLAN_CROSS; + else + parm->action.eVLAN_CrossAction = + GSW_PCE_ACTION_CROSS_VLAN_REGULAR; + } + /* Applicable for 3.0*/ - if (gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { parm->action.bPortBitMapMuxControl = (ptbl.val[6] >> 0) & 0x1; + if (parm->action.bPortBitMapMuxControl) parm->action.nForwardPortMap[0] = ptbl.val[1]; + if (((ptbl.val[5] >> 2) & 0x1) && ((ptbl.val[0] >> 1) & 0x1)) parm->action.bCVLAN_Ignore_Control = 1; - + if ((ptbl.val[0] >> 1) & 0x1) { parm->action.eSVLAN_Action = 1; parm->action.nSVLAN_Id = (ptbl.val[6] >> 4) & 0xFFF; //parm->action.nFId = ((ptbl.val[2] >> 8) & 0xFF); } - + if ((ptbl.val[0] >> 1) & 0x1) { //Govind - 3.0 same flag for both eVLAN_Action n eSVLAN_Action? parm->action.eVLAN_Action = 1; parm->action.nVLAN_Id = (ptbl.val[5] >> 4) & 0xFFF; @@ -3125,55 +2015,60 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } } - //Extended VLAN tagging action. - if (gswdev->gipver == LTQ_GSWIP_3_1) { + //Extended VLAN tagging action. + if (IS_VRSN_31(gswdev->gipver)) { if ((ptbl.val[6] >> 3) & 0x1) { parm->action.bExtendedVlanEnable = 1; //Enable extended VLAN tagging. parm->action.nExtendedVlanBlockId = (ptbl.val[6] >> 4) & 0x3FF; - } + } } /* Applicable for 3.0*/ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if ((ptbl.val[0] >> 12) & 0x1) { parm->action.bRMON_Action = 1; parm->action.nRMON_Id = (((ptbl.val[4] >> 8) & 0x1F) - 1); } + if ((ptbl.val[0] >> 11) & 0x1) { parm->action.eMeterAction = (ptbl.val[3] >> 6) & 0x3; parm->action.nMeterId = ptbl.val[3] & 0x1F; } - + if (!((ptbl.val[3] >> 13) & 0x1)) - parm->action.bRemarkClass = 1; + parm->action.bRemarkClass = 1; + if (!((ptbl.val[3] >> 12) & 0x1)) parm->action.bRemarkDSCP = 1; + if (!((ptbl.val[6] >> 2) & 0x1)) parm->action.bRemarkSTAG_DEI = 1; + if (!((ptbl.val[6] >> 1) & 0x1)) - parm->action.bRemarkSTAG_PCP = 1; + parm->action.bRemarkSTAG_PCP = 1; + if (!((ptbl.val[3] >> 14) & 0x1)) parm->action.bRemarkPCP = 1; - + if ((ptbl.val[0] >> 3) & 0x1) parm->action.bRemarkAction = 1; - + if ((ptbl.val[0] >> 6) & 0x1) { if ((ptbl.val[4] >> 14) & 0x1) - parm->action.eCritFrameAction = - GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL; + parm->action.eCritFrameAction = + GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL; else - parm->action.eCritFrameAction = - GSW_PCE_ACTION_CRITICAL_FRAME_REGULAR; + parm->action.eCritFrameAction = + GSW_PCE_ACTION_CRITICAL_FRAME_REGULAR; } } /* RMON counter action value */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if ((ptbl.val[4] >> 4) & 0x1) { parm->action.bRMON_Action = parm->action.bFlowID_Action = 1; - parm->action.nRMON_Id = parm->action.nFlowID = - ptbl.val[1] & 0xFF; + parm->action.nRMON_Id = parm->action.nFlowID = + ptbl.val[1] & 0xFF; } /* Metering and counter action value */ @@ -3188,16 +2083,16 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* FID action control */ if ((ptbl.val[5] >> 3) & 0x1) { - parm->action.bFidEnable = 1; - parm->action.nFId = (ptbl.val[2] >> 8) & 0x3F; + parm->action.bFidEnable = 1; + parm->action.nFId = (ptbl.val[2] >> 8) & 0x3F; } } /* Applicable for 3.0*/ - if (gswdev->gipver == LTQ_GSWIP_3_0) { + if (gswdev->gipver == LTQ_GSWIP_3_0) { if (ptbl.val[0] & 0x1) { //If port-map action set. if (ptbl.val[1] == 0x0) { //If port-map IDs not set. - if (((ptbl.val[4] >> 2) & 0x3) == 0x3) { + if (((ptbl.val[4] >> 2) & 0x3) == 0x3) { //If port-map type is 'tflow'. parm->action.ePortMapAction = GSW_PCE_ACTION_PORTMAP_DISCARD; @@ -3208,25 +2103,26 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } } else if (ptbl.val[1] != 0x0) { //If port-map IDs set. parm->action.nForwardPortMap[0] = ptbl.val[1]; + if (((ptbl.val[4] >> 2) & 0x3) == 0x3) { //If port-map type is 'tflow'. parm->action.ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; } else if ((((ptbl.val[4] >> 2) & 0x3) == 0x1)) { //If port-map type is 'MC router'. - parm->action.ePortMapAction = + parm->action.ePortMapAction = GSW_PCE_ACTION_PORTMAP_CPU; } } } } - + /* Applicable for 3.1*/ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (ptbl.val[0] & 0x1) { //If port-map action set. if (!(ptbl.val[10]) && !(ptbl.val[11]) && !(ptbl.val[12]) && - !(ptbl.val[13]) && !(ptbl.val[14]) && !(ptbl.val[15]) && - !(ptbl.val[16]) && !(ptbl.val[17])) { + !(ptbl.val[13]) && !(ptbl.val[14]) && !(ptbl.val[15]) && + !(ptbl.val[16]) && !(ptbl.val[17])) { //If port-map IDs not set. if (((ptbl.val[4] >> 2) & 0x3) == 0x3) { //If port-map type is 'tflow'. @@ -3238,11 +2134,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) GSW_PCE_ACTION_PORTMAP_REGULAR; } } else if (((ptbl.val[10]) || (ptbl.val[11]) || (ptbl.val[12])) && - ((ptbl.val[13]) || (ptbl.val[14]) || (ptbl.val[15])) && - ((ptbl.val[16]) || (ptbl.val[17]))) { - /* It is 'traffic-flow' portmap type */ - for(i = 0; i <= 7; i++) - parm->action.nForwardPortMap[i] = ptbl.val[i+10]; + ((ptbl.val[13]) || (ptbl.val[14]) || (ptbl.val[15])) && + ((ptbl.val[16]) || (ptbl.val[17]))) { + /* It is 'traffic-flow' portmap type */ + for (i = 0; i <= 7; i++) + parm->action.nForwardPortMap[i] = ptbl.val[i + 10]; if (((ptbl.val[4] >> 2) & 0x3) == 0x3) { //If port-map type is 'tflow'. @@ -3250,7 +2146,7 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) GSW_PCE_ACTION_PORTMAP_ALTERNATIVE; } else if (((ptbl.val[4] >> 2) & 0x3) == 0x1) { //If port-map type is 'MC router'. - parm->action.ePortMapAction = + parm->action.ePortMapAction = GSW_PCE_ACTION_PORTMAP_CPU; } } @@ -3258,48 +2154,47 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* Color action */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if ((ptbl.val[0] >> 6) & 0x1) { if ((ptbl.val[2] & 0x7) < 4) { - parm->action.eColorFrameAction = + parm->action.eColorFrameAction = GSW_PCE_ACTION_COLOR_FRAME_NO_CHANGE; } else { - parm->action.eColorFrameAction = (ptbl.val[2] & 0x7) - 2; + parm->action.eColorFrameAction = (ptbl.val[2] & 0x7) - 2; } } } /* TS action control */ if ((ptbl.val[0] >> 7) & 0x1) { - if ((ptbl.val[4] >> 15) & 0x1) { - parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_STORED; + if ((ptbl.val[4] >> 15) & 0x1) { + parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_STORED; parm->action.nRecordId = ((ptbl.val[8] >> 4) & 0xFFF); - } - else - parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_REGULAR; - - } else - parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_DISABLE; + } else + parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_REGULAR; + + } else + parm->action.eTimestampAction = GSW_PCE_ACTION_TIMESTAMP_DISABLE; /* Cross state action control */ if ((ptbl.val[0] >> 5) & 0x1) { - if ((ptbl.val[4] >> 13) & 0x1) - parm->action.eCrossStateAction = - GSW_PCE_ACTION_CROSS_STATE_CROSS; - else - parm->action.eCrossStateAction = - GSW_PCE_ACTION_CROSS_STATE_REGULAR; - } else - parm->action.eCrossStateAction = GSW_PCE_ACTION_CROSS_STATE_DISABLE; + if ((ptbl.val[4] >> 13) & 0x1) + parm->action.eCrossStateAction = + GSW_PCE_ACTION_CROSS_STATE_CROSS; + else + parm->action.eCrossStateAction = + GSW_PCE_ACTION_CROSS_STATE_REGULAR; + } else + parm->action.eCrossStateAction = GSW_PCE_ACTION_CROSS_STATE_DISABLE; /* Interrupt Request Queue action control */ if ((ptbl.val[0] >> 8) & 0x1) { - if ((ptbl.val[0] >> 15) & 0x1) - parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_EVENT; - else - parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_REGULAR; - } else - parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_DISABLE; + if ((ptbl.val[0] >> 15) & 0x1) + parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_EVENT; + else + parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_REGULAR; + } else + parm->action.eIrqAction = GSW_PCE_ACTION_IRQ_DISABLE; /* MAC learning action control */ if ((ptbl.val[0] >> 9) & 0x1) { @@ -3318,32 +2213,31 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Traffic class action control */ if ((ptbl.val[0] >> 2) & 1) { if ((ptbl.val[0] >> 14) & 1) { - parm->action.eTrafficClassAction = + parm->action.eTrafficClassAction = GSW_PCE_ACTION_TRAFFIC_CLASS_ALTERNATIVE; parm->action.nTrafficClassAlternate = (ptbl.val[3] >> 8) & 0xF; - } - else - parm->action.eTrafficClassAction = - GSW_PCE_ACTION_TRAFFIC_CLASS_REGULAR; + } else + parm->action.eTrafficClassAction = + GSW_PCE_ACTION_TRAFFIC_CLASS_REGULAR; } } /* Inner CoS & DEI field value for 3.0 */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (((ptbl.key[6]) & 0xF) != 0xF) { parm->pattern.nPCP = (ptbl.key[6]) & 0x7; parm->pattern.bPCP_Enable = 1; } } - + /* Inner CoS & DEI field value for 3.1 */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (((ptbl.key[6]) & 0x1F) != 0x1F) { //Is pattern enabled? parm->pattern.nPCP = (ptbl.key[6]) & 0xF; parm->pattern.bPCP_Enable = 1; } } - + /* Outer CoS & DEI field value */ if (((ptbl.key[8]) & 0x1F) != 0x1F) { //Is pattern enabled? parm->pattern.nSTAG_PCP_DEI = (ptbl.key[8]) & 0xF; @@ -3352,14 +2246,17 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Packet length field table */ ptable = &(pthandle->pce_tbl[idx]); + if (ptable->pkt_lng_idx != 0xFF) { //Is table enabled? pce_pkt_length_t pkg_lng_tbl; memset(&pkg_lng_tbl, 0, sizeof(pce_pkt_length_t)); /* Packet length used */ parm->pattern.bPktLngEnable = 1; + if (0 != pce_tm_pkg_lng_tbl_read(&pthandle->pce_sub_tbl, - ptable->pkt_lng_idx, &pkg_lng_tbl)) + ptable->pkt_lng_idx, &pkg_lng_tbl)) GSW_RETURN_PCE; + /* Packet length */ parm->pattern.nPktLng = pkg_lng_tbl.pkg_lng; /* Packet length Range */ @@ -3370,15 +2267,19 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->dst_mac_addr_idx != 0xFF) { //Is table enabled? pce_da_prog_t da_mac_tbl; memset(&da_mac_tbl, 0, sizeof(pce_da_prog_t)); + if (0 != pce_tm_da_mac_tbl_read(&pthandle->pce_sub_tbl, - ptable->dst_mac_addr_idx, &da_mac_tbl)) + ptable->dst_mac_addr_idx, &da_mac_tbl)) GSW_RETURN_PCE; + /* Destination MAC address used */ parm->pattern.bMAC_DstEnable = 1; + /* Destination MAC address */ for (i = 0; i < 6; i++) parm->pattern.nMAC_Dst[i] = da_mac_tbl.mac[i]; - /* Destination MAC address mask */ + + /* Destination MAC address mask */ parm->pattern.nMAC_DstMask = da_mac_tbl.mac_mask; } @@ -3386,14 +2287,18 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->src_mac_addr_idx != 0xFF) { //Is table enabled? pce_sa_prog_t sa_mac_tbl; memset(&sa_mac_tbl, 0, sizeof(pce_sa_prog_t)); + if (0 != pce_tm_sa_mac_tbl_read(&pthandle->pce_sub_tbl, - ptable->src_mac_addr_idx, &sa_mac_tbl)) + ptable->src_mac_addr_idx, &sa_mac_tbl)) GSW_RETURN_PCE; + /* Destination MAC address used */ parm->pattern.bMAC_SrcEnable = 1; + /* Destination MAC address */ for (i = 0; i < 6; i++) parm->pattern.nMAC_Src[i] = sa_mac_tbl.mac[i]; + /* Destination MAC address mask */ parm->pattern.nMAC_SrcMask = sa_mac_tbl.mac_mask; } @@ -3402,9 +2307,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->payload1_idx != 0xFF) { //Is table enabled? payload_tbl_t payload_tbl; memset(&payload_tbl, 0, sizeof(payload_tbl_t)); + if (0 != pce_tm_payload_tbl_read(&pthandle->pce_sub_tbl, - ptable->payload1_idx, &payload_tbl)) + ptable->payload1_idx, &payload_tbl)) GSW_RETURN_PCE; + /* Destination Application used */ parm->pattern.bPayload1_SrcEnable = 1; /* Destination Application field */ @@ -3419,9 +2326,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->payload2_idx != 0xFF) { //Is table enabled? payload_tbl_t payload_tbl; memset(&payload_tbl, 0, sizeof(payload_tbl_t)); + if (0 != pce_tm_payload_tbl_read(&pthandle->pce_sub_tbl, - ptable->payload2_idx, &payload_tbl)) + ptable->payload2_idx, &payload_tbl)) GSW_RETURN_PCE; + /* Destination Application used */ parm->pattern.bPayload2_SrcEnable = 1; /* Destination Application field */ @@ -3436,9 +2345,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->dst_appl_fld_idx != 0xFF) { //Is table enabled? app_tbl_t appl_tbl; memset(&appl_tbl, 0, sizeof(app_tbl_t)); + if (0 != pce_tm_appl_tbl_read(&pthandle->pce_sub_tbl, - ptable->dst_appl_fld_idx, &appl_tbl)) + ptable->dst_appl_fld_idx, &appl_tbl)) GSW_RETURN_PCE; + /* Destination Application used */ parm->pattern.bAppDataMSB_Enable = 1; /* Destination Application field */ @@ -3453,9 +2364,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->src_appl_fld_idx != 0xFF) { //Is table enabled? app_tbl_t appl_tbl; memset(&appl_tbl, 0, sizeof(app_tbl_t)); + if (0 != pce_tm_appl_tbl_read(&pthandle->pce_sub_tbl, - ptable->src_appl_fld_idx, &appl_tbl)) + ptable->src_appl_fld_idx, &appl_tbl)) GSW_RETURN_PCE; + /* Source Application used */ parm->pattern.bAppDataLSB_Enable = 1; /* Source Application field */ @@ -3467,48 +2380,56 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* Parser flags field table */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if (ptable->parse_lsb_idx != 0xFF) { //Is table enabled? flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); + if (0 != pce_tm_flags_tbl_read(&pthandle->pce_sub_tbl, - ptable->parse_lsb_idx, &flags_tbl)) + ptable->parse_lsb_idx, &flags_tbl)) GSW_RETURN_PCE; + parm->pattern.bParserFlagLSB_Enable = 1; parm->pattern.nParserFlagLSB = flags_tbl.parser_flag_data; parm->pattern.nParserFlagLSB_Mask = flags_tbl.mask_value; } - + if (ptable->parse_msb_idx != 0xFF) { //Is table enabled? flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); + if (0 != pce_tm_flags_tbl_read(&pthandle->pce_sub_tbl, - ptable->parse_msb_idx, &flags_tbl)) + ptable->parse_msb_idx, &flags_tbl)) GSW_RETURN_PCE; + parm->pattern.bParserFlagMSB_Enable = 1; parm->pattern.nParserFlagMSB = flags_tbl.parser_flag_data; parm->pattern.nParserFlagMSB_Mask = flags_tbl.mask_value; } - + /* Parser flags field table extend */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (ptable->parse1_lsb_idx != 0xFF) { //Is table enabled? flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); + if (0 != pce_tm_flags_tbl_read(&pthandle->pce_sub_tbl, - ptable->parse1_lsb_idx, &flags_tbl)) + ptable->parse1_lsb_idx, &flags_tbl)) GSW_RETURN_PCE; + parm->pattern.bParserFlag1LSB_Enable = 1; parm->pattern.nParserFlag1LSB = flags_tbl.parser_flag_data; parm->pattern.nParserFlag1LSB_Mask = flags_tbl.mask_value; } - + if (ptable->parse1_msb_idx != 0xFF) { //Is table enabled? flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); + if (0 != pce_tm_flags_tbl_read(&pthandle->pce_sub_tbl, - ptable->parse1_msb_idx, &flags_tbl)) + ptable->parse1_msb_idx, &flags_tbl)) GSW_RETURN_PCE; + parm->pattern.bParserFlag1MSB_Enable = 1; parm->pattern.nParserFlag1MSB = flags_tbl.parser_flag_data; parm->pattern.nParserFlag1MSB_Mask = flags_tbl.mask_value; @@ -3518,10 +2439,10 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Inner DIP n SIP field table */ if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + (IS_VRSN_31(gswdev->gipver))) { /* DIP field table */ if ((ptable->inr_dip_msb_idx != 0xFF) - && (ptable->inr_dip_lsb_idx != 0xFF)) { //IPv6 + && (ptable->inr_dip_lsb_idx != 0xFF)) { //IPv6 pce_dasa_msb_t dasa_tbl; pce_dasa_lsb_t dasa_tbl_lsb; int i, j; @@ -3529,38 +2450,45 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl_lsb, 0, sizeof(pce_dasa_lsb_t)); /* Inner DIP MS8B used */ parm->pattern.eInnerDstIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_msb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_dip_msb_idx, &dasa_tbl)) + ptable->inr_dip_msb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate inner DIP MS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) parm->pattern.nInnerDstIP.nIPv6[i] = - (((dasa_tbl.imsb[j] & 0xFF) << 8) - | (dasa_tbl.imsb[j-1] & 0xFF)); + (((dasa_tbl.imsb[j] & 0xFF) << 8) + | (dasa_tbl.imsb[j - 1] & 0xFF)); + /* Inner DIP MS8B nibble mask */ for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerDstIP_Mask |= - (1 << ((i * 4) + j + 16)); + parm->pattern.nInnerDstIP_Mask |= + (1 << ((i * 4) + j + 16)); } } + /* Inner DIP LS8B used */ parm->pattern.eInnerDstIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_dip_lsb_idx, &dasa_tbl_lsb)) + ptable->inr_dip_lsb_idx, &dasa_tbl_lsb)) GSW_RETURN_PCE; + /* Populate inner DIP LS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) - parm->pattern.nInnerDstIP.nIPv6[i+4] = - (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) - | (dasa_tbl_lsb.ilsb[j-1] & 0xFF)); + parm->pattern.nInnerDstIP.nIPv6[i + 4] = + (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) + | (dasa_tbl_lsb.ilsb[j - 1] & 0xFF)); + /* Inner DIP LS8B nibble mask */ for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl_lsb.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerDstIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nInnerDstIP_Mask |= + (1 << ((i * 4) + j)); } } } else if (ptable->inr_dip_lsb_idx != 0xFF) { //IPv4 @@ -3568,27 +2496,32 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl, 0, sizeof(pce_dasa_lsb_t)); /*Inner DIP used */ parm->pattern.eInnerDstIP_Select = GSW_PCE_IP_V4; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_dip_lsb_idx, &dasa_tbl)) + ptable->inr_dip_lsb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Inner DIP used */ parm->pattern.nInnerDstIP.nIPv4 = (dasa_tbl.ilsb[0] - | (dasa_tbl.ilsb[1] << 8) - | (dasa_tbl.ilsb[2] << 16) - | (dasa_tbl.ilsb[3] << 24)); + | (dasa_tbl.ilsb[1] << 8) + | (dasa_tbl.ilsb[2] << 16) + | (dasa_tbl.ilsb[3] << 24)); + /* Inner DIP nibble mask */ for (i = 0; i < 2; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerDstIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nInnerDstIP_Mask |= + (1 << ((i * 4) + j)); } } + parm->pattern.nInnerDstIP_Mask |= 0xFF00; } + /* SIP field table */ if ((ptable->inr_sip_msb_idx != 0xFF) - && (ptable->inr_sip_lsb_idx != 0xFF)) { //IPv6 + && (ptable->inr_sip_lsb_idx != 0xFF)) { //IPv6 pce_dasa_msb_t dasa_tbl; pce_dasa_lsb_t dasa_tbl_lsb; int i, j; @@ -3596,38 +2529,45 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl_lsb, 0, sizeof(pce_dasa_lsb_t)); /* Inner SIP MS8B used */ parm->pattern.eInnerSrcIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_msb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_sip_msb_idx, &dasa_tbl)) + ptable->inr_sip_msb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate inner SIP MS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) parm->pattern.nInnerSrcIP.nIPv6[i] = - (((dasa_tbl.imsb[j] & 0xFF) << 8) - | (dasa_tbl.imsb[j-1] & 0xFF)); + (((dasa_tbl.imsb[j] & 0xFF) << 8) + | (dasa_tbl.imsb[j - 1] & 0xFF)); + /* Inner SIP MS8B nibble mask */ for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerSrcIP_Mask |= - (1 << ((i * 4) + j + 16)); + parm->pattern.nInnerSrcIP_Mask |= + (1 << ((i * 4) + j + 16)); } } + /* Inner SIP LS8B used */ parm->pattern.eInnerSrcIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_sip_lsb_idx, &dasa_tbl_lsb)) + ptable->inr_sip_lsb_idx, &dasa_tbl_lsb)) GSW_RETURN_PCE; + /* Populate inner SIP LS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) - parm->pattern.nInnerSrcIP.nIPv6[i+4] = - (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) - | (dasa_tbl_lsb.ilsb[j-1] & 0xFF)); + parm->pattern.nInnerSrcIP.nIPv6[i + 4] = + (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) + | (dasa_tbl_lsb.ilsb[j - 1] & 0xFF)); + /* Inner DIP LS8B nibble mask */ for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl_lsb.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerSrcIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nInnerSrcIP_Mask |= + (1 << ((i * 4) + j)); } } } else if (ptable->inr_sip_lsb_idx != 0xFF) { //IPv4 @@ -3635,31 +2575,35 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl, 0, sizeof(pce_dasa_lsb_t)); /* Inner SIP used */ parm->pattern.eInnerSrcIP_Select = GSW_PCE_IP_V4; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->inr_sip_lsb_idx, &dasa_tbl)) + ptable->inr_sip_lsb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate inner SIP */ parm->pattern.nInnerSrcIP.nIPv4 = (dasa_tbl.ilsb[0] - | (dasa_tbl.ilsb[1] << 8) - | (dasa_tbl.ilsb[2] << 16) - | (dasa_tbl.ilsb[3] << 24)); + | (dasa_tbl.ilsb[1] << 8) + | (dasa_tbl.ilsb[2] << 16) + | (dasa_tbl.ilsb[3] << 24)); + /* Inner SIP nibble mask */ for (i = 0; i < 2; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nInnerSrcIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nInnerSrcIP_Mask |= + (1 << ((i * 4) + j)); } } + parm->pattern.nInnerSrcIP_Mask |= 0xFF00; - } + } } /*LTQ_GSWIP_3_0*/ /* Outer DIP n SIP field table */ /* DIP field table */ if ((ptable->dip_msb_idx != 0xFF) - && (ptable->dip_lsb_idx != 0xFF)) { //IPv6 + && (ptable->dip_lsb_idx != 0xFF)) { //IPv6 pce_dasa_msb_t dasa_tbl; pce_dasa_lsb_t dasa_tbl_lsb; int i, j; @@ -3667,44 +2611,51 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl_lsb, 0, sizeof(pce_dasa_lsb_t)); /* DIP MS8B used */ parm->pattern.eDstIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_msb_tbl_read(&pthandle->pce_sub_tbl, - ptable->dip_msb_idx, &dasa_tbl)) + ptable->dip_msb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate DIP MS8B used */ for (i = 0, j = 7; i < 4; i++, j -= 2) parm->pattern.nDstIP.nIPv6[i] = - (((dasa_tbl.imsb[j] & 0xFF) << 8) - | (dasa_tbl.imsb[j-1] & 0xFF)); + (((dasa_tbl.imsb[j] & 0xFF) << 8) + | (dasa_tbl.imsb[j - 1] & 0xFF)); + /* DIP MS8B nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nDstIP_Mask |= - (1 << ((i * 4) + j + 16)); + parm->pattern.nDstIP_Mask |= + (1 << ((i * 4) + j + 16)); } } } else if (gswdev->gipver == LTQ_GSWIP_2_2) parm->pattern.nDstIP_Mask = dasa_tbl.mask[0] << 16; + /* DIP LS8B used */ parm->pattern.eDstIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->dip_lsb_idx, &dasa_tbl_lsb)) + ptable->dip_lsb_idx, &dasa_tbl_lsb)) GSW_RETURN_PCE; + /* Populate DIP LS8B used */ for (i = 0, j = 7; i < 4; i++, j -= 2) - parm->pattern.nDstIP.nIPv6[i+4] = - (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) - | (dasa_tbl_lsb.ilsb[j-1] & 0xFF)); + parm->pattern.nDstIP.nIPv6[i + 4] = + (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) + | (dasa_tbl_lsb.ilsb[j - 1] & 0xFF)); + /* Inner DIP LS8B nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl_lsb.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nDstIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nDstIP_Mask |= + (1 << ((i * 4) + j)); } } } else if (gswdev->gipver == LTQ_GSWIP_2_2) @@ -3714,31 +2665,36 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl, 0, sizeof(pce_dasa_lsb_t)); /* DIP used */ parm->pattern.eDstIP_Select = GSW_PCE_IP_V4; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->dip_lsb_idx, &dasa_tbl)) + ptable->dip_lsb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate DIP */ parm->pattern.nDstIP.nIPv4 = (dasa_tbl.ilsb[0] - | (dasa_tbl.ilsb[1] << 8) - | (dasa_tbl.ilsb[2] << 16) - | (dasa_tbl.ilsb[3] << 24)); + | (dasa_tbl.ilsb[1] << 8) + | (dasa_tbl.ilsb[2] << 16) + | (dasa_tbl.ilsb[3] << 24)); + /* DIP nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 2; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nDstIP_Mask |= (1 << ((i *4) + j)); + parm->pattern.nDstIP_Mask |= (1 << ((i * 4) + j)); } } + parm->pattern.nDstIP_Mask |= 0xFF00; } else if (gswdev->gipver == LTQ_GSWIP_2_2) parm->pattern.nDstIP_Mask = dasa_tbl.mask[0]; } + /* SIP field table */ if ((ptable->sip_msb_idx != 0xFF) - && (ptable->sip_lsb_idx != 0xFF)) { //IPv6 + && (ptable->sip_lsb_idx != 0xFF)) { //IPv6 pce_dasa_msb_t dasa_tbl; pce_dasa_lsb_t dasa_tbl_lsb; int i, j; @@ -3746,44 +2702,51 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl_lsb, 0, sizeof(pce_dasa_lsb_t)); /* SIP MS8B used */ parm->pattern.eSrcIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_msb_tbl_read(&pthandle->pce_sub_tbl, - ptable->sip_msb_idx, &dasa_tbl)) + ptable->sip_msb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate SIP MS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) parm->pattern.nSrcIP.nIPv6[i] = - (((dasa_tbl.imsb[j] & 0xFF) << 8) - | (dasa_tbl.imsb[j-1] & 0xFF)); + (((dasa_tbl.imsb[j] & 0xFF) << 8) + | (dasa_tbl.imsb[j - 1] & 0xFF)); + /* Inner DIP MS8B nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nSrcIP_Mask |= - (1 << ((i * 4) + j + 16)); + parm->pattern.nSrcIP_Mask |= + (1 << ((i * 4) + j + 16)); } } } else if (gswdev->gipver == LTQ_GSWIP_2_2) parm->pattern.nSrcIP_Mask = dasa_tbl.mask[0] << 16; + /* SIP LS8B used */ parm->pattern.eSrcIP_Select = GSW_PCE_IP_V6; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->sip_lsb_idx, &dasa_tbl_lsb)) + ptable->sip_lsb_idx, &dasa_tbl_lsb)) GSW_RETURN_PCE; + /* Populate SIP LS8B */ for (i = 0, j = 7; i < 4; i++, j -= 2) - parm->pattern.nSrcIP.nIPv6[i+4] = - (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) - | (dasa_tbl_lsb.ilsb[j-1] & 0xFF)); + parm->pattern.nSrcIP.nIPv6[i + 4] = + (((dasa_tbl_lsb.ilsb[j] & 0xFF) << 8) + | (dasa_tbl_lsb.ilsb[j - 1] & 0xFF)); + /* Inner DIP LS8B nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl_lsb.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nSrcIP_Mask |= - (1 << ((i *4) + j)); + parm->pattern.nSrcIP_Mask |= + (1 << ((i * 4) + j)); } } } else if (gswdev->gipver == LTQ_GSWIP_2_2) @@ -3793,23 +2756,27 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&dasa_tbl, 0, sizeof(pce_dasa_lsb_t)); /* SIP used */ parm->pattern.eSrcIP_Select = GSW_PCE_IP_V4; + if (0 != pce_dasa_lsb_tbl_read(&pthandle->pce_sub_tbl, - ptable->sip_lsb_idx, &dasa_tbl)) + ptable->sip_lsb_idx, &dasa_tbl)) GSW_RETURN_PCE; + /* Populate SIP used */ parm->pattern.nSrcIP.nIPv4 = (dasa_tbl.ilsb[0] - | (dasa_tbl.ilsb[1] << 8) - | (dasa_tbl.ilsb[2] << 16) - | (dasa_tbl.ilsb[3] << 24)); + | (dasa_tbl.ilsb[1] << 8) + | (dasa_tbl.ilsb[2] << 16) + | (dasa_tbl.ilsb[3] << 24)); + /* SIP nibble mask */ - if ((gswdev->gipver == LTQ_GSWIP_3_0) || - (gswdev->gipver == LTQ_GSWIP_3_1)) { + if ((gswdev->gipver == LTQ_GSWIP_3_0) || + (IS_VRSN_31(gswdev->gipver))) { for (i = 0; i < 2; i++) { for (j = 0; j < 4; j++) { if (((dasa_tbl.mask[i] >> (j * 4)) & 0xF) == 0xF) - parm->pattern.nSrcIP_Mask |= (1 << ((i *4) + j)); + parm->pattern.nSrcIP_Mask |= (1 << ((i * 4) + j)); } } + parm->pattern.nSrcIP_Mask |= 0xFF00; } else if (gswdev->gipver == LTQ_GSWIP_2_2) parm->pattern.nSrcIP_Mask = dasa_tbl.mask[0]; @@ -3821,9 +2788,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); /* Ethertype used */ parm->pattern.bEtherTypeEnable = 1; + if (0 != pce_tm_ptcl_tbl_read(&pthandle->pce_sub_tbl, - ptable->ethertype_idx, &pctl_tbl)) + ptable->ethertype_idx, &pctl_tbl)) GSW_RETURN_PCE; + /* Ethertype */ parm->pattern.nEtherType = pctl_tbl.ethertype; /* Ethertype Mask */ @@ -3831,15 +2800,17 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* Protocol field table */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if (ptable->ppp_prot_idx != 0xFF) { prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); /* Ethertype used */ parm->pattern.bPPP_ProtocolEnable = 1; + if (0 != pce_tm_ptcl_tbl_read(&pthandle->pce_sub_tbl, - ptable->ppp_prot_idx, &pctl_tbl)) + ptable->ppp_prot_idx, &pctl_tbl)) GSW_RETURN_PCE; + /* Ethertype */ parm->pattern.nPPP_Protocol = pctl_tbl.ethertype; /* Ethertype Mask */ @@ -3852,18 +2823,22 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (ptable->ip_prot_idx != 0xFF) { prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); + /* IP protocol used */ if (0 != pce_tm_ptcl_tbl_read(&pthandle->pce_sub_tbl, - ptable->ip_prot_idx, &pctl_tbl)) + ptable->ip_prot_idx, &pctl_tbl)) GSW_RETURN_PCE; + if ((pctl_tbl.ethertype & 0xFF) == 0xFF) parm->pattern.bProtocolEnable = 0; else parm->pattern.bProtocolEnable = 1; + if (((pctl_tbl.ethertype >> 8) & 0xFF) == 0xFF) parm->pattern.bInnerProtocolEnable = 0; else parm->pattern.bInnerProtocolEnable = 1; + /* IP protocol */ parm->pattern.nProtocol = pctl_tbl.ethertype & 0xFF; /* IP protocol Mask */ @@ -3882,15 +2857,17 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&pppoe_tbl, 0, sizeof(pce_ppoe_tbl_t)); /* PPPoE used */ parm->pattern.bSessionIdEnable = 1; + if (0 != pce_tm_pppoe_tbl_read(&pthandle->pce_sub_tbl, - ptable->pppoe_idx, &pppoe_tbl)) + ptable->pppoe_idx, &pppoe_tbl)) GSW_RETURN_PCE; + /* PPPoE */ parm->pattern.nSessionId = pppoe_tbl.sess_id; } /* VLAN-ID field table */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { /* Inner VLAN-ID field table */ if (ptable->vlan_idx != 0x7F) { pctbl_prog_t pcetable_vlan; @@ -3902,9 +2879,11 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pcetable_vlan.pcindex = ptable->vlan_idx; /* ptbl.key[0] = parm->nVId; */ gsw_pce_table_read(cdev, &pcetable_vlan); + if (pcetable_vlan.valid == 1) parm->pattern.nVid = pcetable_vlan.key[0] & 0xFFF; } + /* Outer VLAN-ID field table */ if (ptable->svlan_idx != 0x7F) { pctbl_prog_t pcetable_vlan; @@ -3916,29 +2895,32 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pcetable_vlan.pcindex = ptable->svlan_idx; /* ptbl.key[0] = parm->nVId; */ gsw_pce_table_read(cdev, &pcetable_vlan); + if (pcetable_vlan.valid == 1) parm->pattern.nSLAN_Vid = pcetable_vlan.key[0] & 0xFFF; } } /* VLAN-ID field table */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { /*Inner vlan -CTAG VLAN index*/ if ((ptbl.key[20] & 0x1FFF) != 0x1FFF) { parm->pattern.bVid = 1; parm->pattern.nVid = ptbl.key[20] & 0xFFF; parm->pattern.bVid_Original = (ptbl.key[20] >> 15) & 1; + if ((ptbl.key[21] & 0xFFF) != 0) { parm->pattern.bVidRange_Select = 1; parm->pattern.nVidRange = ptbl.key[21] & 0xFFF; } } - /*Outer vlan -STAG VLAN index*/ + /*Outer vlan -STAG VLAN index*/ if ((ptbl.key[18] & 0x1FFF) != 0x1FFF) { parm->pattern.bSLAN_Vid = 1; parm->pattern.nSLAN_Vid = ptbl.key[18] & 0xFFF; parm->pattern.bOuterVid_Original = (ptbl.key[18] >> 15) & 1; + if ((ptbl.key[19] & 0xFFF) != 0) { parm->pattern.bSVidRange_Select = 1; parm->pattern.nOuterVidRange = ptbl.key[19] & 0xFFF; @@ -3954,57 +2936,65 @@ int pce_rule_read(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /*OAM and extraction packet control*/ parm->action.nRecordId = ((ptbl.val[8] >> 4) & 0xFFF); } + /*Extraction flag*/ if ((ptbl.val[7] >> 8) & 0x1) { parm->action.bExtractEnable = 1; } } - + return GSW_statusOk; } int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) { ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - pctbl_prog_t ptbl; + static pctbl_prog_t ptbl; u32 idx = parm->pattern.nIndex; pce_table_t *ptable; GSW_PCE_action_t *paction; - GSW_PCE_rule_t key_current; + static GSW_PCE_rule_t key_current; int tindex, i, reg_val = 0; signed int status; PCE_ASSERT(idx >= PCE_TABLE_SIZE); + if (parm->pattern.bEnable == 0) { /* Entry to delete. */ return pce_pattern_delete(cdev, pthandle, idx); } + /* Read the rule at given index to check if it is indeed same as current */ key_current.pattern.nIndex = idx; + if (pce_rule_read(cdev, pthandle, &key_current) != 0) GSW_RETURN_PCE; - /* Check if rule already exists */ + + /* Check if rule already exists */ if (!memcmp(&key_current, parm, sizeof(GSW_PCE_rule_t))) { pr_err("\n Rule already exists\n"); return GSW_statusOk; } + /* Init the TFOW table entry to zero */ memset(&ptbl, 0, sizeof(pctbl_prog_t)); gsw_r32(cdev, PCE_GCTRL_1_VLANMD_OFFSET, - PCE_GCTRL_1_VLANMD_SHIFT, - PCE_GCTRL_1_VLANMD_SIZE, ®_val); + PCE_GCTRL_1_VLANMD_SHIFT, + PCE_GCTRL_1_VLANMD_SIZE, ®_val); + /* Clean the old entry before adding the new one. */ if (pthandle->ptblused[idx] != 0) { if (pce_pattern_delete(cdev, pthandle, idx) != 0) GSW_RETURN_PCE; } + /* Mark the entry as used */ pthandle->ptblused[idx] = 1; /* Other tables to refer for this TFLOW entry */ ptable = &(pthandle->pce_tbl[idx]); /* Populate 'match' parameter values */ - /* Pattern field - PortID value */ + /* Pattern field - PortID value */ if (parm->pattern.bPortIdEnable == 1) ptbl.key[0] = (parm->pattern.nPortId & 0x0F); else @@ -4017,14 +3007,15 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ptbl.key[6] |= (0x7F << 8); //Mark as don't care. /* Pattern field - Inner DSCP value */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bInner_DSCP_Enable == 1) ptbl.key[9] |= ((parm->pattern.nInnerDSCP & 0x3F) << 8); else ptbl.key[9] |= (0x7F << 8); //Mark as don't care. } + /* Pattern field - inner PCP n DEI value */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bPCP_Enable == 1) ptbl.key[6] |= (parm->pattern.nPCP & 0xF); else @@ -4035,7 +3026,7 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) else ptbl.key[6] |= 0xF; //Mark as don't care. } - + /* Pattern field - outer PCP n DEI value */ if (parm->pattern.bSTAG_PCP_DEI_Enable == 1) { /* PCP value */ @@ -4051,87 +3042,106 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pkg_lng.pkg_lng = parm->pattern.nPktLng; /* Packet length range, in number of bytes */ pkg_lng.pkg_lng_rng = parm->pattern.nPktLngRange; - tindex = pce_tm_pkg_lng_tbl_write(cdev, &pthandle->pce_sub_tbl, - &pkg_lng); + tindex = pce_tm_pkg_lng_tbl_write(cdev, &pthandle->pce_sub_tbl, + &pkg_lng); + if (tindex < 0) return tindex; + ptable->pkt_lng_idx = tindex; } else { ptable->pkt_lng_idx = 0xFF; //Mark as don't care. } + ptbl.key[7] |= ptable->pkt_lng_idx; /* Pattern field - Destination MAC address field table */ if (parm->pattern.bMAC_DstEnable == 1) { pce_da_prog_t da_mac_tbl; + for (i = 0; i < 6; i++) da_mac_tbl.mac[i] = parm->pattern.nMAC_Dst[i]; + da_mac_tbl.mac_mask = parm->pattern.nMAC_DstMask; - tindex = pce_da_mac_tbl_write(cdev, &pthandle->pce_sub_tbl, - &da_mac_tbl); + tindex = pce_da_mac_tbl_write(cdev, &pthandle->pce_sub_tbl, + &da_mac_tbl); + if (tindex < 0) return tindex; + ptable->dst_mac_addr_idx = tindex; } else { ptable->dst_mac_addr_idx = 0xFF; //Mark as don't care. } - ptbl.key[5] |= (ptable->dst_mac_addr_idx << 8); - + + ptbl.key[5] |= (ptable->dst_mac_addr_idx << 8); + /* Pattern field - Source MAC address field table */ if (parm->pattern.bMAC_SrcEnable == 1) { pce_sa_prog_t sa_mac_tbl; + for (i = 0; i < 6; i++) sa_mac_tbl.mac[i] = parm->pattern.nMAC_Src[i]; + /* Source MAC address mask */ sa_mac_tbl.mac_mask = parm->pattern.nMAC_SrcMask; - tindex = pce_sa_mac_tbl_write(cdev, &pthandle->pce_sub_tbl, - &sa_mac_tbl); + tindex = pce_sa_mac_tbl_write(cdev, &pthandle->pce_sub_tbl, + &sa_mac_tbl); + if (tindex < 0) return tindex; + ptable->src_mac_addr_idx = tindex; } else { ptable->src_mac_addr_idx = 0xFF; //Mark as don't care. } + ptbl.key[5] |= ptable->src_mac_addr_idx; /* Pattern field - Parser Flags field table */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { - /* Parser flags 15:0 */ + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { + /* Parser flags 15:0 */ if (parm->pattern.bParserFlagLSB_Enable == 1) { flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); flags_tbl.parser_flag_data = parm->pattern.nParserFlagLSB; flags_tbl.mask_value = parm->pattern.nParserFlagLSB_Mask; flags_tbl.valid = 1; - tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, - &flags_tbl); + tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, + &flags_tbl); + if (tindex < 0) return tindex; + ptable->parse_lsb_idx = tindex; } else { ptable->parse_lsb_idx = 0xFF; //Mark as don't care. } + ptbl.key[12] |= ptable->parse_lsb_idx; /* Parser flags 47:32 */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - if (parm->pattern.bParserFlag1LSB_Enable == 1 ) { + if (IS_VRSN_31(gswdev->gipver)) { + if (parm->pattern.bParserFlag1LSB_Enable == 1) { flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); flags_tbl.parser_flag_data = parm->pattern.nParserFlag1LSB; flags_tbl.mask_value = parm->pattern.nParserFlag1LSB_Mask; flags_tbl.valid = 1; - tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, - &flags_tbl); + tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, + &flags_tbl); + if (tindex < 0) return tindex; + ptable->parse1_lsb_idx = tindex; } else { ptable->parse1_lsb_idx = 0xFF; //Mark as don't care. - } + } + ptbl.key[16] |= ptable->parse1_lsb_idx; } - + /* Parser flags 31:16 */ if (parm->pattern.bParserFlagMSB_Enable == 1) { flag_tbl_t flags_tbl; @@ -4139,32 +3149,38 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) flags_tbl.parser_flag_data = parm->pattern.nParserFlagMSB; flags_tbl.mask_value = parm->pattern.nParserFlagMSB_Mask; flags_tbl.valid = 1; - tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, - &flags_tbl); + tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, + &flags_tbl); + if (tindex < 0) return tindex; + ptable->parse_msb_idx = tindex; } else { ptable->parse_msb_idx = 0xFF; //Mark as don't care. } + ptbl.key[12] |= (ptable->parse_msb_idx << 8); /* Parser flags 63:48 */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bParserFlag1MSB_Enable == 1) { flag_tbl_t flags_tbl; memset(&flags_tbl, 0, sizeof(flag_tbl_t)); flags_tbl.parser_flag_data = parm->pattern.nParserFlag1MSB; flags_tbl.mask_value = parm->pattern.nParserFlag1MSB_Mask; flags_tbl.valid = 1; - tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, - &flags_tbl); + tindex = pce_flags_tbl_write(cdev, &pthandle->pce_sub_tbl, + &flags_tbl); + if (tindex < 0) return tindex; + ptable->parse1_msb_idx = tindex; } else { ptable->parse1_msb_idx = 0xFF; //Mark as don't care. } + ptbl.key[16] |= (ptable->parse1_msb_idx << 8); } @@ -4177,14 +3193,17 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) payload_tbl.payload_data = parm->pattern.nPayload1; payload_tbl.mask_range = parm->pattern.nPayload1_Mask; payload_tbl.valid = 1; - tindex = pce_payload_tbl_write(cdev, &pthandle->pce_sub_tbl, - &payload_tbl); + tindex = pce_payload_tbl_write(cdev, &pthandle->pce_sub_tbl, + &payload_tbl); + if (tindex < 0) return tindex; + ptable->payload1_idx = tindex; } else { ptable->payload1_idx = 0xFF; //Mark as don't care. } + ptbl.key[13] |= ptable->payload1_idx; /* Pattern field - Payload2 used */ @@ -4197,14 +3216,17 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Destination Application mask/range */ payload_tbl.mask_range = parm->pattern.nPayload2_Mask; payload_tbl.valid = 1; - tindex = pce_payload_tbl_write(cdev, &pthandle->pce_sub_tbl, - &payload_tbl); + tindex = pce_payload_tbl_write(cdev, &pthandle->pce_sub_tbl, + &payload_tbl); + if (tindex < 0) return tindex; + ptable->payload2_idx = tindex; } else { ptable->payload2_idx = 0xFF; //Mark as don't care. } + ptbl.key[13] |= (ptable->payload2_idx << 8); } @@ -4217,14 +3239,17 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Destination Application mask/range */ appl_tbl.mask_range = parm->pattern.nAppMaskRangeMSB; tindex = pce_appl_tbl_write(cdev, &pthandle->pce_sub_tbl, &appl_tbl); + if (tindex < 0) return tindex; + ptable->dst_appl_fld_idx = tindex; } else { ptable->dst_appl_fld_idx = 0xFF; //Mark as don't care. } + ptbl.key[4] |= ptable->dst_appl_fld_idx; - + /* Pattern field - Source Application field used */ if (parm->pattern.bAppDataLSB_Enable == 1) { app_tbl_t appl_tbl; @@ -4234,17 +3259,21 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Source Application mask/range */ appl_tbl.mask_range = parm->pattern.nAppMaskRangeLSB; tindex = pce_appl_tbl_write(cdev, &pthandle->pce_sub_tbl, &appl_tbl); + if (tindex < 0) return tindex; + ptable->src_appl_fld_idx = tindex; } else { ptable->src_appl_fld_idx = 0xFF; //Mark as don't care. } + ptbl.key[4] |= (ptable->src_appl_fld_idx << 8); /* Pattern field - outer DIP field table */ ptable->dip_msb_idx = 0xFF; //Mark as don't care. ptable->dip_lsb_idx = 0xFF; //Mark as don't care. + /* DIP MSB used - IPv6 bits 127:64 */ if (parm->pattern.eDstIP_Select == GSW_PCE_IP_V6) { pce_dasa_msb_t mtbl; @@ -4253,100 +3282,119 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) u16 maskNibble; memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->pattern.nDstIP.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->pattern.nDstIP.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->pattern.nDstIP.nIPv6[i] >> 8) & 0xFF); } - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { //mtbl.nmask = (u16)((parm->pattern.nDstIP_Mask >> 16) & 0xFFFF); for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nDstIP_Mask >> ((i * 4) + 16)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - mtbl.mask[i] |= (0xF << (j*4)); + mtbl.mask[i] |= (0xF << (j * 4)); } } } else { mtbl.mask[0] = (u16)((parm->pattern.nDstIP_Mask >> 16) & 0xFFFF); } + mtbl.valid = 1; tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, &mtbl); + if (tindex < 0) { pr_err("%s:%s:%d(DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->dip_msb_idx = tindex; - + /* DIP LSB used - IPv6 bits 63:0 */ /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->pattern.nDstIP.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->pattern.nDstIP.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->pattern.nDstIP.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->pattern.nDstIP.nIPv6[i + 4] >> 8) & 0xFF); } - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { //ltbl.nmask = (u16)(parm->pattern.nDstIP_Mask & 0xFFFF); for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nDstIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } } else { ltbl.mask[0] = (u16)(parm->pattern.nDstIP_Mask & 0xFFFF); } + ltbl.valid = 1; tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->dip_lsb_idx = tindex; } else if (parm->pattern.eDstIP_Select == GSW_PCE_IP_V4) { /* DIP LSB used - IPv4 bits 31:0 */ pce_dasa_lsb_t ltbl; memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->pattern.nDstIP.nIPv4 >> (i * 8)) & 0xFF); - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { int j; u16 maskNibble; + //ltbl.nmask = (u16)(parm->pattern.nDstIP_Mask) & 0xFFFF; for (i = 0; i < 2; i++) { maskNibble = ((parm->pattern.nDstIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //Mask out the bits 63:32 always for IPv4. ltbl.mask[3] = ltbl.mask[2] = 0xFFFF; } else { /* DIP LSB Nibble Mask */ ltbl.mask[0] = (u16)(parm->pattern.nDstIP_Mask | 0xFF00) & 0xFFFF; } + ltbl.valid = 1; tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->dip_lsb_idx = tindex; } + ptbl.key[3] |= (ptable->dip_msb_idx << 8); ptbl.key[3] |= ptable->dip_lsb_idx; /* Pattern field - SIP field table */ ptable->sip_msb_idx = 0xFF; //Mark as don't care. ptable->sip_lsb_idx = 0xFF; //Mark as don't care. + /* SIP MSB used - IPv6 bits 127:64 */ if (parm->pattern.eSrcIP_Select == GSW_PCE_IP_V6) { pce_dasa_msb_t mtbl; @@ -4355,102 +3403,120 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) u16 maskNibble; memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->pattern.nSrcIP.nIPv6[i] & 0xFF); + mtbl.imsb[j - 1] = (parm->pattern.nSrcIP.nIPv6[i] & 0xFF); mtbl.imsb[j] = ((parm->pattern.nSrcIP.nIPv6[i] >> 8) & 0xFF); } - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { //mtbl.nmask = (u16)((parm->pattern.nSrcIP_Mask >> 16) & 0xFFFF); for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nSrcIP_Mask >> ((i * 4) + 16)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - mtbl.mask[i] |= (0xF << (j*4)); + mtbl.mask[i] |= (0xF << (j * 4)); } } } else { mtbl.mask[0] = (u16)((parm->pattern.nSrcIP_Mask >> 16) & 0xFFFF); } + mtbl.valid = 1; tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, &mtbl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->sip_msb_idx = tindex; - + /* SIP LSB used - IPv6 bits 63:0 */ /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->pattern.nSrcIP.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->pattern.nSrcIP.nIPv6[i+4] >> 8) & 0xFF); + ltbl.ilsb[j - 1] = (parm->pattern.nSrcIP.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->pattern.nSrcIP.nIPv6[i + 4] >> 8) & 0xFF); } - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { //ltbl.nmask = (u16)(parm->pattern.nSrcIP_Mask & 0xFFFF); for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nSrcIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } } else { ltbl.mask[0] = (u16)(parm->pattern.nSrcIP_Mask & 0xFFFF); } + ltbl.valid = 1; tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->sip_lsb_idx = tindex; } else if (parm->pattern.eSrcIP_Select == GSW_PCE_IP_V4) { /* SIP LSB used - IPv4 bits 31:0 */ pce_dasa_lsb_t ltbl; memset(<bl, 0, sizeof(pce_dasa_lsb_t)); - /* Second, search for SIP in the DA/SA table (SIP LSB) */ + + /* Second, search for SIP in the DA/SA table (SIP LSB) */ for (i = 0; i < 4; i++) ltbl.ilsb[i] = ((parm->pattern.nSrcIP.nIPv4 >> (i * 8)) & 0xFF); - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) - { + + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { int j; u16 maskNibble; + //ltbl.nmask = (u16)(parm->pattern.nSrcIP_Mask) & 0xFFFF; for (i = 0; i < 2; i++) { maskNibble = ((parm->pattern.nSrcIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //Mask out the bits 63:32 always for IPv4. ltbl.mask[3] = ltbl.mask[2] = 0xFFFF; } else { /* DIP LSB Nibble Mask */ ltbl.mask[0] = (u16)(parm->pattern.nSrcIP_Mask | 0xFF00) & 0xFFFF; } + ltbl.valid = 1; tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->sip_lsb_idx = tindex; } + ptbl.key[2] |= (ptable->sip_msb_idx << 8); ptbl.key[2] |= ptable->sip_lsb_idx; /* Pattern field - inner DIP field table */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { ptable->inr_dip_msb_idx = 0xFF; //Mark as don't care. ptable->inr_dip_lsb_idx = 0xFF; //Mark as don't care. + /* DIP MSB used - IPv6 bits 127:64 */ if (parm->pattern.eInnerDstIP_Select == GSW_PCE_IP_V6) { pce_dasa_msb_t mtbl; @@ -4459,53 +3525,64 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) u16 maskNibble; memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->pattern.nInnerDstIP.nIPv6[i] & 0xFF); - mtbl.imsb[j] = ((parm->pattern.nInnerDstIP.nIPv6[i] >> 8) & - 0xFF); + mtbl.imsb[j - 1] = (parm->pattern.nInnerDstIP.nIPv6[i] & 0xFF); + mtbl.imsb[j] = ((parm->pattern.nInnerDstIP.nIPv6[i] >> 8) & + 0xFF); } + for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nInnerDstIP_Mask >> ((i * 4) + 16)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - mtbl.mask[i] |= (0xF << (j*4)); + mtbl.mask[i] |= (0xF << (j * 4)); } } + //mtbl.nmask = (u16)((parm->pattern.nInnerDstIP_Mask >> 16) & 0xFFFF); mtbl.valid = 1; - tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, - &mtbl); + tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, + &mtbl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_dip_msb_idx = tindex; /* DIP LSB used - IPv6 bits 63:0 */ /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->pattern.nInnerDstIP.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->pattern.nInnerDstIP.nIPv6[i+4]>> 8) & - 0xFF); + ltbl.ilsb[j - 1] = (parm->pattern.nInnerDstIP.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->pattern.nInnerDstIP.nIPv6[i + 4] >> 8) & + 0xFF); } + for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nInnerDstIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //ltbl.nmask = (u16)(parm->pattern.nInnerDstIP_Mask & 0xFFFF); ltbl.valid = 1; - tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, - <bl); + tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, + <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_dip_lsb_idx = tindex; } else if (parm->pattern.eInnerDstIP_Select == GSW_PCE_IP_V4) { /* DIP LSB used - IPv4 bits 31:0 */ @@ -4513,36 +3590,44 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) int j; u16 maskNibble; memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0; i < 4; i++) - ltbl.ilsb[i] = ((parm->pattern.nInnerDstIP.nIPv4 >> (i * 8)) & - 0xFF); + ltbl.ilsb[i] = ((parm->pattern.nInnerDstIP.nIPv4 >> (i * 8)) & + 0xFF); + for (i = 0; i < 2; i++) { maskNibble = ((parm->pattern.nInnerDstIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //Mask out the bits 63:32 always for IPv4. ltbl.mask[3] = ltbl.mask[2] = 0xFFFF; //ltbl.nmask = (u16)(parm->pattern.nInnerDstIP_Mask & 0xFFFF); ltbl.valid = 1; - tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, - <bl); + tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, + <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_dip_lsb_idx = tindex; } + ptbl.key[11] |= (ptable->inr_dip_msb_idx << 8); ptbl.key[11] |= ptable->inr_dip_lsb_idx; - + /* Pattern field - inner SIP field table */ ptable->inr_sip_msb_idx = 0xFF; //Mark as don't care. ptable->inr_sip_lsb_idx = 0xFF; //Mark as don't care. + /* SIP MSB used - IPv6 bits 127:64 */ if (parm->pattern.eInnerSrcIP_Select == GSW_PCE_IP_V6) { pce_dasa_msb_t mtbl; @@ -4551,53 +3636,64 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) u16 maskNibble; memset(&mtbl, 0, sizeof(pce_dasa_msb_t)); memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* First, search for DIP in the DA/SA table (DIP MSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - mtbl.imsb[j-1] = (parm->pattern.nInnerSrcIP.nIPv6[i] & 0xFF); - mtbl.imsb[j] = ((parm->pattern.nInnerSrcIP.nIPv6[i] >> 8) & - 0xFF); + mtbl.imsb[j - 1] = (parm->pattern.nInnerSrcIP.nIPv6[i] & 0xFF); + mtbl.imsb[j] = ((parm->pattern.nInnerSrcIP.nIPv6[i] >> 8) & + 0xFF); } + for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nInnerSrcIP_Mask >> ((i * 4) + 16)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - mtbl.mask[i] |= (0xF << (j*4)); + mtbl.mask[i] |= (0xF << (j * 4)); } } + //mtbl.nmask = (u16)((parm->pattern.nInnerSrcIP_Mask >> 16) & 0xFFFF); mtbl.valid = 1; - tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, - &mtbl); + tindex = pce_dasa_msb_tbl_write(cdev, &pthandle->pce_sub_tbl, + &mtbl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_sip_msb_idx = tindex; /* SIP LSB used - IPv6 bits 63:0 */ /* First, search for DIP in the DA/SA table (DIP LSB) */ for (i = 0, j = 7; i < 4; i++, j -= 2) { - ltbl.ilsb[j-1] = (parm->pattern.nInnerSrcIP.nIPv6[i+4] & 0xFF); - ltbl.ilsb[j] = ((parm->pattern.nInnerSrcIP.nIPv6[i+4] >> 8) & - 0xFF); + ltbl.ilsb[j - 1] = (parm->pattern.nInnerSrcIP.nIPv6[i + 4] & 0xFF); + ltbl.ilsb[j] = ((parm->pattern.nInnerSrcIP.nIPv6[i + 4] >> 8) & + 0xFF); } + for (i = 0; i < 4; i++) { maskNibble = ((parm->pattern.nInnerSrcIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //ltbl.nmask = (u16)(parm->pattern.nInnerSrcIP_Mask & 0xFFFF); ltbl.valid = 1; - tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, - <bl); + tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, + <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_sip_lsb_idx = tindex; } else if (parm->pattern.eInnerSrcIP_Select == GSW_PCE_IP_V4) { /* SIP LSB used - IPv4 bits 31:0 */ @@ -4605,30 +3701,37 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) int j; u16 maskNibble; memset(<bl, 0, sizeof(pce_dasa_lsb_t)); + /* Second, search for SIP in the DA/SA table (SIP LSB) */ for (i = 0; i < 4; i++) - ltbl.ilsb[i] = ((parm->pattern.nInnerSrcIP.nIPv4 >> (i * 8)) & - 0xFF); + ltbl.ilsb[i] = ((parm->pattern.nInnerSrcIP.nIPv4 >> (i * 8)) & + 0xFF); + for (i = 0; i < 2; i++) { maskNibble = ((parm->pattern.nInnerSrcIP_Mask >> (i * 4)) & 0xF); + for (j = 0; j < 4; j++) { if ((maskNibble >> j) & 0x1) - ltbl.mask[i] |= (0xF << (j*4)); + ltbl.mask[i] |= (0xF << (j * 4)); } } + //Mask out the bits 63:32 always for IPv4. ltbl.mask[3] = ltbl.mask[2] = 0xFFFF; //ltbl.nmask = (u16)(parm->pattern.nInnerSrcIP_Mask & 0xFFFF); ltbl.valid = 1; - tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, - <bl); + tindex = pce_dasa_lsb_tbl_write(cdev, &pthandle->pce_sub_tbl, + <bl); + if (tindex < 0) { pr_err("%s:%s:%d (DASA Table full)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + ptable->inr_sip_lsb_idx = tindex; } + ptbl.key[10] |= (ptable->inr_sip_msb_idx << 8); ptbl.key[10] |= ptable->inr_sip_lsb_idx; } @@ -4640,35 +3743,41 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pctl_tbl.ethertype = parm->pattern.nEtherType; pctl_tbl.emask = parm->pattern.nEtherTypeMask; tindex = pce_ptcl_tbl_write(cdev, &pthandle->pce_sub_tbl, &pctl_tbl); + if (tindex < 0) return tindex; + ptable->ethertype_idx = tindex; } else { ptable->ethertype_idx = 0xFF; //Mark as don't care. } + ptbl.key[1] |= ptable->ethertype_idx; - /* Pattern field - PPP Protocol table */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + /* Pattern field - PPP Protocol table */ + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bPPP_ProtocolEnable == 1) { prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); pctl_tbl.ethertype = parm->pattern.nPPP_Protocol; pctl_tbl.emask = parm->pattern.nPPP_ProtocolMask; - tindex = pce_ptcl_tbl_write(cdev, &pthandle->pce_sub_tbl, - &pctl_tbl); + tindex = pce_ptcl_tbl_write(cdev, &pthandle->pce_sub_tbl, + &pctl_tbl); + if (tindex < 0) return tindex; + ptable->ppp_prot_idx = tindex; } else { ptable->ppp_prot_idx = 0xFF; //Mark as don't care. } + ptbl.key[9] |= ptable->ppp_prot_idx; } - + /* Pattern field - Both outer n inner IP protocol table */ - if ((parm->pattern.bProtocolEnable == 1) && - (parm->pattern.bInnerProtocolEnable == 1)) { + if ((parm->pattern.bProtocolEnable == 1) && + (parm->pattern.bInnerProtocolEnable == 1)) { prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); pctl_tbl.ethertype = (parm->pattern.nProtocol & 0xFF); @@ -4676,11 +3785,13 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pctl_tbl.emask = (parm->pattern.nProtocolMask & 0x3); pctl_tbl.emask |= ((parm->pattern.nInnerProtocolMask & 0x3) << 2); tindex = pce_ptcl_tbl_write(cdev, &pthandle->pce_sub_tbl, &pctl_tbl); + if (tindex < 0) return tindex; + ptable->ip_prot_idx = tindex; } else if (parm->pattern.bInnerProtocolEnable == 1) { - /* Only inner IP protocol table */ + /* Only inner IP protocol table */ prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); pctl_tbl.ethertype = (0xFF); @@ -4688,12 +3799,14 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pctl_tbl.emask = 0x3; //Mask out outer Proto value. pctl_tbl.emask |= ((parm->pattern.nInnerProtocolMask & 0x3) << 2); tindex = pce_ptcl_tbl_write(cdev, - &pthandle->pce_sub_tbl, &pctl_tbl); + &pthandle->pce_sub_tbl, &pctl_tbl); + if (tindex < 0) return tindex; + ptable->ip_prot_idx = tindex; } else if (parm->pattern.bProtocolEnable == 1) { - /* Only outer IP protocol table */ + /* Only outer IP protocol table */ prtcol_tbl_t pctl_tbl; memset(&pctl_tbl, 0, sizeof(prtcol_tbl_t)); pctl_tbl.ethertype = (parm->pattern.nProtocol & 0xFF); @@ -4701,65 +3814,77 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) pctl_tbl.emask = (parm->pattern.nProtocolMask & 0x3); pctl_tbl.emask |= (0x3 << 2); //Mask out inner Proto value. tindex = pce_ptcl_tbl_write(cdev, &pthandle->pce_sub_tbl, &pctl_tbl); + if (tindex < 0) return tindex; + ptable->ip_prot_idx = tindex; } else { ptable->ip_prot_idx = 0xFF; //Mark as don't care. } + ptbl.key[1] |= (ptable->ip_prot_idx << 8); /* Pattern field - PPPoE table */ if (parm->pattern.bSessionIdEnable == 1) { pce_ppoe_tbl_t pppoe_tbl; pppoe_tbl.sess_id = parm->pattern.nSessionId; - tindex = pce_tm_pppoe_tbl_write(cdev, &pthandle->pce_sub_tbl, - &pppoe_tbl); + tindex = pce_tm_pppoe_tbl_write(cdev, &pthandle->pce_sub_tbl, + &pppoe_tbl); + if (tindex < 0) return tindex; + ptable->pppoe_idx = tindex; } else { ptable->pppoe_idx = 0xFF; //Mark as don't care. } + ptbl.key[7] |= (ptable->pppoe_idx << 8); /* Pattern field - VID value */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { tindex = 0x7F; //Mark as don't care. + /* Pattern field - inner VID */ if (parm->pattern.bVid == 1) { tindex = pce_vid_index(cdev, - &pthandle->pce_sub_tbl, parm->pattern.nVid); + &pthandle->pce_sub_tbl, parm->pattern.nVid); + if (reg_val == 1) { /*ETC*/ if (tindex == 0x7F) tindex = act_vlan_id_create(cdev, - parm->pattern.nVid, - parm->pattern.bVidRange_Select, - parm->pattern.nVidRange); + parm->pattern.nVid, + parm->pattern.bVidRange_Select, + parm->pattern.nVidRange); } else { if (tindex == 0x7F) { pr_err("%s:%s:%d (Create VID before use it)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } } } + ptable->vlan_idx = tindex; ptbl.key[0] &= ~(0xFF << 8); ptbl.key[0] |= (ptable->vlan_idx << 8); /* Pattern field - outer VID */ tindex = 0x7F; //Mark as don't care. + /* ETC */ if (reg_val == 1) { if (parm->pattern.bSLAN_Vid == 1) { tindex = pce_vid_index(cdev, - &pthandle->pce_sub_tbl, - parm->pattern.nSLAN_Vid); + &pthandle->pce_sub_tbl, + parm->pattern.nSLAN_Vid); + if (tindex == 0x7F) tindex = act_vlan_id_create(cdev, - parm->pattern.nSLAN_Vid, 0, 0); + parm->pattern.nSLAN_Vid, 0, 0); } + ptable->svlan_idx = tindex; ptbl.key[8] &= ~(0xFF << 8); ptbl.key[8] |= (ptable->svlan_idx << 8); @@ -4767,24 +3892,26 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* Pattern field - VID value */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { /* Pattern field - inner VID */ if (parm->pattern.bVid == 1) { - ptbl.key[20] |=(parm->pattern.nVid & 0x0FFF); - ptbl.key[20] |=(parm->pattern.bVid_Original << 15); + ptbl.key[20] |= (parm->pattern.nVid & 0x0FFF); + ptbl.key[20] |= (parm->pattern.bVid_Original << 15); + if (parm->pattern.bVidRange_Select) - ptbl.key[21] |=(parm->pattern.nVidRange & 0xFFF); + ptbl.key[21] |= (parm->pattern.nVidRange & 0xFFF); } else { ptbl.key[20] |= 0x1FFF; //Mark as don't care. } /* Pattern field - outer VID */ if (parm->pattern.bSLAN_Vid == 1) { - ptbl.key[18] |=(parm->pattern.nSLAN_Vid & 0x0FFF); - ptbl.key[18] |=(parm->pattern.bOuterVid_Original << 15); + ptbl.key[18] |= (parm->pattern.nSLAN_Vid & 0x0FFF); + ptbl.key[18] |= (parm->pattern.bOuterVid_Original << 15); + if (parm->pattern.bSVidRange_Select) - ptbl.key[19] |=(parm->pattern.nOuterVidRange & 0xFFF); - }else { + ptbl.key[19] |= (parm->pattern.nOuterVidRange & 0xFFF); + } else { ptbl.key[18] |= 0x1FFF; //Mark as don't care. } } @@ -4798,15 +3925,17 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* Pattern field - Sub-IF ID value */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bSubIfIdEnable == 1) { ptbl.key[17] |= (parm->pattern.nSubIfId & 0x0FF); + switch (parm->pattern.eSubIfIdType) { - case GSW_PCE_SUBIFID_TYPE_BRIDGEPORT: - ptbl.key[17] |=(0x1 << 9); - break; - default: - break; + case GSW_PCE_SUBIFID_TYPE_BRIDGEPORT: + ptbl.key[17] |= (0x1 << 9); + break; + + default: + break; } } else { ptbl.key[17] |= 0x1FF; //Mark as don't care. @@ -4820,66 +3949,90 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } else { ptbl.key[17] |= (3 << 10); //Don't care condition. } - + /* Pattern field - Exclude bits */ if (parm->pattern.bParserFlag1LSB_Exclude == 1) ptbl.key[14] |= (1 << 5); + if (parm->pattern.bParserFlag1MSB_Exclude == 1) ptbl.key[14] |= (1 << 6); - } + } /* Pattern field - Exclude bits */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { if (parm->pattern.bPortId_Exclude == 1) ptbl.key[14] |= (1 << 7); + if (parm->pattern.bVid_Exclude == 1) ptbl.key[14] |= (1 << 8); + if (parm->pattern.bEtherType_Exclude == 1) ptbl.key[14] |= (1 << 9); + if (parm->pattern.bProtocol_Exclude == 1) ptbl.key[14] |= (1 << 10); + if (parm->pattern.bSrcIP_Exclude == 1) ptbl.key[14] |= (1 << 11); + if (parm->pattern.bDstIP_Exclude == 1) ptbl.key[14] |= (1 << 12); + /* source port */ if (parm->pattern.bAppMSB_Exclude == 1) ptbl.key[14] |= (1 << 13); + if (parm->pattern.bAppLSB_Exclude == 1) ptbl.key[14] |= (1 << 14); + if (parm->pattern.bSrcMAC_Exclude == 1) ptbl.key[14] |= (1 << 15); if (parm->pattern.bDstMAC_Exclude == 1) ptbl.key[15] |= (1 << 0); + if (parm->pattern.bCTAG_PCP_DEI_Exclude == 1) ptbl.key[15] |= (1 << 1); + if (parm->pattern.bSTAG_PCP_DEI_Exclude == 1) ptbl.key[15] |= (1 << 2); + if (parm->pattern.bDSCP_Exclude == 1) ptbl.key[15] |= (1 << 3); + if (parm->pattern.bPktLng_Exclude == 1) ptbl.key[15] |= (1 << 4); + if (parm->pattern.bSessionId_Exclude == 1) ptbl.key[15] |= (1 << 5); + if (parm->pattern.bSLANVid_Exclude == 1) ptbl.key[15] |= (1 << 6); + if (parm->pattern.bPPP_Protocol_Exclude == 1) ptbl.key[15] |= (1 << 7); + if (parm->pattern.bInnerDSCP_Exclude == 1) ptbl.key[15] |= (1 << 8); + if (parm->pattern.bInnerSrcIP_Exclude == 1) ptbl.key[15] |= (1 << 9); + if (parm->pattern.bInnerDstIP_Exclude == 1) ptbl.key[15] |= (1 << 10); + if (parm->pattern.bParserFlagLSB_Exclude == 1) ptbl.key[15] |= (1 << 11); + if (parm->pattern.bParserFlagMSB_Exclude == 1) ptbl.key[15] |= (1 << 12); + if (parm->pattern.bPayload1_Exclude == 1) ptbl.key[15] |= (1 << 13); + if (parm->pattern.bPayload2_Exclude == 1) ptbl.key[15] |= (1 << 14); + if (parm->pattern.bSubIfId_Exclude == 1) ptbl.key[15] |= (1 << 15); } @@ -4893,59 +4046,70 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) if (paction->eSnoopingTypeAction == GSW_PCE_ACTION_IGMP_SNOOP_DISABLE) { ptbl.val[0] |= 1; //Enable port-map action. ptbl.val[4] |= (0x3 << 2); //Set to 'traffic-flow' portmap MUX control. + switch (paction->ePortMapAction) { - case GSW_PCE_ACTION_PORTMAP_REGULAR: - ptbl.val[4] &= ~(0x3 << 2); //Set to 'default' portmap MUX control. - break; - case GSW_PCE_ACTION_PORTMAP_DISCARD: - break; - case GSW_PCE_ACTION_PORTMAP_CPU: - case GSW_PCE_ACTION_PORTMAP_ALTERNATIVE: - if (gswdev->gipver == LTQ_GSWIP_3_0) { - /* CPU port-map */ //Govind - Need to test for 3.0 with MC router. - ptbl.val[1] = (paction->nForwardPortMap[0] & 0xFFFF); - } - if (gswdev->gipver == LTQ_GSWIP_3_1) { - for(i = 0; i <= 7; i++) - ptbl.val[i+10] = (paction->nForwardPortMap[i]); - } - //If CPU type set to 'MC router' portmap MUX control. - if (paction->ePortMapAction == GSW_PCE_ACTION_PORTMAP_CPU) { - ptbl.val[4] &= ~(0x3 << 2); - ptbl.val[4] |= (0x1 << 2); //Govind - why CPU type to MC router? - } - break; - /* To fix compilation warnings*/ - default: - break; + case GSW_PCE_ACTION_PORTMAP_REGULAR: + ptbl.val[4] &= ~(0x3 << 2); //Set to 'default' portmap MUX control. + break; + + case GSW_PCE_ACTION_PORTMAP_DISCARD: + break; + + case GSW_PCE_ACTION_PORTMAP_CPU: + case GSW_PCE_ACTION_PORTMAP_ALTERNATIVE: + if (gswdev->gipver == LTQ_GSWIP_3_0) { + /* CPU port-map */ //Govind - Need to test for 3.0 with MC router. + ptbl.val[1] = (paction->nForwardPortMap[0] & 0xFFFF); + } + + if (IS_VRSN_31(gswdev->gipver)) { + for (i = 0; i <= 7; i++) + ptbl.val[i + 10] = (paction->nForwardPortMap[i]); + } + + //If CPU type set to 'MC router' portmap MUX control. + if (paction->ePortMapAction == GSW_PCE_ACTION_PORTMAP_CPU) { + ptbl.val[4] &= ~(0x3 << 2); + ptbl.val[4] |= (0x1 << 2); //Govind - why CPU type to MC router? + } + + break; + + /* To fix compilation warnings*/ + default: + break; } } else { switch (paction->eSnoopingTypeAction) { - case GSW_PCE_ACTION_IGMP_SNOOP_REPORT: - case GSW_PCE_ACTION_IGMP_SNOOP_LEAVE: - ptbl.val[0] |= 1; - ptbl.val[4] &= ~(0x3 << 2); - //Set to 'MC router' portmap MUX control. - ptbl.val[4] |= (0x1 << 2); - break; - default: - ptbl.val[0] |= 1; - //Set to 'default' portmap MUX control. - ptbl.val[4] &= ~(0x3 << 2); - break; + case GSW_PCE_ACTION_IGMP_SNOOP_REPORT: + case GSW_PCE_ACTION_IGMP_SNOOP_LEAVE: + ptbl.val[0] |= 1; + ptbl.val[4] &= ~(0x3 << 2); + //Set to 'MC router' portmap MUX control. + ptbl.val[4] |= (0x1 << 2); + break; + + default: + ptbl.val[0] |= 1; + //Set to 'default' portmap MUX control. + ptbl.val[4] &= ~(0x3 << 2); + break; } } } else { /* Disable port map action */ ptbl.val[0] &= ~1; + if (gswdev->gipver == LTQ_GSWIP_3_0) { ptbl.val[1] = 0xFFFF; - } + } + //Govind - But why do we need to do below? - if (gswdev->gipver == LTQ_GSWIP_3_1) { - for(i = 0; i <= 7; i++) - ptbl.val[i+10] = 0xFFFF; + if (IS_VRSN_31(gswdev->gipver)) { + for (i = 0; i <= 7; i++) + ptbl.val[i + 10] = 0xFFFF; } + ptbl.val[4] &= ~(0x3 << 2); } @@ -4959,19 +4123,21 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ptbl.val[1] = paction->nFlowID & 0xFFFF; } else { pr_err("%s:%s:%d (Portmap & FlowID can be used exclusively)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } } } /* Inner and outer VLAN action */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { tindex = 0x7F; ptbl.val[2] = 0; ptbl.val[0] &= ~(1 << 13); + if (paction->eVLAN_Action != GSW_PCE_ACTION_VLAN_DISABLE) { ptbl.val[0] |= (1 << 1); + if (paction->eVLAN_Action == GSW_PCE_ACTION_VLAN_ALTERNATIVE) { if (reg_val == 1) { /*ETC */ @@ -4985,7 +4151,8 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) memset(&vatable, 0, sizeof(avlan_tbl_t)); vatable.vid = paction->nVLAN_Id; tindex = pce_vlan_id_fid_index(cdev, - &pthandle->pce_sub_tbl, &vatable); + &pthandle->pce_sub_tbl, &vatable); + if (tindex != 0x7F) { ptbl.val[2] = (tindex & 0xFF); ptbl.val[2] |= ((vatable.fid & 0xFF) << 8); @@ -4994,13 +4161,16 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } } } + /* ETC */ if (reg_val == 1) { ptbl.val[6] = 0; + if (paction->eSVLAN_Action != GSW_PCE_ACTION_VLAN_DISABLE) { ptbl.val[0] |= (1 << 1); /* Default CTAG VLAN ID and FID */ ptbl.val[6] &= ~(1 << 3); + if (paction->eSVLAN_Action == GSW_PCE_ACTION_VLAN_ALTERNATIVE) { ptbl.val[6] |= ((paction->nSVLAN_Id & 0xFFF) << 4); ptbl.val[0] |= (1 << 13); @@ -5009,180 +4179,211 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } } } - //Extended VLAN tagging action. - if (gswdev->gipver == LTQ_GSWIP_3_1) { + + //Extended VLAN tagging action. + if (IS_VRSN_31(gswdev->gipver)) { if (paction->bExtendedVlanEnable) { ptbl.val[0] |= (1 << 1); //Enable VLAN action. ptbl.val[6] |= (1 << 3); //Enable extended VLAN tagging. ptbl.val[6] |= ((paction->nExtendedVlanBlockId & 0x3FF) << 4); - } + } } /* Traffic class action */ if (paction->eTrafficClassAction != GSW_PCE_ACTION_TRAFFIC_CLASS_DISABLE) { ptbl.val[0] |= (1 << 2); + switch (paction->eTrafficClassAction) { case GSW_PCE_ACTION_TRAFFIC_CLASS_ALTERNATIVE: ptbl.val[0] |= (1 << 14); ptbl.val[3] |= (paction->nTrafficClassAlternate & 0xF) << 8; break; + default: break; } } - + /* Cross VLAN action */ if (paction->eVLAN_CrossAction != GSW_PCE_ACTION_CROSS_VLAN_DISABLE) { ptbl.val[0] |= (1 << 4); + if (paction->eVLAN_CrossAction == GSW_PCE_ACTION_CROSS_VLAN_CROSS) ptbl.val[3] |= (1 << 15); } - + /* Cross state action */ if (paction->eCrossStateAction != GSW_PCE_ACTION_CROSS_STATE_DISABLE) { ptbl.val[0] |= (1 << 5); + if (paction->eCrossStateAction == GSW_PCE_ACTION_CROSS_STATE_CROSS) ptbl.val[4] |= (1 << 13); } - + /* Critical frame action */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { - if (paction->eCritFrameAction != - GSW_PCE_ACTION_CRITICAL_FRAME_DISABLE) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (paction->eCritFrameAction != + GSW_PCE_ACTION_CRITICAL_FRAME_DISABLE) { ptbl.val[0] |= (1 << 6); - if (paction->eCritFrameAction == - GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL) + + if (paction->eCritFrameAction == + GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL) ptbl.val[4] |= (1 << 14); } } /* Color action */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (paction->eColorFrameAction != GSW_PCE_ACTION_COLOR_FRAME_DISABLE) { ptbl.val[0] |= (1 << 6); + switch (paction->eColorFrameAction) { - case GSW_PCE_ACTION_COLOR_FRAME_CRITICAL: - ptbl.val[2] |=0x4; - break; - case GSW_PCE_ACTION_COLOR_FRAME_GREEN: - ptbl.val[2] |=0x5; - break; - case GSW_PCE_ACTION_COLOR_FRAME_YELLOW: - ptbl.val[2] |=0x6; - break; - case GSW_PCE_ACTION_COLOR_FRAME_RED: - ptbl.val[2] |=0x7; - break; - default:/*GSW_PCE_ACTION_COLOR_FRAME_NO_CHANGE*/ - break; + case GSW_PCE_ACTION_COLOR_FRAME_CRITICAL: + ptbl.val[2] |= 0x4; + break; + + case GSW_PCE_ACTION_COLOR_FRAME_GREEN: + ptbl.val[2] |= 0x5; + break; + + case GSW_PCE_ACTION_COLOR_FRAME_YELLOW: + ptbl.val[2] |= 0x6; + break; + + case GSW_PCE_ACTION_COLOR_FRAME_RED: + ptbl.val[2] |= 0x7; + break; + + default:/*GSW_PCE_ACTION_COLOR_FRAME_NO_CHANGE*/ + break; } } } - + /* Time stamp action */ if (paction->eTimestampAction != GSW_PCE_ACTION_TIMESTAMP_DISABLE) { ptbl.val[0] |= (1 << 7); + if (paction->eTimestampAction == GSW_PCE_ACTION_TIMESTAMP_STORED) { ptbl.val[4] |= (1 << 15); ptbl.val[8] |= ((paction->nRecordId & 0xFFF) << 4); - } + } } - + /* Interrupt action */ if (paction->eIrqAction != GSW_PCE_ACTION_IRQ_DISABLE) { ptbl.val[0] |= (1 << 8); + if (paction->eIrqAction == GSW_PCE_ACTION_IRQ_EVENT) ptbl.val[0] |= (1 << 15); } - + /* MAC Learning action */ if (paction->eLearningAction != GSW_PCE_ACTION_LEARNING_DISABLE) { ptbl.val[0] |= (1 << 9); + switch (paction->eLearningAction) { case GSW_PCE_ACTION_LEARNING_REGULAR: - //ptbl.val[4] &= ~(0x3); - break; + //ptbl.val[4] &= ~(0x3); + break; + case GSW_PCE_ACTION_LEARNING_FORCE_NOT: - ptbl.val[4] |= 0x2; - break; + ptbl.val[4] |= 0x2; + break; + case GSW_PCE_ACTION_LEARNING_FORCE: - ptbl.val[4] |= 0x3; - break; + ptbl.val[4] |= 0x3; + break; + default: - ptbl.val[4] |= 0x1; - break; + ptbl.val[4] |= 0x1; + break; } } - + /* IGMP Snooping action. */ if (paction->eSnoopingTypeAction != GSW_PCE_ACTION_IGMP_SNOOP_DISABLE) { ptbl.val[0] |= (1 << 10); + switch (paction->eSnoopingTypeAction) { - case GSW_PCE_ACTION_IGMP_SNOOP_REGULAR: - //ptbl.val[4] |= (0 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_REPORT: - ptbl.val[4] |= (1 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_LEAVE: - ptbl.val[4] |= (2 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_AD: - ptbl.val[4] |= (3 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_QUERY: - ptbl.val[4] |= (4 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP: - ptbl.val[4] |= (5 << 5); - break; - case GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER: - ptbl.val[4] |= (6 << 5); - break; - default: - break; + case GSW_PCE_ACTION_IGMP_SNOOP_REGULAR: + //ptbl.val[4] |= (0 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_REPORT: + ptbl.val[4] |= (1 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_LEAVE: + ptbl.val[4] |= (2 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_AD: + ptbl.val[4] |= (3 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_QUERY: + ptbl.val[4] |= (4 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP: + ptbl.val[4] |= (5 << 5); + break; + + case GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER: + ptbl.val[4] |= (6 << 5); + break; + + default: + break; } } - + /* Metering action */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { if (paction->eMeterAction != GSW_PCE_ACTION_METER_DISABLE) { ptbl.val[0] |= (1 << 11); ptbl.val[3] |= (paction->nMeterId & 0x1F); + switch (paction->eMeterAction) { - case GSW_PCE_ACTION_METER_REGULAR: - ptbl.val[3] |= 0 << 6; - break; - case GSW_PCE_ACTION_METER_1: - ptbl.val[3] |= 1 << 6; - break; - /*case GSW_PCE_ACTION_METER_2: - ptbl.val[3] |= 2 << 6; - break;*/ - case GSW_PCE_ACTION_METER_1_2: - ptbl.val[3] |= 3 << 6; - break; - case GSW_PCE_ACTION_METER_DISABLE: - break; + case GSW_PCE_ACTION_METER_REGULAR: + ptbl.val[3] |= 0 << 6; + break; + + case GSW_PCE_ACTION_METER_1: + ptbl.val[3] |= 1 << 6; + break; + + /*case GSW_PCE_ACTION_METER_2: + ptbl.val[3] |= 2 << 6; + break;*/ + case GSW_PCE_ACTION_METER_1_2: + ptbl.val[3] |= 3 << 6; + break; + + case GSW_PCE_ACTION_METER_DISABLE: + break; } } else { ptbl.val[3] |= 0x1F; } } - + /* Metering action */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if (paction->eMeterAction != GSW_PCE_ACTION_METER_DISABLE) { ptbl.val[0] |= (1 << 11); + switch (paction->eMeterAction) { - case GSW_PCE_ACTION_METER_1: - ptbl.val[3] |= 1 << 7; - ptbl.val[3] |= (paction->nMeterId & 0x7F); - break; - default: - break; + case GSW_PCE_ACTION_METER_1: + ptbl.val[3] |= 1 << 7; + ptbl.val[3] |= (paction->nMeterId & 0x7F); + break; + + default: + break; } - } + } /* FID action */ if (paction->bFidEnable == 1) { @@ -5190,12 +4391,13 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ptbl.val[2] |= ((paction->nFId) & 0x3F) << 8; } } - + /* RMON action */ - if (gswdev->gipver != LTQ_GSWIP_3_1) { - if (paction->bRMON_Action != 0) { + if (IS_VRSN_NOT_31(gswdev->gipver)) { + if (paction->bRMON_Action != 0) { ptbl.val[0] |= (1 << 12); ptbl.val[4] &= ~(0x1F << 8); + if (paction->nRMON_Id < 24) { ptbl.val[4] |= ((paction->nRMON_Id + 1) << 8); } else { @@ -5206,30 +4408,32 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ptbl.val[4] &= ~(0x1F << 8); } } - + /* RMON or Flow-ID action. */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { if ((paction->bFlowID_Action != 0) && (paction->bRMON_Action != 0)) { - if (paction->nFlowID != paction->nRMON_Id){ + if (paction->nFlowID != paction->nRMON_Id) { pr_err("RMON counter ID & FlowID should be equal.\n"); return -1; } } - + if (paction->bFlowID_Action != 0) { if (!(paction->nFlowID)) { pr_err("Flow-ID zero is reserved.\n"); return -1; - } + } + ptbl.val[4] |= (0x1 << 4); ptbl.val[1] = paction->nFlowID & 0xFF; - } + } if (paction->bRMON_Action != 0) { if (!(paction->nRMON_Id)) { pr_err("RMON-ID zero is reserved.\n"); return -1; - } + } + ptbl.val[4] |= (1 << 4); ptbl.val[1] = paction->nRMON_Id & 0xFF; } @@ -5238,43 +4442,47 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) /* Remarking action. */ if (gswdev->gipver == LTQ_GSWIP_3_0) { ptbl.val[3] |= (0x7 << 12); - if (paction->bRemarkDSCP == 1) + + if (paction->bRemarkDSCP == 1) ptbl.val[3] &= ~(1 << 12); else ptbl.val[3] |= (1 << 12); - if (paction->bRemarkClass == 1) + + if (paction->bRemarkClass == 1) ptbl.val[3] &= ~(1 << 13); else ptbl.val[3] |= (1 << 13); - if (paction->bRemarkPCP == 1) + + if (paction->bRemarkPCP == 1) ptbl.val[3] &= ~(1 << 14); else ptbl.val[3] |= (1 << 14); + /* ETC */ - if (paction->bRemarkSTAG_PCP == 1) + if (paction->bRemarkSTAG_PCP == 1) ptbl.val[6] &= ~(1 << 1); else ptbl.val[6] |= (1 << 1); - if (paction->bRemarkSTAG_DEI == 1) + + if (paction->bRemarkSTAG_DEI == 1) ptbl.val[6] &= ~(1 << 2); else ptbl.val[6] |= (1 << 2); - + if (paction->bPortBitMapMuxControl == 1) { ptbl.val[6] |= (1 << 0); ptbl.val[1] = paction->nForwardPortMap[0]; - } - else + } else ptbl.val[6] &= ~(1 << 0); - + /* Remarking action enable */ if (paction->bRemarkAction != 0) ptbl.val[0] |= (1 << 3); else ptbl.val[0] &= ~(1 << 3); - + /* CVLAN Ignore action */ - if (paction->bCVLAN_Ignore_Control == 1) { + if (paction->bCVLAN_Ignore_Control == 1) { ptbl.val[5] |= (1 << 2); ptbl.val[0] |= (1 << 1); //Govind - why set this bit? } else { @@ -5291,93 +4499,113 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) ptbl.val[5] |= (1 << 1); /* IGMP snoop control */ - if (gswdev->gipver == LTQ_GSWIP_3_0 || gswdev->gipver == LTQ_GSWIP_3_1) { - if (paction->ePortFilterType_Action != - GSW_PCE_PORT_FILTER_ACTION_UNUSED) { + if (gswdev->gipver == LTQ_GSWIP_3_0 || IS_VRSN_31(gswdev->gipver)) { + if (paction->ePortFilterType_Action != + GSW_PCE_PORT_FILTER_ACTION_UNUSED) { if (paction->ePortMapAction == GSW_PCE_ACTION_PORTMAP_DISABLE) { ptbl.val[7] &= ~(0x3F << 1); + switch (paction->ePortFilterType_Action) { - case GSW_PCE_PORT_FILTER_ACTION_1: - ptbl.val[7] |= (1 << 1); - break; - case GSW_PCE_PORT_FILTER_ACTION_2: - ptbl.val[7] |= (1 << 2); - break; - case GSW_PCE_PORT_FILTER_ACTION_3: - ptbl.val[7] |= (1 << 3); - break; - case GSW_PCE_PORT_FILTER_ACTION_4: - ptbl.val[7] |= (1 << 4); - break; - case GSW_PCE_PORT_FILTER_ACTION_5: - ptbl.val[7] |= (1 << 5); - break; - case GSW_PCE_PORT_FILTER_ACTION_6: - ptbl.val[7] |= (1 << 6); - break; - default: - break; + case GSW_PCE_PORT_FILTER_ACTION_1: + ptbl.val[7] |= (1 << 1); + break; + + case GSW_PCE_PORT_FILTER_ACTION_2: + ptbl.val[7] |= (1 << 2); + break; + + case GSW_PCE_PORT_FILTER_ACTION_3: + ptbl.val[7] |= (1 << 3); + break; + + case GSW_PCE_PORT_FILTER_ACTION_4: + ptbl.val[7] |= (1 << 4); + break; + + case GSW_PCE_PORT_FILTER_ACTION_5: + ptbl.val[7] |= (1 << 5); + break; + + case GSW_PCE_PORT_FILTER_ACTION_6: + ptbl.val[7] |= (1 << 6); + break; + + default: + break; } + if (gswdev->gipver == LTQ_GSWIP_3_0) { ptbl.val[1] = (paction->nForwardPortMap[0] & 0xFFFF); } + //Port-member map. - if (gswdev->gipver == LTQ_GSWIP_3_1) { - for(i = 0; i <= 7; i++) - ptbl.val[i+10] = paction->nForwardPortMap[i]; + if (IS_VRSN_31(gswdev->gipver)) { + for (i = 0; i <= 7; i++) + ptbl.val[i + 10] = paction->nForwardPortMap[i]; } - } + } } - + /* Processing path action */ - if (paction->eProcessPath_Action != GSW_PCE_PROCESSING_PATH_UNUSED) { + if (paction->eProcessPath_Action != GSW_PCE_PROCESSING_PATH_UNUSED) { ptbl.val[8] |= (1 << 0); + switch (paction->eProcessPath_Action) { - case GSW_PCE_PROCESSING_PATH_1: - ptbl.val[8] |= (1 << 1); - break; - case GSW_PCE_PROCESSING_PATH_2: - ptbl.val[8] |= (1 << 2); - break; - case GSW_PCE_PROCESSING_PATH_BOTH: - ptbl.val[8] |= (3 << 1); - break; - default: - break; + case GSW_PCE_PROCESSING_PATH_1: + ptbl.val[8] |= (1 << 1); + break; + + case GSW_PCE_PROCESSING_PATH_2: + ptbl.val[8] |= (1 << 2); + break; + + case GSW_PCE_PROCESSING_PATH_BOTH: + ptbl.val[8] |= (3 << 1); + break; + + default: + break; } } /* Routing action */ if (gswdev->gipver == LTQ_GSWIP_3_0) { - if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { + if (gswdev->sdev == LTQ_FLOW_DEV_INT_R) { if (paction->bRoutExtId_Action == 1) ptbl.val[9] |= ((paction->nRoutExtId & 0xFF) << 8); else ptbl.val[9] |= (0xFF << 8); + if (paction->bRtDstPortMaskCmp_Action == 1) ptbl.val[9] &= ~(1 << 6); else ptbl.val[9] |= (1 << 6); + if (paction->bRtSrcPortMaskCmp_Action == 1) ptbl.val[9] &= ~(1 << 5); else ptbl.val[9] |= (1 << 5); + if (paction->bRtDstIpMaskCmp_Action == 1) ptbl.val[9] &= ~(1 << 4); else ptbl.val[9] |= (1 << 4); + if (paction->bRtSrcIpMaskCmp_Action == 1) ptbl.val[9] &= ~(1 << 3); else ptbl.val[9] |= (1 << 3); + if (paction->bRtInnerIPasKey_Action == 1) ptbl.val[9] |= (1 << 2); else ptbl.val[9] &= ~(1 << 2); + if (paction->bRtAccelEna_Action == 1) ptbl.val[9] |= (1 << 1); else ptbl.val[9] &= ~(1 << 1); + if (paction->bRtCtrlEna_Action == 1) ptbl.val[9] |= (1 << 0); else @@ -5387,28 +4615,32 @@ int pce_rule_write(void *cdev, ltq_pce_table_t *pthandle, GSW_PCE_rule_t *parm) } /* OAM and packet extraction to CPU action */ - if (gswdev->gipver == LTQ_GSWIP_3_1) { - if((paction->bExtractEnable == 1) || (paction->bOamEnable == 1)) { + if (IS_VRSN_31(gswdev->gipver)) { + if ((paction->bExtractEnable == 1) || (paction->bOamEnable == 1)) { ptbl.val[8] |= (1 << 0); - if(paction->bExtractEnable == 1) { + + if (paction->bExtractEnable == 1) { ptbl.val[7] |= (1 << 8); /* Extraction flag */ } - if(paction->bOamEnable == 1) { + + if (paction->bOamEnable == 1) { ptbl.val[8] |= (1 << 3); /* OAM flag*/ /*OAM and extraction packet control*/ ptbl.val[8] |= ((paction->nRecordId & 0xFFF) << 4); } } - } + } ptbl.pcindex = idx; ptbl.table = PCE_TFLOW_INDEX; ptbl.valid = 1; status = gsw_pce_table_write(cdev, &ptbl); + if (status == GSW_statusOk) return GSW_statusOk; else return status; + return GSW_statusOk; } diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_gphy_fw.c b/drivers/net/ethernet/lantiq/switch-api/gsw_gphy_fw.c index bfa6354032f530e2b0fb468717fee3ae4e1cf7e8..8937438a58117db1f9f02cdb399a6fb3da7afc46 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_gphy_fw.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_gphy_fw.c @@ -40,7 +40,7 @@ static struct proc_dir_entry *g_proc_gphy_dir; -static int dev_id; +static int dev_id; static struct device_node *gphy_node; static struct device *gphy_dev; const char *g_gphy_fw_mode = NULL; @@ -82,7 +82,7 @@ typedef struct gphy_image_header { } gphy_image_header_t; struct core_ops *ops; struct task_struct *gphy_pw_id; -static int gphy_pw_save_thread (void *arg); +static int gphy_pw_save_thread(void *arg); /* Signal Related */ wait_queue_head_t gphy_pw_wait; unsigned int phy_port_nos[6]; @@ -99,7 +99,7 @@ static unsigned int ssd_interval = 4; #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR struct task_struct *gphy_ssd_id; wait_queue_head_t gphy_ssd_wait; -static int gphy_ssd_err_thread (void *arg); +static int gphy_ssd_err_thread(void *arg); static unsigned int ssd_cnt[NUM_OF_PORTS] = {0}; #endif /* PHY_SSD_ERROR */ @@ -235,7 +235,7 @@ static int proc_read_phy_on(struct seq_file *, void *); static int proc_read_phy_off(struct seq_file *, void *); static ssize_t proc_write_phy_on(struct file *, const char __user *, size_t, loff_t *); static ssize_t proc_write_phy_off(struct file *, const char __user *, size_t, loff_t *); -static void gsw_mdio_data_write(unsigned int phyAddr, unsigned int regAddr,unsigned int data); +static void gsw_mdio_data_write(unsigned int phyAddr, unsigned int regAddr, unsigned int data); //For VRX220 SW control PHY LED @@ -252,8 +252,8 @@ enum gphy_gpio_mapping { GPHY_4_GPIO = 12 + GPIO_VRX200_OFFSET, GPHY_5_GPIO = 15 + GPIO_VRX200_OFFSET, }; -int gphy_led_state[NUM_OF_PORTS] = {0,0,0,0,0,0}; /* 0: OFF, 1: ON, 2: flash */ -int gphy_led_status_on[NUM_OF_PORTS] = {0,0,0,0,0,0}; +int gphy_led_state[NUM_OF_PORTS] = {0, 0, 0, 0, 0, 0}; /* 0: OFF, 1: ON, 2: flash */ +int gphy_led_status_on[NUM_OF_PORTS] = {0, 0, 0, 0, 0, 0}; //end For VRX220 SW control PHY LED static unsigned short gsw_mdio_data_read(unsigned int phyAddr, unsigned int regAddr); @@ -261,23 +261,23 @@ static unsigned short gsw_mdio_data_read(unsigned int phyAddr, unsigned int regA static unsigned short gsw_mmd_data_read(unsigned int phyAddr, unsigned int regAddr); #endif /* PHY_SSD_ERROR */ static dma_addr_t xway_gphy_load(unsigned char *pData); -static int ltq_gphy_firmware_config (void); -static int ltq_mix_firmware_config (u8 *fw_ptr, int); +static int ltq_gphy_firmware_config(void); +static int ltq_mix_firmware_config(u8 *fw_ptr, int); static struct file_operations file_phy_fw_fops = { - .owner = THIS_MODULE, - .open = proc_read_phy_fw_open, - .read = seq_read, - .write = proc_write_phy_fw, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = proc_read_phy_fw_open, + .read = seq_read, + .write = proc_write_phy_fw, + .llseek = seq_lseek, + .release = single_release, }; static int proc_read_phy_fw_open(struct inode *inode, struct file *file) { - return single_open(file, proc_read_phy_fw, NULL); + return single_open(file, proc_read_phy_fw, NULL); } -unsigned int found_magic = 0, found_img = 0, first_block =0, fw_len=0, rcv_size = 0, second_block = 0; +unsigned int found_magic = 0, found_img = 0, first_block = 0, fw_len = 0, rcv_size = 0, second_block = 0; int fmode = 0, update_ge = 0, update_fe = 0; static ssize_t proc_write_phy_fw(struct file *file, const char __user *buf, size_t count, loff_t *data) { @@ -290,6 +290,7 @@ static ssize_t proc_write_phy_fw(struct file *file, const char __user *buf, size if (!found_img) { memcpy(&header, (local_buf + (found_magic * sizeof(gphy_image_header_t))), sizeof(gphy_image_header_t)); + if (header.immagic == IH_MAGIC_NO) { found_magic++; first_block = 0; @@ -299,91 +300,95 @@ static ssize_t proc_write_phy_fw(struct file *file, const char __user *buf, size update_fe = 0; } } + if (!found_img) { if (strcmp(g_gphy_fw_mode, "11G-FW") == 0) { -/* dev_info(gphy_dev, "%s: header:%s, size:%d \n", __func__,header.imname, header.imsize);*/ + /* dev_info(gphy_dev, "%s: header:%s, size:%d \n", __func__,header.imname, header.imsize);*/ if (((strncmp(header.imname, "VR9 V1.1 GPHY GE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.1 GPHY GE", sizeof(header.imname)) == 0)) \ - && (dev_id == 0) ) { + || (strncmp(header.imname, "AR10 V1.1 GPHY GE", sizeof(header.imname)) == 0)) \ + && (dev_id == 0)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 1; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } else if (((strncmp(header.imname, "VR9 V1.2 GPHY GE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ - && (dev_id == 1)) { + || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 1; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } else if ((strncmp(header.imname, "GRX500 V1.1 GPHY BE", sizeof(header.imname)) == 0) \ - && (dev_id == 1)) { + && (dev_id == 1)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 1; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } } else if (strcmp(g_gphy_fw_mode, "22F-FW") == 0) { - if(((strncmp(header.imname, "VR9 V1.1 GPHY FE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.1 GPHY FE", sizeof(header.imname)) == 0)) \ - && (dev_id == 0)) { + if (((strncmp(header.imname, "VR9 V1.1 GPHY FE", sizeof(header.imname)) == 0) \ + || (strncmp(header.imname, "AR10 V1.1 GPHY FE", sizeof(header.imname)) == 0)) \ + && (dev_id == 0)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 2; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } else if (((strncmp(header.imname, "VR9 V1.2 GPHY FE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0 )) \ - && (dev_id == 1)) { + || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 2; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } } else if (strcmp(g_gphy_fw_mode, "11G22F-FW") == 0) { - dev_info(gphy_dev, "%s: header:%s, size:%d \n", __func__,header.imname, header.imsize); + dev_info(gphy_dev, "%s: header:%s, size:%d \n", __func__, header.imname, header.imsize); + if (((strncmp(header.imname, "VR9 V1.2 GPHY GE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ - && (dev_id == 1)) { + || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 1; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } + if (((strncmp(header.imname, "VR9 V1.2 GPHY FE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0 )) \ - && (dev_id == 1)) { + || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { first_block = 1; fw_len = header.imsize; found_img = 1; fmode = 2; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); } } } + if ((strcmp(g_gphy_fw_mode, "11G-FW") == 0) || (strcmp(g_gphy_fw_mode, "22F-FW") == 0)) { if ((first_block == 1) && (!second_block) && found_img) { - g_gphy_fw_dma = (u8*) kmalloc (fw_len * sizeof (unsigned char), GFP_KERNEL); + g_gphy_fw_dma = (u8 *) kmalloc(fw_len * sizeof(unsigned char), GFP_KERNEL); memset(g_gphy_fw_dma, 0, fw_len); rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); - memcpy(g_gphy_fw_dma, local_buf+(found_magic * sizeof(gphy_image_header_t)), rcv_size); + memcpy(g_gphy_fw_dma, local_buf + (found_magic * sizeof(gphy_image_header_t)), rcv_size); second_block = 1; } else if ((second_block == 1) && found_img) { - if (rcv_size < (fw_len) ) { + if (rcv_size < (fw_len)) { if ((rcv_size + len) >= fw_len) { - memcpy(g_gphy_fw_dma+rcv_size, local_buf, (fw_len-rcv_size)); + memcpy(g_gphy_fw_dma + rcv_size, local_buf, (fw_len - rcv_size)); first_block = 0; found_img = 0; second_block = 0; found_magic = 0; ltq_gphy_firmware_config(); } else { - memcpy(g_gphy_fw_dma+rcv_size, local_buf, (len)); + memcpy(g_gphy_fw_dma + rcv_size, local_buf, (len)); rcv_size += len; } } else { @@ -396,97 +401,114 @@ static ssize_t proc_write_phy_fw(struct file *file, const char __user *buf, size } } else if (strcmp(g_gphy_fw_mode, "11G22F-FW") == 0) { if ((first_block == 1) && (!second_block) && found_img) { - if (fmode == 1 ) { - g_gphy_fw_dma = (u8*) kmalloc (fw_len * sizeof (unsigned char), GFP_KERNEL); - if (g_gphy_fw_dma == NULL ) + if (fmode == 1) { + g_gphy_fw_dma = (u8 *) kmalloc(fw_len * sizeof(unsigned char), GFP_KERNEL); + + if (g_gphy_fw_dma == NULL) return -1; + memset(g_gphy_fw_dma, 0, fw_len); rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); - memcpy(g_gphy_fw_dma, local_buf+(found_magic * sizeof(gphy_image_header_t)), rcv_size); + memcpy(g_gphy_fw_dma, local_buf + (found_magic * sizeof(gphy_image_header_t)), rcv_size); } - if (fmode == 2 ) { - f_gphy_fw_dma = (u8*) kmalloc (fw_len * sizeof (unsigned char), GFP_KERNEL); - if (f_gphy_fw_dma == NULL ) + + if (fmode == 2) { + f_gphy_fw_dma = (u8 *) kmalloc(fw_len * sizeof(unsigned char), GFP_KERNEL); + + if (f_gphy_fw_dma == NULL) return -1; + memset(f_gphy_fw_dma, 0, fw_len); rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); - memcpy(f_gphy_fw_dma, local_buf+(found_magic * sizeof(gphy_image_header_t)), rcv_size); + memcpy(f_gphy_fw_dma, local_buf + (found_magic * sizeof(gphy_image_header_t)), rcv_size); } + second_block = 1; } else if ((second_block == 1) && found_img) { - if (rcv_size < (fw_len) ) { + if (rcv_size < (fw_len)) { if ((rcv_size + len) >= fw_len) { - if (fmode == 1 ) { - if ((len <= 4096) && (len > 64)) { + if (fmode == 1) { + if ((len <= 4096) && (len > 64)) { update_ge = 1; - memcpy(g_gphy_fw_dma+rcv_size, local_buf, (fw_len-rcv_size)); + memcpy(g_gphy_fw_dma + rcv_size, local_buf, (fw_len - rcv_size)); rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); memcpy(&header, (local_buf + (found_magic * sizeof(gphy_image_header_t))), sizeof(gphy_image_header_t)); } } - if (fmode == 2 ) { - if ((len <= 4096) && (len > 64)) { + + if (fmode == 2) { + if ((len <= 4096) && (len > 64)) { update_fe = 1; - memcpy(f_gphy_fw_dma+rcv_size, local_buf, (fw_len-rcv_size)); + memcpy(f_gphy_fw_dma + rcv_size, local_buf, (fw_len - rcv_size)); rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); memcpy(&header, (local_buf + (found_magic * sizeof(gphy_image_header_t))), sizeof(gphy_image_header_t)); } } + if (((strncmp(header.imname, "VR9 V1.2 GPHY GE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ - && (dev_id == 1)) { - first_block = 1; - fw_len = header.imsize; - found_img = 1; - fmode = 1; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); - g_gphy_fw_dma = (u8*) kmalloc (fw_len * sizeof (unsigned char), GFP_KERNEL); - if (g_gphy_fw_dma == NULL ) { - pr_err("ERROR: Line: %d: %s: Found:%s FW \n", __LINE__, __func__,header.imname); - return -1; - } - memset(g_gphy_fw_dma, 0, fw_len); - found_magic++; - rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); - memcpy(g_gphy_fw_dma, local_buf+(found_magic * sizeof(gphy_image_header_t)), rcv_size); + || (strncmp(header.imname, "AR10 V1.2 GPHY GE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { + first_block = 1; + fw_len = header.imsize; + found_img = 1; + fmode = 1; + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); + g_gphy_fw_dma = (u8 *) kmalloc(fw_len * sizeof(unsigned char), GFP_KERNEL); + + if (g_gphy_fw_dma == NULL) { + pr_err("ERROR: Line: %d: %s: Found:%s FW \n", __LINE__, __func__, header.imname); + return -1; + } + + memset(g_gphy_fw_dma, 0, fw_len); + found_magic++; + rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); + memcpy(g_gphy_fw_dma, local_buf + (found_magic * sizeof(gphy_image_header_t)), rcv_size); } + if (((strncmp(header.imname, "VR9 V1.2 GPHY FE", sizeof(header.imname)) == 0) \ - || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0 )) \ - && (dev_id == 1)) { - first_block = 1; - fw_len = header.imsize; - found_img = 1; - fmode = 2; - found_magic++; - dev_info(gphy_dev, "%s: Found:%s FW \n", __func__,header.imname); - f_gphy_fw_dma = (u8*) kmalloc (fw_len * sizeof (unsigned char), GFP_KERNEL); - if (f_gphy_fw_dma == NULL ) { - pr_err("ERROR: Line: %d: %s: Found:%s FW \n", __LINE__, __func__,header.imname); - return -1; - } - memset(f_gphy_fw_dma, 0, fw_len); - rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); - memcpy(f_gphy_fw_dma, local_buf+(found_magic * sizeof(gphy_image_header_t)), rcv_size); + || (strncmp(header.imname, "AR10 V1.2 GPHY FE", sizeof(header.imname)) == 0)) \ + && (dev_id == 1)) { + first_block = 1; + fw_len = header.imsize; + found_img = 1; + fmode = 2; + found_magic++; + dev_info(gphy_dev, "%s: Found:%s FW \n", __func__, header.imname); + f_gphy_fw_dma = (u8 *) kmalloc(fw_len * sizeof(unsigned char), GFP_KERNEL); + + if (f_gphy_fw_dma == NULL) { + pr_err("ERROR: Line: %d: %s: Found:%s FW \n", __LINE__, __func__, header.imname); + return -1; + } + + memset(f_gphy_fw_dma, 0, fw_len); + rcv_size = (len - (found_magic * sizeof(gphy_image_header_t))); + memcpy(f_gphy_fw_dma, local_buf + (found_magic * sizeof(gphy_image_header_t)), rcv_size); } - if ( update_ge == 1) { + + if (update_ge == 1) { if (g_gphy_fw_dma) { ltq_mix_firmware_config(g_gphy_fw_dma, 1); update_ge = 0; } } - if ( update_fe == 1) { + + if (update_fe == 1) { if (f_gphy_fw_dma) { ltq_mix_firmware_config(f_gphy_fw_dma, 2); update_fe = 0; } } } else { - if (fmode == 1 ) { - memcpy(g_gphy_fw_dma+rcv_size, local_buf, (len)); + if (fmode == 1) { + memcpy(g_gphy_fw_dma + rcv_size, local_buf, (len)); } - if (fmode == 2 ) { - memcpy(f_gphy_fw_dma+rcv_size, local_buf, (len)); + + if (fmode == 2) { + memcpy(f_gphy_fw_dma + rcv_size, local_buf, (len)); } + rcv_size += len; } } else { @@ -494,23 +516,26 @@ static ssize_t proc_write_phy_fw(struct file *file, const char __user *buf, size found_img = 0; second_block = 0; found_magic = 0; - if ( update_ge == 1) { + + if (update_ge == 1) { if (g_gphy_fw_dma) ltq_mix_firmware_config(g_gphy_fw_dma, 1); } - if ( update_fe == 1) { + + if (update_fe == 1) { if (f_gphy_fw_dma) ltq_mix_firmware_config(f_gphy_fw_dma, 2); } } } } + return len; } static int proc_read_phy_fw(struct seq_file *seq, void *v) { - return 0; + return 0; } /* static void space_ignore(char **p, int *len) @@ -524,39 +549,43 @@ static void space_ignore(char **p, int *len) static int get_number(char **p, int *len, int is_hex) { int ret = 0, n = 0; - if ( (*p)[0] == '0' && (*p)[1] == 'x' ) { + + if ((*p)[0] == '0' && (*p)[1] == 'x') { is_hex = 1; (*p) += 2; (*len) -= 2; } - if ( is_hex ) { - while ( *len && ((**p >= '0' && **p <= '9') \ - || (**p >= 'a' && **p <= 'f') || (**p >= 'A' && **p <= 'F'))) { - if ( **p >= '0' && **p <= '9' ) + + if (is_hex) { + while (*len && ((**p >= '0' && **p <= '9') \ + || (**p >= 'a' && **p <= 'f') || (**p >= 'A' && **p <= 'F'))) { + if (**p >= '0' && **p <= '9') n = **p - '0'; - else if ( **p >= 'a' && **p <= 'f' ) + else if (**p >= 'a' && **p <= 'f') n = **p - 'a' + 10; - else if ( **p >= 'A' && **p <= 'F' ) + else if (**p >= 'A' && **p <= 'F') n = **p - 'A' + 10; + ret = (ret << 4) | n; (*p)++; (*len)--; } } else { - while ( *len && **p >= '0' && **p <= '9' ) { + while (*len && **p >= '0' && **p <= '9') { n = **p - '0'; ret = ret * 10 + n; (*p)++; (*len)--; } } + return ret; } #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR static int proc_read_phy_ssd_open(struct inode *inode, struct file *file) { - return single_open(file, proc_read_phy_on, NULL); + return single_open(file, proc_read_phy_on, NULL); } static ssize_t proc_write_phy_ssd(struct file *file, const char __user *buf, size_t count, loff_t *data) @@ -566,33 +595,38 @@ static ssize_t proc_write_phy_ssd(struct file *file, const char __user *buf, siz char *p; len = sizeof(local_buf) < count ? sizeof(local_buf) - 1 : count; rlen = len - copy_from_user((local_buf), buf, len); - while ( rlen && local_buf[rlen - 1] <= ' ' ) + + while (rlen && local_buf[rlen - 1] <= ' ') rlen--; + local_buf[rlen] = 0; - for ( p = local_buf; *p && *p <= ' '; p++, rlen-- ); - if ( !*p ) + + for (p = local_buf; *p && *p <= ' '; p++, rlen--); + + if (!*p) return 0; + num = get_number(&p, &rlen, 0); - ssd_interval = ( num < 2 )? 1 : num; + ssd_interval = (num < 2) ? 1 : num; return len; } static struct file_operations file_phy_ssd_fops = { - .owner = THIS_MODULE, - .open = proc_read_phy_ssd_open, - .read = seq_read, - .write = proc_write_phy_ssd, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = proc_read_phy_ssd_open, + .read = seq_read, + .write = proc_write_phy_ssd, + .llseek = seq_lseek, + .release = single_release, }; #endif /* PHY_SSD_ERROR */ static struct file_operations file_phy_on_fops = { - .owner = THIS_MODULE, - .open = proc_read_phy_on_open, - .read = seq_read, - .write = proc_write_phy_on, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = proc_read_phy_on_open, + .read = seq_read, + .write = proc_write_phy_on, + .llseek = seq_lseek, + .release = single_release, }; static ssize_t proc_write_phy_on(struct file *file, const char __user *buf, size_t count, loff_t *data) @@ -602,34 +636,39 @@ static ssize_t proc_write_phy_on(struct file *file, const char __user *buf, size char *p; len = sizeof(local_buf) < count ? sizeof(local_buf) - 1 : count; rlen = len - copy_from_user((local_buf), buf, len); - while ( rlen && local_buf[rlen - 1] <= ' ' ) + + while (rlen && local_buf[rlen - 1] <= ' ') rlen--; + local_buf[rlen] = 0; - for ( p = local_buf; *p && *p <= ' '; p++, rlen-- ); - if ( !*p ) + + for (p = local_buf; *p && *p <= ' '; p++, rlen--); + + if (!*p) return 0; + num = get_number(&p, &rlen, 0); - on_interval = ( num < 4 )? 3 : num; + on_interval = (num < 4) ? 3 : num; return len; } static int proc_read_phy_on_open(struct inode *inode, struct file *file) { - return single_open(file, proc_read_phy_on, NULL); + return single_open(file, proc_read_phy_on, NULL); } static int proc_read_phy_on(struct seq_file *seq, void *v) { - return 0; + return 0; } static struct file_operations file_phy_off_fops = { - .owner = THIS_MODULE, - .open = proc_read_phy_off_open, - .read = seq_read, - .write = proc_write_phy_off, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = proc_read_phy_off_open, + .read = seq_read, + .write = proc_write_phy_off, + .llseek = seq_lseek, + .release = single_release, }; static ssize_t proc_write_phy_off(struct file *file, const char __user *buf, size_t count, loff_t *data) @@ -639,23 +678,28 @@ static ssize_t proc_write_phy_off(struct file *file, const char __user *buf, siz char *p; len = sizeof(local_buf) < count ? sizeof(local_buf) - 1 : count; rlen = len - copy_from_user((local_buf), buf, len); - while ( rlen && local_buf[rlen - 1] <= ' ' ) + + while (rlen && local_buf[rlen - 1] <= ' ') rlen--; + local_buf[rlen] = 0; - for ( p = local_buf; *p && *p <= ' '; p++, rlen-- ); - if ( !*p ) + + for (p = local_buf; *p && *p <= ' '; p++, rlen--); + + if (!*p) return 0; + num = get_number(&p, &rlen, 0); - off_interval = ( num < 4 )? 5 : num; + off_interval = (num < 4) ? 5 : num; return len; } static int proc_read_phy_off_open(struct inode *inode, struct file *file) { - return single_open(file, proc_read_phy_off, NULL); + return single_open(file, proc_read_phy_off, NULL); } static int proc_read_phy_off(struct seq_file *seq, void *v) { - return 0; + return 0; } static struct file_operations file_ver_fops = { .owner = THIS_MODULE, @@ -673,7 +717,7 @@ static int proc_read_ver_open(struct inode *inode, struct file *file) static int proc_read_ver(struct seq_file *seq, void *v) { seq_printf(seq, "LTQ GPHY driver %s, version %s, on:%d, off:%d, pw_mode:%d, ssd_interval:%d\n", \ - g_gphy_fw_mode, version, on_interval, off_interval, pw_save_mode, ssd_interval); + g_gphy_fw_mode, version, on_interval, off_interval, pw_save_mode, ssd_interval); return 0; } @@ -682,24 +726,36 @@ static int proc_file_create(void) struct proc_dir_entry *entry; g_proc_gphy_dir = proc_mkdir("driver/ltq_gphy", NULL); + if (!g_proc_gphy_dir) return -ENOMEM; - entry = proc_create ("version", S_IRUGO, g_proc_gphy_dir, &file_ver_fops); + + entry = proc_create("version", S_IRUGO, g_proc_gphy_dir, &file_ver_fops); + if (!entry) goto Err0; - entry = proc_create ("phyfirmware", S_IRUGO|S_IWUSR, g_proc_gphy_dir, &file_phy_fw_fops); + + entry = proc_create("phyfirmware", S_IRUGO | S_IWUSR, g_proc_gphy_dir, &file_phy_fw_fops); + if (!entry) goto Err2; - entry = proc_create ("on_delay", S_IRUGO|S_IWUSR, g_proc_gphy_dir, &file_phy_on_fops); + + entry = proc_create("on_delay", S_IRUGO | S_IWUSR, g_proc_gphy_dir, &file_phy_on_fops); + if (!entry) goto Err3; - entry = proc_create ("off_delay", S_IRUGO|S_IWUSR, g_proc_gphy_dir, &file_phy_off_fops); + + entry = proc_create("off_delay", S_IRUGO | S_IWUSR, g_proc_gphy_dir, &file_phy_off_fops); + if (!entry) goto Err4; + #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR - entry = proc_create ("ssd_delay", S_IRUGO|S_IWUSR, g_proc_gphy_dir, &file_phy_ssd_fops); + entry = proc_create("ssd_delay", S_IRUGO | S_IWUSR, g_proc_gphy_dir, &file_phy_ssd_fops); + if (!entry) goto Err5; + #endif /* PHY_SSD_ERROR */ return 0; #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR @@ -721,12 +777,13 @@ static void proc_file_delete(void) { if (!g_proc_gphy_dir) return; + remove_proc_entry("version", g_proc_gphy_dir); remove_proc_entry("phyfirmware", g_proc_gphy_dir); remove_proc_entry("driver/ltq_gphy", NULL); } -static dma_addr_t xway_gphy_load (unsigned char *pData) +static dma_addr_t xway_gphy_load(unsigned char *pData) { dma_addr_t dev_addr = 0; void *fw_addr; @@ -736,11 +793,14 @@ static dma_addr_t xway_gphy_load (unsigned char *pData) * memory area with a 16 kB boundary aligned start address */ size = fw_len + XWAY_GPHY_FW_ALIGN; + if (g_fw_addr) { dma_free_coherent(gphy_dev, size, g_fw_addr, g_dev_addr); g_fw_addr = NULL; } + fw_addr = dma_alloc_coherent(gphy_dev, size, &dev_addr, GFP_KERNEL); + if (fw_addr) { fw_addr = PTR_ALIGN(fw_addr, XWAY_GPHY_FW_ALIGN); dev_addr = ALIGN(dev_addr, XWAY_GPHY_FW_ALIGN); @@ -750,10 +810,11 @@ static dma_addr_t xway_gphy_load (unsigned char *pData) } else { dev_err(gphy_dev, "failed to alloc firmware memory\n"); } + return dev_addr; } -static dma_addr_t xway_fphy_load (unsigned char *pData) +static dma_addr_t xway_fphy_load(unsigned char *pData) { dma_addr_t dev_addr = 0; void *fw_addr; @@ -763,11 +824,14 @@ static dma_addr_t xway_fphy_load (unsigned char *pData) * memory area with a 16 kB boundary aligned start address */ size = fw_len + XWAY_GPHY_FW_ALIGN; + if (f_fw_addr) { dma_free_coherent(gphy_dev, size, f_fw_addr, f_dev_addr); f_fw_addr = NULL; } + fw_addr = dma_alloc_coherent(gphy_dev, size, &dev_addr, GFP_KERNEL); + if (fw_addr) { fw_addr = PTR_ALIGN(fw_addr, XWAY_GPHY_FW_ALIGN); dev_addr = ALIGN(dev_addr, XWAY_GPHY_FW_ALIGN); @@ -777,25 +841,29 @@ static dma_addr_t xway_fphy_load (unsigned char *pData) } else { dev_err(gphy_dev, "failed to alloc firmware memory\n"); } + return dev_addr; } /* reset and boot a gphy. these phys only exist on xrx200 SoC */ int xway_gphy_rcu_config(unsigned int id, dma_addr_t dev_addr) { - if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220") ) { + if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220")) { struct clk *clk; clk = clk_get_sys("1f203000.rcu", "gphy"); + if (IS_ERR(clk)) return PTR_ERR(clk); + clk_enable(clk); } - if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220") ) { + if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220")) { if (id > 1) { dev_info(gphy_dev, "%u is an invalid gphy id\n", id); return -EINVAL; } + ltq_rcu_w32_mask(0, xrx200_gphy[id].rd, RCU_RST_REQ); ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); ltq_rcu_w32_mask(xrx200_gphy[id].rd, 0, RCU_RST_REQ); @@ -805,6 +873,7 @@ int xway_gphy_rcu_config(unsigned int id, dma_addr_t dev_addr) dev_info(gphy_dev, "%u is an invalid gphy id\n", id); return -EINVAL; } + ltq_rcu_w32_mask(0, xrx300_gphy[id].rd, RCU_RST_REQ); ltq_rcu_w32(dev_addr, xrx300_gphy[id].addr); ltq_rcu_w32_mask(xrx300_gphy[id].rd, 0, RCU_RST_REQ); @@ -814,6 +883,7 @@ int xway_gphy_rcu_config(unsigned int id, dma_addr_t dev_addr) dev_info(gphy_dev, "%u is an invalid gphy id\n", id); return -EINVAL; } + ltq_rcu_w32_mask(0, xrx330_gphy[id].rd, RCU_RST_REQ); ltq_rcu_w32(dev_addr, xrx330_gphy[id].addr); ltq_rcu_w32_mask(xrx330_gphy[id].rd, 0, RCU_RST_REQ); @@ -823,12 +893,14 @@ int xway_gphy_rcu_config(unsigned int id, dma_addr_t dev_addr) dev_info(gphy_dev, "%u is an invalid gphy id\n", id); return -EINVAL; } + ltq_rcu_w32_mask(0, xrx500_gphy[id].rd, RCU_RST_REQ); gsw_reg_w32((dev_addr & 0xFFFF), xrx500_gphy[id].addr); gsw_reg_w32(((dev_addr >> 16) & 0xFFFF), (xrx500_gphy[id].addr + 4)); ltq_rcu_w32_mask(xrx500_gphy[id].rd, 0, RCU_RST_REQ); dev_info(gphy_dev, "booting GPHY%u firmware at %X for GRX500\n", id, dev_addr); } + return 0; } @@ -837,39 +909,50 @@ static int ltq_gphy_firmware_config() int i; dma_addr_t data_ptr; data_ptr = xway_gphy_load(g_gphy_fw_dma); + if (g_gphy_fw_dma) kfree(g_gphy_fw_dma); + if (!data_ptr) return -ENOMEM; + for (i = 0; i < g_no_phys; i++) - xway_gphy_rcu_config(i,data_ptr); - pr_err("%s: fw_mode:%s, no of phys:%d,data_ptr:%X\n", __func__, g_gphy_fw_mode, g_no_phys,data_ptr); + xway_gphy_rcu_config(i, data_ptr); + + pr_err("%s: fw_mode:%s, no of phys:%d,data_ptr:%X\n", __func__, g_gphy_fw_mode, g_no_phys, data_ptr); return 0; } -static int ltq_mix_firmware_config (u8 *fw_ptr, int mix_mode) +static int ltq_mix_firmware_config(u8 *fw_ptr, int mix_mode) { int i; dma_addr_t data_ptr = 0; + if (mix_mode == 1) data_ptr = xway_gphy_load(fw_ptr); + if (mix_mode == 2) data_ptr = xway_fphy_load(fw_ptr); + if (fw_ptr) kfree(fw_ptr); + if (!data_ptr) return -ENOMEM; + for (i = 0; i < g_no_phys; i++) { if ((mix_mode == 1) && (phy_fw_type[i] == 1)) - xway_gphy_rcu_config(i,data_ptr); + xway_gphy_rcu_config(i, data_ptr); + if ((mix_mode == 2) && (phy_fw_type[i] == 2)) - xway_gphy_rcu_config(i,data_ptr); + xway_gphy_rcu_config(i, data_ptr); } - pr_err("%s: fw_mode:%s, no of phys:%d,data_ptr:%X,mix_mode:%d \n", __func__, g_gphy_fw_mode, g_no_phys,data_ptr, mix_mode); + + pr_err("%s: fw_mode:%s, no of phys:%d,data_ptr:%X,mix_mode:%d \n", __func__, g_gphy_fw_mode, g_no_phys, data_ptr, mix_mode); return 0; } -static void gsw_mdio_data_write(unsigned int phyAddr, unsigned int regAddr,unsigned int data) +static void gsw_mdio_data_write(unsigned int phyAddr, unsigned int regAddr, unsigned int data) { GSW_MDIO_data_t mdio_data; memset(&mdio_data, 0, sizeof(GSW_MDIO_data_t)); @@ -877,7 +960,7 @@ static void gsw_mdio_data_write(unsigned int phyAddr, unsigned int regAddr,unsig mdio_data.nAddressReg = regAddr; mdio_data.nData = data; ops->gsw_common_ops.MDIO_DataWrite(ops, (unsigned int)&mdio_data); - return ; + return ; } static unsigned short gsw_mdio_data_read(unsigned int phyAddr, unsigned int regAddr) @@ -887,7 +970,7 @@ static unsigned short gsw_mdio_data_read(unsigned int phyAddr, unsigned int regA mdio_data.nAddressDev = phyAddr; mdio_data.nAddressReg = regAddr; ops->gsw_common_ops.MDIO_DataRead(ops, (unsigned int)&mdio_data); - return (mdio_data.nData); + return (mdio_data.nData); } #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR @@ -898,20 +981,23 @@ static unsigned short gsw_mmd_data_read(unsigned int phyAddr, unsigned int regAd mmd_data.nAddressDev = phyAddr; mmd_data.nAddressReg = regAddr; ops->gsw_common_ops.MmdDataRead(ops, (unsigned int)&mmd_data); - return (mmd_data.nData); + return (mmd_data.nData); } #endif /* PHY_SSD_ERROR */ -static int gphy_pw_save_thread (void *arg) +static int gphy_pw_save_thread(void *arg) { - allow_signal(SIGKILL); - while(!kthread_should_stop ()) { + allow_signal(SIGKILL); + + while (!kthread_should_stop()) { u8 index; GSW_portLinkCfg_t param; memset(¶m, 0, sizeof(GSW_portLinkCfg_t)); set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) break; + /* Get the port Link Status */ for (index = 0; index < NUM_OF_PORTS; index++) { if ((gphy_power_down[index] == 1) && (gphy_link_status[index] == 0)) { @@ -921,45 +1007,56 @@ static int gphy_pw_save_thread (void *arg) gsw_mdio_data_write(index, 0x0, reg0_val); } } - interruptible_sleep_on_timeout(&gphy_pw_wait, (on_interval * HZ) ); + + interruptible_sleep_on_timeout(&gphy_pw_wait, (on_interval * HZ)); + for (index = 0; index < NUM_OF_PORTS; index++) { param.nPortId = index; ops->gsw_common_ops.PortLinkCfgGet(ops, (unsigned int)¶m); - if (param.eLink == 0 ) { + + if (param.eLink == 0) { gphy_link_status[index] = 1; power_down_cnt[index] = 0; } else { gphy_link_status[index] = 0; power_down_cnt[index]++; + if ((power_down_cnt[index] % 6) != 0) { u16 reg0_val; reg0_val = gsw_mdio_data_read(index, 0x0); reg0_val |= (0x800); gsw_mdio_data_write(index, 0x0, reg0_val); } + gphy_power_down[index] = 1; } } + /*poll again once configured time is up */ - interruptible_sleep_on_timeout(&gphy_pw_wait, (off_interval * HZ) ); + interruptible_sleep_on_timeout(&gphy_pw_wait, (off_interval * HZ)); } + return 0; } #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR -static int gphy_ssd_err_thread (void *arg) +static int gphy_ssd_err_thread(void *arg) { - allow_signal(SIGKILL); - while(!kthread_should_stop ()) { + allow_signal(SIGKILL); + + while (!kthread_should_stop()) { u8 index; GSW_portLinkCfg_t param; set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) break; + /* Get the port Link Status */ for (index = 0; index < NUM_OF_PORTS; index++) { memset(¶m, 0, sizeof(GSW_portLinkCfg_t)); param.nPortId = index; ops->gsw_common_ops.PortLinkCfgGet(ops, (unsigned int)¶m); + if ((param.eLink == 0) && (gphy_link_status[index] == 0)) { gphy_link_status[index] = 1; ssd_cnt[index] = 0; @@ -968,13 +1065,16 @@ static int gphy_ssd_err_thread (void *arg) ssd_cnt[index] = 0; } } + for (index = 0; index < NUM_OF_PORTS; index++) { if ((gphy_link_status[index] == 1)) { u16 reg0_val; ssd_cnt[index]++; - if ((ssd_cnt[index] % 3) == 0 ) { + + if ((ssd_cnt[index] % 3) == 0) { ssd_cnt[index] = 0; reg0_val = gsw_mmd_data_read(index, 0x1F07be); + if ((reg0_val >> 1) & 0x1) { u16 reg1_val; reg1_val = gsw_mdio_data_read(index, 0x0); @@ -984,8 +1084,10 @@ static int gphy_ssd_err_thread (void *arg) } } } - interruptible_sleep_on_timeout(&gphy_ssd_wait, (ssd_interval * HZ) ); + + interruptible_sleep_on_timeout(&gphy_ssd_wait, (ssd_interval * HZ)); } + return 0; } #endif /* PHY_SSD_ERROR */ @@ -993,25 +1095,30 @@ static int gphy_ssd_err_thread (void *arg) /* Switches on the LED */ /* Input: port * : on_off */ - /* Process: Use the GPIO to ON/OFF the LED - */ - void gphy_data_led_on_off (int port, int on_off) - { - u32 gpio_pin = GPHY_2_GPIO; - switch (port) { - case 2: - gpio_pin = GPHY_2_GPIO; - break; - case 3: - gpio_pin = GPHY_3_GPIO; - break; - case 4: - gpio_pin = GPHY_4_GPIO; - break; - case 5: - gpio_pin = GPHY_5_GPIO; - break; +/* Process: Use the GPIO to ON/OFF the LED +*/ +void gphy_data_led_on_off(int port, int on_off) +{ + u32 gpio_pin = GPHY_2_GPIO; + + switch (port) { + case 2: + gpio_pin = GPHY_2_GPIO; + break; + + case 3: + gpio_pin = GPHY_3_GPIO; + break; + + case 4: + gpio_pin = GPHY_4_GPIO; + break; + + case 5: + gpio_pin = GPHY_5_GPIO; + break; } + if (on_off) { gpio_set_value(gpio_pin, 1); } else { @@ -1019,26 +1126,31 @@ static int gphy_ssd_err_thread (void *arg) } } -static int gphy_rmon_poll_thread (void *arg) +static int gphy_rmon_poll_thread(void *arg) { int port; int port_rx[NUM_OF_PORTS]; - int port_rx_prev[NUM_OF_PORTS] = {0,0,0,0,0,0}; + int port_rx_prev[NUM_OF_PORTS] = {0, 0, 0, 0, 0, 0}; int port_tx[NUM_OF_PORTS]; - int port_tx_prev[NUM_OF_PORTS] = {0,0,0,0,0,0}; + int port_tx_prev[NUM_OF_PORTS] = {0, 0, 0, 0, 0, 0}; GSW_RMON_Port_cnt_t param; GSW_portLinkCfg_t param_link; - printk (KERN_INFO "start %p ..\n", current); + printk(KERN_INFO "start %p ..\n", current); allow_signal(SIGKILL); - while(!kthread_should_stop ()) { + + while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) break; + ops = gsw_get_swcore_ops(0); - if(!ops) { + + if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); return -EIO; - } + } + for (port = 2; port < NUM_OF_PORTS; port++) { memset(¶m, 0, sizeof(GSW_RMON_Port_cnt_t)); memset(¶m_link, 0, sizeof(GSW_portLinkCfg_t)); @@ -1047,7 +1159,8 @@ static int gphy_rmon_poll_thread (void *arg) ops->gsw_rmon_ops.RMON_Port_Get(ops, (unsigned int)¶m); port_rx[port] = param.nRxGoodPkts; port_tx[port] = param.nTxGoodPkts; - if ((port_rx[port] != port_rx_prev[port]) ||(port_tx[port] != port_tx_prev[port])) { + + if ((port_rx[port] != port_rx_prev[port]) || (port_tx[port] != port_tx_prev[port])) { if (gphy_led_status_on[port] == 0) { gphy_led_status_on[port] = 1; gphy_data_led_on_off(port, LED_ON); @@ -1055,21 +1168,25 @@ static int gphy_rmon_poll_thread (void *arg) gphy_led_status_on[port] = 0; gphy_data_led_on_off(port, LED_OFF); } + port_rx_prev[port] = port_rx[port]; port_tx_prev[port] = port_tx[port]; } else { ops->gsw_common_ops.PortLinkCfgGet(ops, (unsigned int)¶m_link); - if (param_link.eLink == 0 ) { + + if (param_link.eLink == 0) { gphy_led_status_on[port] = 1; - gphy_data_led_on_off (port, LED_ON); + gphy_data_led_on_off(port, LED_ON); } else { gphy_led_status_on[port] = 0; - gphy_data_led_on_off (port, LED_OFF); + gphy_data_led_on_off(port, LED_OFF); } } } + msleep(30); } + return 0; } @@ -1079,30 +1196,36 @@ int AR10_F2_GPHY_LED_init(void) gpio_direction_output(GPHY_2_GPIO, 1); //set gpio direction as output else printk(KERN_EMERG "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + if (!gpio_request(GPHY_3_GPIO, "SW-LED")) gpio_direction_output(GPHY_3_GPIO, 1); //set gpio direction as output else return 1; + if (!gpio_request(GPHY_4_GPIO, "SW-LED")) gpio_direction_output(GPHY_4_GPIO, 1); //set gpio direction as output else return 1; + if (!gpio_request(GPHY_5_GPIO, "SW-LED")) gpio_direction_output(GPHY_5_GPIO, 1); //set gpio direction as output else return 1; + gphy_rmon_poll_thread_id = kthread_create(gphy_rmon_poll_thread, NULL, \ - "gphy_rmon_poll_thread"); + "gphy_rmon_poll_thread"); + if (!IS_ERR(gphy_rmon_poll_thread_id)) { - printk (KERN_EMERG "GPHY RMON poll thread created..\n"); + printk(KERN_EMERG "GPHY RMON poll thread created..\n"); wake_up_process(gphy_rmon_poll_thread_id); } + return 0; } //end For VRX220 SW control PHY LED -static int __init gphy_driver_init (struct platform_device *pdev) -{ +static int __init gphy_driver_init(struct platform_device *pdev) +{ const __be32 *no_phys; gphy_dev = &pdev->dev; gphy_node = pdev->dev.of_node; @@ -1116,83 +1239,104 @@ static int __init gphy_driver_init (struct platform_device *pdev) ssd_interval = 4; #endif /* PHY_SSD_ERROR */ dev_id = 0; + if (of_property_read_string(pdev->dev.of_node, "fw-mode", &g_gphy_fw_mode)) { pr_err("%s:%s:%d (failed to read firmware mode)\n", __FILE__, __func__, __LINE__); -/* dev_err(&pdev->dev, "failed to read firmware mode\n");*/ + /* dev_err(&pdev->dev, "failed to read firmware mode\n");*/ return 0; } + no_phys = of_get_property(gphy_node, "no_of_phys", NULL); + if (!no_phys) { pr_err("%s:%s:%d (failed to get maximum number of internal gphys ports)\n", __FILE__, __func__, __LINE__); -/* dev_err(&pdev->dev, "failed to get maximum number of internal gphys ports\n");*/ + /* dev_err(&pdev->dev, "failed to get maximum number of internal gphys ports\n");*/ return 0; } + g_no_phys = (*no_phys); - - if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220") ) { + + if (of_machine_is_compatible("lantiq,vr9") || of_machine_is_compatible("lantiq,xrx220")) { // int type = ltq_get_soc_type(); // if (type == SOC_TYPE_VR9) /*SOC_TYPE_VR9_2*/ // dev_id = 0; // else - dev_id = 1; + dev_id = 1; } else if (of_machine_is_compatible("lantiq,ar10")) { dev_id = 1; no_phys = of_get_property(gphy_node, "pw_save_mode", NULL); + if (no_phys) pw_save_mode = (*no_phys); } else if (of_machine_is_compatible("lantiq,grx390")) { dev_id = 1; no_phys = of_get_property(gphy_node, "pw_save_mode", NULL); + if (no_phys) pw_save_mode = (*no_phys); } else if (of_machine_is_compatible("lantiq,grx500")) { dev_id = 1; } - if (of_machine_is_compatible("lantiq,xrx220") ) { + + if (of_machine_is_compatible("lantiq,xrx220")) { int i; of_property_read_u32_array(gphy_node, "phy_port_nos", phy_port_nos, g_no_phys); of_property_read_u32_array(gphy_node, "phy_fw_type", phy_fw_type, g_no_phys); + for (i = 0; i < g_no_phys; i++) { pr_err("phy_port_nos[%d]:%d, phy_fw_type[%d]:%d\n", i, phy_port_nos[i], i, phy_fw_type[i]); } } + proc_file_create(); pr_err("%s: fw_mode:%s, no of phys:%d, mode:%d\n", \ - __func__, g_gphy_fw_mode, g_no_phys, pw_save_mode); + __func__, g_gphy_fw_mode, g_no_phys, pw_save_mode); + if (of_machine_is_compatible("lantiq,grx390")) { - if ( (pw_save_mode == 1) || (ssd_err_mode == 1) ) { + if ((pw_save_mode == 1) || (ssd_err_mode == 1)) { ops = gsw_get_swcore_ops(0); - if(!ops) { + + if (!ops) { pr_err("%s: Open SWAPI device FAILED!\n", __func__); return -EIO; } - if ( pw_save_mode == 1 ) { + + if (pw_save_mode == 1) { init_waitqueue_head(&gphy_pw_wait); gphy_pw_id = kthread_create(gphy_pw_save_thread, NULL, "gphy_pw_save"); + if (!IS_ERR(gphy_pw_id)) wake_up_process(gphy_pw_id); } - #if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR - if ( ssd_err_mode == 1 ) { + +#if defined(PHY_SSD_ERROR) && PHY_SSD_ERROR + + if (ssd_err_mode == 1) { init_waitqueue_head(&gphy_ssd_wait); gphy_ssd_id = kthread_create(gphy_ssd_err_thread, NULL, "gphy_ssd_wait"); + if (!IS_ERR(gphy_ssd_id)) wake_up_process(gphy_ssd_id); } - #endif /* PHY_SSD_ERROR */ + +#endif /* PHY_SSD_ERROR */ } } - //For VRX220 SW control PHY LED + + //For VRX220 SW control PHY LED if (of_machine_is_compatible("lantiq,xrx220")) - AR10_F2_GPHY_LED_init(); + AR10_F2_GPHY_LED_init(); + return 0; } -static int __init gphy_driver_exit (struct platform_device *pdev) +static int __init gphy_driver_exit(struct platform_device *pdev) { proc_file_delete(); - if ( pw_save_mode == 1 ) + + if (pw_save_mode == 1) ops = NULL; + return 0; } diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_init.c b/drivers/net/ethernet/lantiq/switch-api/gsw_init.c index 4cd3be5796c5bf4d70736184cc89fdd05da9fec5..789f6d739b49058a53d890f6660df81a109438aa 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_init.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_init.c @@ -8,8 +8,7 @@ For licensing information, see the file 'LICENSE' in the root folder of this software module. ******************************************************************************/ - - +#ifdef __KERNEL__ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> /* printk() */ @@ -22,12 +21,12 @@ #include <linux/version.h> #ifndef CONFIG_X86_INTEL_CE2700 + #include <lantiq.h> #include <lantiq_soc.h> #else #include <linux/netip_subsystem.h> #include <linux/avalanche/generic/modphy_mrpc_api.h> - extern int DWC_ETH_QOS_mdio_read_direct(int bus_number, bool c45, int phyaddr, int mmd, int phyreg, int *phydata); extern int DWC_ETH_QOS_mdio_write_direct(int bus_number, bool c45, int phyaddr, int mmd, int phyreg, int phydata); @@ -36,7 +35,6 @@ extern int DWC_ETH_QOS_mdio_write_direct(int bus_number, bool c45, int phyaddr, #define MMD_DISABLED 32 #define MDIO_BUS_NUMBER_0 0 - /* netip-subsystem gpio value set register*/ #define DATA_OUT_SET_REG_OFFSET 0x14 /* netip-subsystem gpio value clear register*/ @@ -46,13 +44,9 @@ extern int DWC_ETH_QOS_mdio_write_direct(int bus_number, bool c45, int phyaddr, #define NETSS_GPIO_17 (1 << 17) #define NETSS_GPIO_19 (1 << 19) + #endif /*CONFIG_X86_INTEL_CE2700*/ -#include "gsw_init.h" - -void __iomem *addr_gswl; -void __iomem *addr_gswr; -void __iomem *addr_gsw; #define sw_w32(x, y) ltq_w32((x), (addr_gswl + (y))) #define sw_r32(x) ltq_r32(addr_gswl + (x)) @@ -60,14 +54,26 @@ void __iomem *addr_gsw; #define gsw1_w32(x, y) ltq_w32((x), ((y))) #define gsw1_r32(x) ltq_r32((x)) -#if 0 -void gsw_reg_w32(uint32_t val, uint32_t reg_off) -{ - sw_w32(val, reg_off); -} -EXPORT_SYMBOL_GPL(gsw_reg_w32); + +void __iomem *addr_gswl; +void __iomem *addr_gswr; +void __iomem *addr_gsw; + +#endif /* KERNEL_MODE */ + +#if defined(WIN_PC_MODE) && WIN_PC_MODE +void *addr_gswl; +void *addr_gswr; +void *addr_gsw; #endif +#include <gsw_init.h> + +#if defined(UART_INTERFACE) && UART_INTERFACE +static int uart_reg_rd(u32 regaddr, u32 *data); +static int uart_reg_wr(u32 regaddr, u32 data); +#endif /* UART_INTERFACE */ + #define GSW_API_MAJOR_NUMBER 81 #define LTQ_INT_GSWITCH 0 #define LTQ_EXT_GSWITCH 1 @@ -92,311 +98,336 @@ static const u16 gsw_ops_type[] = { GSW_COMMON_MAGIC, GSW_ROUTE_MAGIC, GSW_DEBUG_MAGIC, + GSW_IRQ_MAGIC }; extern ltq_lowlevel_fkts_t ltq_flow_fkt_tbl; +#ifdef __KERNEL__ extern ltq_lowlevel_fkts_t ltq_rt_fkt_tbl; +#endif + ioctl_wrapper_init_t ioctlinit; ioctl_wrapper_ctx_t *pioctlctl = NULL; ethsw_api_dev_t *pEDev0 = NULL, *pEDev1 = NULL; -struct ltq_lowlevel_fkts_t * ioct_cmd_start_node=NULL; +struct ltq_lowlevel_fkts_t *ioct_cmd_start_node = NULL; + +#if defined(WIN_PC_MODE) && WIN_PC_MODE +struct core_ops *gsw_get_swcore_ops(u32 devid) +{ + if (devid == 0) + return (&pEDev0->ops); + if (devid == 1) + return (&pEDev1->ops); +} -static void insert_ioctl_type (ltq_lowlevel_fkts_t ops_content,struct fkts_linklist *node) +#endif + +static void insert_ioctl_type(ltq_lowlevel_fkts_t ops_content, struct fkts_linklist *node) { ltq_lowlevel_fkts_t *current_ptr; - current_ptr= (ltq_lowlevel_fkts_t *)kmalloc(sizeof(ltq_lowlevel_fkts_t), GFP_KERNEL); +#ifdef __KERNEL__ + current_ptr = (ltq_lowlevel_fkts_t *)kmalloc(sizeof(ltq_lowlevel_fkts_t), GFP_KERNEL); +#else + current_ptr = (ltq_lowlevel_fkts_t *)malloc(sizeof(ltq_lowlevel_fkts_t)); +#endif //printk("ltq_lowlevel_fkts_t ptr =%x\n",(unsigned int)current_ptr); - current_ptr->pNext=NULL; - current_ptr->nType=ops_content.nType; - current_ptr->nNumFkts=(ops_content.nNumFkts + 1); - current_ptr->pFkts=ops_content.pFkts; - - if (node->first_ptr !=NULL) { - node->last_ptr->pNext=current_ptr; - node->last_ptr=current_ptr; + current_ptr->pNext = NULL; + current_ptr->nType = ops_content.nType; + current_ptr->nNumFkts = (ops_content.nNumFkts + 1); + current_ptr->pFkts = ops_content.pFkts; + + if (node->first_ptr != NULL) { + node->last_ptr->pNext = current_ptr; + node->last_ptr = current_ptr; } else { - node->first_ptr=node->last_ptr=current_ptr; + node->first_ptr = node->last_ptr = current_ptr; } } -static void gsw_delete_ioctl_cmd_linklist(ltq_lowlevel_fkts_t* first_node) +static void gsw_delete_ioctl_cmd_linklist(ltq_lowlevel_fkts_t *first_node) { - ltq_lowlevel_fkts_t *free_node,*last_node; + ltq_lowlevel_fkts_t *free_node, *last_node; last_node = first_node; - while(last_node != NULL) { + + while (last_node != NULL) { free_node = last_node; last_node = last_node->pNext; +#ifdef __KERNEL__ kfree(free_node); +#else + free(free_node); +#endif } } -static ltq_lowlevel_fkts_t* gsw_create_ioctl_cmd_linklist (struct core_ops *ops) +static ltq_lowlevel_fkts_t *gsw_create_ioctl_cmd_linklist(struct core_ops *ops) { struct fkts_linklist *node; - ltq_lowlevel_fkts_t* first_node; + ltq_lowlevel_fkts_t *first_node; ltq_lowlevel_fkts_t ops_content; - u16 i,num_of_types=0; - - node=(struct fkts_linklist *)kmalloc(sizeof(struct fkts_linklist), GFP_KERNEL); - node->first_ptr=NULL; - node->last_ptr=NULL; - - num_of_types = (sizeof(gsw_ops_type)/sizeof(gsw_ops_type[0])); - for(i=0;i < num_of_types;i++) - { - switch(gsw_ops_type[i]) { - case GSW_RMON_MAGIC: - ops_content.pNext=NULL; - //printk("address of rmon =%x\n",(unsigned int)&ops->gsw_rmon_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_rmon_ops; - ops_content.nType = GSW_RMON_MAGIC; - //printk("size of pdata_t.ops.gsw_rmon_ops = %x\n",(sizeof(ops->gsw_rmon_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_rmon_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_MAC_MAGIC: - ops_content.pNext=NULL; - //printk("address of mac =%x\n",(unsigned int)&ops->gsw_swmac_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_swmac_ops; - ops_content.nType = GSW_MAC_MAGIC; - //printk("size of pdata_t.ops.gsw_mac_ops = %x\n",(sizeof(ops->gsw_swmac_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_swmac_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_EXVLAN_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_extvlan_ops =%x\n",(unsigned int)&ops->gsw_extvlan_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_extvlan_ops; - ops_content.nType = GSW_EXVLAN_MAGIC; - //printk("size of pdata_t.ops.gsw_extvlan_ops = %x\n",(sizeof(ops->gsw_extvlan_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_extvlan_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_VLANFILTER_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_vlanfilter_ops =%x\n",(unsigned int)&ops->gsw_vlanfilter_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_vlanfilter_ops; - ops_content.nType = GSW_VLANFILTER_MAGIC; - //printk("size of pdata_t.ops.gsw_vlanfilter_ops = %x\n",(sizeof(ops->gsw_vlanfilter_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_vlanfilter_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_CTP_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_ctp_ops =%x\n",(unsigned int)&ops->gsw_ctp_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_ctp_ops; - ops_content.nType = GSW_CTP_MAGIC; - //printk("size of pdata_t.ops.gsw_ctp_ops = %x\n",(sizeof(ops->gsw_ctp_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_ctp_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_BRDGPORT_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_brdgport_ops =%x\n",(unsigned int)&ops->gsw_brdgport_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_brdgport_ops; - ops_content.nType = GSW_BRDGPORT_MAGIC; - //printk("size of pdata_t.ops.gsw_brdgport_ops = %x\n",(sizeof(ops->gsw_brdgport_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_brdgport_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_BRDG_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_brdg_ops =%x\n",(unsigned int)&ops->gsw_brdg_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_brdg_ops; - ops_content.nType = GSW_BRDG_MAGIC; - //printk("size of pdata_t.ops.gsw_brdg_ops = %x\n",(sizeof(ops->gsw_brdg_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_brdg_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_TFLOW_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_tflow_ops =%x\n",(unsigned int)&ops->gsw_tflow_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_tflow_ops; - ops_content.nType = GSW_TFLOW_MAGIC; - //printk("size of pdata_t.ops.gsw_tflow_ops = %x\n",(sizeof(ops->gsw_tflow_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_tflow_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_QOS_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_qos_ops =%x\n",(unsigned int)&ops->gsw_qos_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_qos_ops; - ops_content.nType = GSW_QOS_MAGIC; - //printk("size of pdata_t.ops.gsw_qos_ops = %x\n",(sizeof(ops->gsw_qos_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_qos_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_STP_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_stp_ops =%x\n",(unsigned int)&ops->gsw_stp_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_stp_ops; - ops_content.nType = GSW_STP_MAGIC; - //printk("size of pdata_t.ops.gsw_stp_ops = %x\n",(sizeof(ops->gsw_stp_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_stp_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_EAPOL_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_8021x_ops =%x\n",(unsigned int)&ops->gsw_8021x_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_8021x_ops; - ops_content.nType = GSW_EAPOL_MAGIC; - //printk("size of pdata_t.ops.gsw_8021x_ops = %x\n",(sizeof(ops->gsw_8021x_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_8021x_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_MULTICAST_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_multicast_ops =%x\n",(unsigned int)&ops->gsw_multicast_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_multicast_ops; - ops_content.nType = GSW_EAPOL_MAGIC; - //printk("size of pdata_t.ops.gsw_multicast_ops = %x\n",(sizeof(ops->gsw_multicast_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_multicast_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_TRUNKING_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_trunking_ops =%x\n",(unsigned int)&ops->gsw_trunking_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_trunking_ops; - ops_content.nType = GSW_TRUNKING_MAGIC; - //printk("size of pdata_t.ops.gsw_trunking_ops = %x\n",(sizeof(ops->gsw_trunking_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_trunking_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_WOL_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_wol_ops =%x\n",(unsigned int)&ops->gsw_wol_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_wol_ops; - ops_content.nType = GSW_WOL_MAGIC; - //printk("size of pdata_t.ops.gsw_wol_ops = %x\n",(sizeof(ops->gsw_wol_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_wol_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_VLAN_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_vlan_ops =%x\n",(unsigned int)&ops->gsw_vlan_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_vlan_ops; - ops_content.nType = GSW_VLAN_MAGIC; - //printk("size of pdata_t.ops.gsw_vlan_ops = %x\n",(sizeof(ops->gsw_vlan_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_vlan_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_PMAC_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_pmac_ops =%x\n",(unsigned int)&ops->gsw_pmac_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_pmac_ops; - ops_content.nType = GSW_PMAC_MAGIC; - //printk("size of pdata_t.ops.gsw_pmac_ops = %x\n",(sizeof(ops->gsw_pmac_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_pmac_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_ROUTE_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_pae_ops =%x\n",(unsigned int)&ops->gsw_pae_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_pae_ops; - ops_content.nType = GSW_ROUTE_MAGIC; - //printk("size of pdata_t.ops.gsw_pae_ops = %x\n",(sizeof(ops->gsw_pae_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_pae_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_COMMON_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_common_ops =%x\n",(unsigned int)&ops->gsw_common_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_common_ops; - ops_content.nType = GSW_COMMON_MAGIC; - //printk("size of pdata_t.ops.gsw_common_ops = %x\n",(sizeof(ops->gsw_common_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_common_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - case GSW_DEBUG_MAGIC: - ops_content.pNext=NULL; - //printk("address of gsw_debug_ops =%x....\n",(unsigned int)&ops->gsw_debug_ops); - ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_debug_ops; - ops_content.nType = GSW_DEBUG_MAGIC; - //printk("size of pdata_t.ops.gsw_debug_ops = %x\n",(sizeof(ops->gsw_debug_ops)/sizeof(ops_content.pFkts[0]))); - ops_content.nNumFkts = (sizeof(ops->gsw_debug_ops)/sizeof(ops_content.pFkts[0])); - insert_ioctl_type (ops_content,node); - break; - default: + u16 i, num_of_types = 0; +#ifdef __KERNEL__ + node = (struct fkts_linklist *)kmalloc(sizeof(struct fkts_linklist), GFP_KERNEL); +#else + node = (struct fkts_linklist *)malloc(sizeof(struct fkts_linklist)); +#endif + node->first_ptr = NULL; + node->last_ptr = NULL; + + num_of_types = (sizeof(gsw_ops_type) / sizeof(gsw_ops_type[0])); + + for (i = 0; i < num_of_types; i++) { + switch (gsw_ops_type[i]) { + case GSW_RMON_MAGIC: + ops_content.pNext = NULL; + //printk("address of rmon =%x\n",(unsigned int)&ops->gsw_rmon_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_rmon_ops; + ops_content.nType = GSW_RMON_MAGIC; + //printk("size of pdata_t.ops.gsw_rmon_ops = %x\n",(sizeof(ops->gsw_rmon_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_rmon_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_MAC_MAGIC: + ops_content.pNext = NULL; + //printk("address of mac =%x\n",(unsigned int)&ops->gsw_swmac_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_swmac_ops; + ops_content.nType = GSW_MAC_MAGIC; + //printk("size of pdata_t.ops.gsw_mac_ops = %x\n",(sizeof(ops->gsw_swmac_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_swmac_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_EXVLAN_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_extvlan_ops =%x\n",(unsigned int)&ops->gsw_extvlan_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_extvlan_ops; + ops_content.nType = GSW_EXVLAN_MAGIC; + //printk("size of pdata_t.ops.gsw_extvlan_ops = %x\n",(sizeof(ops->gsw_extvlan_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_extvlan_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_VLANFILTER_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_vlanfilter_ops =%x\n",(unsigned int)&ops->gsw_vlanfilter_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_vlanfilter_ops; + ops_content.nType = GSW_VLANFILTER_MAGIC; + //printk("size of pdata_t.ops.gsw_vlanfilter_ops = %x\n",(sizeof(ops->gsw_vlanfilter_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_vlanfilter_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_CTP_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_ctp_ops =%x\n",(unsigned int)&ops->gsw_ctp_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_ctp_ops; + ops_content.nType = GSW_CTP_MAGIC; + //printk("size of pdata_t.ops.gsw_ctp_ops = %x\n",(sizeof(ops->gsw_ctp_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_ctp_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_BRDGPORT_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_brdgport_ops =%x\n",(unsigned int)&ops->gsw_brdgport_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_brdgport_ops; + ops_content.nType = GSW_BRDGPORT_MAGIC; + //printk("size of pdata_t.ops.gsw_brdgport_ops = %x\n",(sizeof(ops->gsw_brdgport_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_brdgport_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_BRDG_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_brdg_ops =%x\n",(unsigned int)&ops->gsw_brdg_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_brdg_ops; + ops_content.nType = GSW_BRDG_MAGIC; + //printk("size of pdata_t.ops.gsw_brdg_ops = %x\n",(sizeof(ops->gsw_brdg_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_brdg_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_TFLOW_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_tflow_ops =%x\n",(unsigned int)&ops->gsw_tflow_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_tflow_ops; + ops_content.nType = GSW_TFLOW_MAGIC; + //printk("size of pdata_t.ops.gsw_tflow_ops = %x\n",(sizeof(ops->gsw_tflow_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_tflow_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_QOS_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_qos_ops =%x\n",(unsigned int)&ops->gsw_qos_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_qos_ops; + ops_content.nType = GSW_QOS_MAGIC; + //printk("size of pdata_t.ops.gsw_qos_ops = %x\n",(sizeof(ops->gsw_qos_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_qos_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_STP_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_stp_ops =%x\n",(unsigned int)&ops->gsw_stp_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_stp_ops; + ops_content.nType = GSW_STP_MAGIC; + //printk("size of pdata_t.ops.gsw_stp_ops = %x\n",(sizeof(ops->gsw_stp_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_stp_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_EAPOL_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_8021x_ops =%x\n",(unsigned int)&ops->gsw_8021x_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_8021x_ops; + ops_content.nType = GSW_EAPOL_MAGIC; + //printk("size of pdata_t.ops.gsw_8021x_ops = %x\n",(sizeof(ops->gsw_8021x_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_8021x_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_MULTICAST_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_multicast_ops =%x\n",(unsigned int)&ops->gsw_multicast_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_multicast_ops; + ops_content.nType = GSW_MULTICAST_MAGIC; + //printk("size of pdata_t.ops.gsw_multicast_ops = %x\n",(sizeof(ops->gsw_multicast_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_multicast_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_TRUNKING_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_trunking_ops =%x\n",(unsigned int)&ops->gsw_trunking_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_trunking_ops; + ops_content.nType = GSW_TRUNKING_MAGIC; + //printk("size of pdata_t.ops.gsw_trunking_ops = %x\n",(sizeof(ops->gsw_trunking_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_trunking_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_WOL_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_wol_ops =%x\n",(unsigned int)&ops->gsw_wol_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_wol_ops; + ops_content.nType = GSW_WOL_MAGIC; + //printk("size of pdata_t.ops.gsw_wol_ops = %x\n",(sizeof(ops->gsw_wol_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_wol_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_VLAN_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_vlan_ops =%x\n",(unsigned int)&ops->gsw_vlan_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_vlan_ops; + ops_content.nType = GSW_VLAN_MAGIC; + //printk("size of pdata_t.ops.gsw_vlan_ops = %x\n",(sizeof(ops->gsw_vlan_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_vlan_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_PMAC_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_pmac_ops =%x\n",(unsigned int)&ops->gsw_pmac_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_pmac_ops; + ops_content.nType = GSW_PMAC_MAGIC; + //printk("size of pdata_t.ops.gsw_pmac_ops = %x\n",(sizeof(ops->gsw_pmac_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_pmac_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_ROUTE_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_pae_ops =%x\n",(unsigned int)&ops->gsw_pae_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_pae_ops; + ops_content.nType = GSW_ROUTE_MAGIC; + //printk("size of pdata_t.ops.gsw_pae_ops = %x\n",(sizeof(ops->gsw_pae_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_pae_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_COMMON_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_common_ops =%x\n",(unsigned int)&ops->gsw_common_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_common_ops; + ops_content.nType = GSW_COMMON_MAGIC; + //printk("size of pdata_t.ops.gsw_common_ops = %x\n",(sizeof(ops->gsw_common_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_common_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_DEBUG_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_debug_ops =%x....\n",(unsigned int)&ops->gsw_debug_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_debug_ops; + ops_content.nType = GSW_DEBUG_MAGIC; + //printk("size of pdata_t.ops.gsw_debug_ops = %x\n",(sizeof(ops->gsw_debug_ops)/sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_debug_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + case GSW_IRQ_MAGIC: + ops_content.pNext = NULL; + //printk("address of gsw_debug_ops =%x....\n",(unsigned int)&ops->gsw_debug_ops); + ops_content.pFkts = (LTQ_ll_fkt *)&ops->gsw_irq_ops; + ops_content.nType = GSW_IRQ_MAGIC; + //printk("size of pdata_t.ops.gsw_irq_ops = %x\n", (sizeof(ops->gsw_irq_ops) / sizeof(ops_content.pFkts[0]))); + ops_content.nNumFkts = (sizeof(ops->gsw_irq_ops) / sizeof(ops_content.pFkts[0])); + insert_ioctl_type(ops_content, node); + break; + + + default: break; } } - first_node=node->first_ptr; - kfree(node); - return first_node; -} -#if 0 -static inline void gsw_r32_raw(void *cdev, short offset, u32 *value) -{ - ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); - - //assert(pethdev->gsw_base==0, "error"); -#if defined(UART_INTERFACE) && UART_INTERFACE - pc_uart_dataread((uintptr_t)pethdev->gsw_base+(offset*4), value); -#else - *value = gsw1_r32((u32)pethdev->gsw_base+(offset*4)); -#endif /* UART_INTERFACE */ -} - -static inline void gsw_w32_raw(void *cdev, short offset, u32 value) -{ - ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); - - //assert(pethdev->gsw_base==0, "error"); -#if defined(UART_INTERFACE) && UART_INTERFACE - pc_uart_datawrite((uintptr_t)pethdev->gsw_base+(offset*4), value); + first_node = node->first_ptr; +#ifdef __KERNEL__ + kfree(node); #else - gsw1_w32(value, (u32)pethdev->gsw_base+(offset*4)); + free(node); #endif + return first_node; } -#endif - +#ifdef __KERNEL__ void gsw_r32_raw(void *cdev, short offset, u32 *value) { ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); - - //assert(pethdev->gsw_base==0, "error"); -#if defined(UART_INTERFACE) && UART_INTERFACE - pc_uart_dataread((uintptr_t)pethdev->gsw_base+(offset*4), value); -#else - *value = gsw1_r32((volatile void *)pethdev->gsw_base+(offset*4)); -#endif /* UART_INTERFACE */ + *value = gsw1_r32((volatile void *)pethdev->gsw_base + (offset * 4)); } void gsw_w32_raw(void *cdev, short offset, u32 value) { ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); - - //assert(pethdev->gsw_base==0, "error"); -#if defined(UART_INTERFACE) && UART_INTERFACE - pc_uart_datawrite((uintptr_t)pethdev->gsw_base+(offset*4), value); -#else - gsw1_w32(value, (volatile void *)(pethdev->gsw_base+(offset*4))); -#endif + gsw1_w32(value, (volatile void *)(pethdev->gsw_base + (offset * 4))); } - +#endif #ifdef CONFIG_X86_INTEL_CE2700 + int GSW_SMDIO_DataRead(void *cdev, GSW_MDIO_data_t *pPar) { u32 data; int ret; - ret = DWC_ETH_QOS_mdio_read_direct(MDIO_BUS_NUMBER_0, C45_ENABLED, - MDIO_ADDR_LANTIQ, MMD_DISABLED, pPar->nAddressReg & 0x1F, &data); + ret = DWC_ETH_QOS_mdio_read_direct(MDIO_BUS_NUMBER_0, C45_ENABLED, + MDIO_ADDR_LANTIQ, MMD_DISABLED, pPar->nAddressReg & 0x1F, &data); pPar->nData = data & 0xFFFF; return ret; } int GSW_SMDIO_DataWrite(void *cdev, GSW_MDIO_data_t *pPar) { - return DWC_ETH_QOS_mdio_write_direct(MDIO_BUS_NUMBER_0, C45_ENABLED, - MDIO_ADDR_LANTIQ, MMD_DISABLED, pPar->nAddressReg & 0x1F, pPar->nData & 0xFFFF); + return DWC_ETH_QOS_mdio_write_direct(MDIO_BUS_NUMBER_0, C45_ENABLED, + MDIO_ADDR_LANTIQ, MMD_DISABLED, pPar->nAddressReg & 0x1F, pPar->nData & 0xFFFF); } /** read the gswitch register */ @@ -408,10 +439,12 @@ void gsw_r32(void *cdev, short offset, short shift, short size, u32 *value) GSW_MDIO_data_t mdio_data; mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x1F; + if ((offset & 0xD000) == 0xD000) mdio_data.nData = (offset); else mdio_data.nData = (offset | 0xE000); + GSW_SMDIO_DataWrite(cdev, &mdio_data); mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x00; @@ -433,11 +466,14 @@ void gsw_w32(void *cdev, short offset, short shift, short size, u32 value) GSW_MDIO_data_t mdio_data; mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x1F; + if ((offset & 0xD000) == 0xD000) mdio_data.nData = (offset); else mdio_data.nData = (offset | 0xE000); + GSW_SMDIO_DataWrite(cdev, &mdio_data); + if (size != 16) { mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x00; @@ -449,32 +485,61 @@ void gsw_w32(void *cdev, short offset, short shift, short size, u32 value) mask = (1 << size) - 1 ; mask = (mask << shift); /* Shift the value to the right place and mask the rest of the bit*/ - value = ( value << shift ) & mask; + value = (value << shift) & mask; /* Mask out the bit field from the read register and place in the new value */ - value = ( rvalue & ~mask ) | value ; + value = (rvalue & ~mask) | value ; mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x1F; + if ((offset & 0xD000) == 0xD000) mdio_data.nData = (offset); else mdio_data.nData = (offset | 0xE000); + GSW_SMDIO_DataWrite(cdev, &mdio_data); } + mdio_data.nAddressDev = 0x1F; mdio_data.nAddressReg = 0x0; mdio_data.nData = value; GSW_SMDIO_DataWrite(cdev, &mdio_data); } -#else - + +#else /* If not CONFIG_X86_INTEL_CE2700*/ + +#if defined(UART_INTERFACE) && UART_INTERFACE +/* UART inetrface suppot function */ +static int uart_reg_rd(u32 regaddr, u32 *data) +{ + /* Add customer UART routines*/ + /* pseudo function */ + pc_uart_dataread(regaddr, data); + return 1; +} +static int uart_reg_wr(u32 regaddr, u32 data) +{ + /* Add customer UART routines*/ + /* pseudo function */ + pc_uart_datawrite(regaddr, data); + return 1; +} +#endif /* UART_INTERFACE */ + /** read the gswitch register */ void gsw_r32(void *cdev, short offset, short shift, short size, u32 *value) { u32 rvalue, mask; ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); + if (pethdev->gsw_base != 0) { +#if defined(UART_INTERFACE) && UART_INTERFACE + u32 ro; + ro = (uintptr_t)(pethdev->gsw_base + (offset * 4)); + uart_reg_rd(ro, &rvalue); +#else rvalue = gsw1_r32((volatile void *)(pethdev->gsw_base + (offset * 4))); +#endif /* UART_INTERFACE */ mask = (1 << size) - 1; rvalue = (rvalue >> shift); *value = (rvalue & mask); @@ -488,17 +553,30 @@ void gsw_w32(void *cdev, short offset, short shift, short size, u32 value) { u32 rvalue, mask; ethsw_api_dev_t *pethdev = GSW_PDATA_GET(cdev); + if (pethdev->gsw_base != 0) { + +#if defined(UART_INTERFACE) && UART_INTERFACE + u32 ro; + ro = (uintptr_t)(pethdev->gsw_base + (offset * 4)); + uart_reg_rd(ro, &rvalue); +#else rvalue = gsw1_r32((volatile void *)(pethdev->gsw_base + (offset * 4))); +#endif /* UART_INTERFACE */ mask = (1 << size) - 1; mask = (mask << shift); value = ((value << shift) & mask); value = ((rvalue & ~mask) | value); +#if defined(UART_INTERFACE) && UART_INTERFACE + uart_reg_wr(ro, value); +#else gsw1_w32(value, ((volatile void *)pethdev->gsw_base + (offset * 4))); +#endif /* UART_INTERFACE */ } else { pr_err("%s:%s:%d,(ERROR)\n", __FILE__, __func__, __LINE__); } } + #endif #ifdef CONFIG_X86_INTEL_CE2700 @@ -520,20 +598,21 @@ void *gsw_p7_netss_map(netss_dev_t netss_subdevice) if (!netss_driver_ready()) { pr_err("%s:%s:%d (Netss Driver Not Ready)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return NULL; } if (netss_device_get_info(netss_subdevice, &pbase)) { pr_err("%s:%s:%d (Netss Get Info Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return NULL; } vbase = ioremap_nocache(pbase.base, pbase.size); + if (!vbase) { pr_err("%s:%s:%d (Virt_base Is Null)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return NULL; } @@ -558,27 +637,28 @@ int gsw_p7_power_on(void) void *netss_gpio_base = NULL; netss_gpio_base = gsw_p7_netss_map(NETSS_DEV_GPIO); + if (!netss_gpio_base) { pr_err("%s:%s:%d (Gpio Base Map Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } /* set power gpio to output and value 1*/ gsw_p7_netss_write(netss_gpio_base, OE_SET_REG_OFFSET, NETSS_GPIO_17); gsw_p7_netss_write(netss_gpio_base, DATA_OUT_SET_REG_OFFSET, - NETSS_GPIO_17); + NETSS_GPIO_17); mdelay(200); /* set reset gpio to output*/ gsw_p7_netss_write(netss_gpio_base, OE_SET_REG_OFFSET, NETSS_GPIO_19); /* set reset gpio value to 0*/ gsw_p7_netss_write(netss_gpio_base, DATA_OUT_CLEAR_REG_OFFSET, - NETSS_GPIO_19); + NETSS_GPIO_19); mdelay(200); /* set reset gpio value to 1*/ gsw_p7_netss_write(netss_gpio_base, DATA_OUT_SET_REG_OFFSET, - NETSS_GPIO_19); + NETSS_GPIO_19); mdelay(1000); gsw_p7_netss_unmap(netss_gpio_base); @@ -600,28 +680,31 @@ int ltq_ethsw_api_register_p7(struct platform_device *pdev) /* Enable Switch Power */ if (gsw_p7_power_on()) { pr_err("%s:%s:%d (Switch Power On Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } /* Init FLOW Switch Core Layer */ core_init.sdev = LTQ_FLOW_DEV_INT; core_init.gsw_base_addr = addr_gsw; -/* core_init.pDev = pRALDev; */ + /* core_init.pDev = pRALDev; */ pethdev = ethsw_api_core_init(&core_init); + if (pethdev == NULL) { pr_err("%s:%s:%d (Init Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + pethdev->cport = GSW_2X_SOC_CPU_PORT; pethdev->gsw_base = addr_gsw; iowrapinit.pLlTable = <q_flow_fkt_tbl; iowrapinit.default_handler = NULL; iowrap = ioctl_wrapper_init(&iowrapinit); + if (iowrap == NULL) { pr_err("%s:%s:%d (WrapperInit Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } @@ -630,23 +713,104 @@ int ltq_ethsw_api_register_p7(struct platform_device *pdev) if (gsw_p7_reset_modphy_lane()) { pr_err("%s:%s:%d (Reset Modphy Lane Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } /* Register Char Device */ result = gsw_api_drv_register(GSW_API_MAJOR_NUMBER); + if (result != 0) { pr_err("%s:%s:%d (Register Char Device Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return result; } return 0; } + #endif /*CONFIG_X86_INTEL_CE2700*/ -#ifdef CONFIG_SOC_GRX500 + +#if defined(WIN_PC_MODE) && WIN_PC_MODE + +int ethsw_swapi_register(void) +{ + int ret; + ethsw_core_init_t core_init; + + /* Find and map our resources */ + /* Switch device index */ + addr_gswl = (void *)0x50000; + + /* Init FLOW Switch Core Layer */ + memset(&core_init, 0, sizeof(ethsw_core_init_t)); + core_init.sdev = LTQ_FLOW_DEV_INT; + core_init.gsw_base_addr = addr_gswl; + pEDev0 = ethsw_api_core_init(&core_init); + + if (pEDev0 == NULL) { + printf("%s:%s:%d (Init Failed)\n", + __FILE__, __func__, __LINE__); + return -1; + } + + pEDev0->cport = GSW_3X_SOC_CPU_PORT; + pEDev0->gsw_dev = LTQ_FLOW_DEV_INT; + pEDev0->gswl_base = addr_gswl; + pEDev0->gsw_base = addr_gswl; + +#if defined(GSW_IOCTL_SUPPORT) && GSW_IOCTL_SUPPORT + ioct_cmd_start_node = gsw_create_ioctl_cmd_linklist(&pEDev0->ops); + ioctlinit.pLlTable = ioct_cmd_start_node; + ioctlinit.default_handler = NULL; + pioctlctl = ioctl_wrapper_init(&ioctlinit); + + if (pioctlctl == NULL) { + printf("%s:%s:%d (WrapperInit Failed)\n", + __FILE__, __func__, __LINE__); + return -1; + } + + /* add Internal switch */ + if (pioctlctl && pEDev0) + ioctl_wrapper_dev_add(pioctlctl, pEDev0, LTQ_INT_GSWITCH); + +#endif /* GSW_IOCTL_SUPPORT */ + return 0; +} + +int ethsw_swapi_unregister(void) +{ + //ethsw_api_core_exit(pEDev0); +#if defined(GSW_IOCTL_SUPPORT) && GSW_IOCTL_SUPPORT + gsw_api_ioctl_wrapper_cleanup(); +#endif /* GSW_IOCTL_SUPPORT */ + return 0; +} + +/* +static int __init gsw_swapi_init(void *) +*/ +int gsw_swapi_init() +{ + ethsw_swapi_register(); + return 0; +} + +/* +static void __exit ltq_etshw_api_exit(void) +*/ +static void gsw_swapi_exit(void) +{ + ethsw_swapi_unregister(); +} + +#endif /*WIN_PC_MODE*/ + +#ifdef __KERNEL__ + +#if defined(CONFIG_SOC_GRX500) && CONFIG_SOC_GRX500 int ltq_gsw_api_register(struct platform_device *pdev) { int result; @@ -655,116 +819,129 @@ int ltq_gsw_api_register(struct platform_device *pdev) struct clk *clk; struct gswss *gswdev = dev_get_drvdata(pdev->dev.parent); u32 device_id = pdev->dev.parent->id; - + /*Initialize global array*/ gswdev->core_dev = pdev; - + memset(&core_init, 0, sizeof(ethsw_core_init_t)); - printk("GSWIP devid = %d\n",device_id); + printk("GSWIP devid = %d\n", device_id); + if (device_id < 0 || device_id >= 2) return -EINVAL; /* Find and map our resources */ memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - printk("memres->start = 0x%08x memres->end = 0x%08x\n",memres->start,memres->end); + printk("memres->start = 0x%08x memres->end = 0x%08x\n", memres->start, memres->end); + if (memres == NULL) { pr_err("%s:%s:%d (Failed)\n", __FILE__, __func__, __LINE__); -/* dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");*/ + /* dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");*/ return -ENOENT; } /*Enable Switch Power */ clk = devm_clk_get(&pdev->dev, "gate"); + if (IS_ERR(clk)) panic("Failed to get switch clock"); + clk_prepare_enable(clk); if (device_id == 0) { addr_gswl = devm_ioremap_resource(&pdev->dev, memres); - printk("addr_gswl = 0x%08x\n",(unsigned int)addr_gswl); + printk("addr_gswl = 0x%08x\n", (unsigned int)addr_gswl); + if (IS_ERR(addr_gswl)) return PTR_ERR(addr_gswl); + pr_err("%s:%s:%d (Register l base:0x%08x)\n", - __FILE__, __func__, __LINE__, (u32)addr_gswl); + __FILE__, __func__, __LINE__, (u32)addr_gswl); } if (device_id == 1) { addr_gswr = devm_ioremap_resource(&pdev->dev, memres); - printk("addr_gswr = 0x%08x\n",(unsigned int)addr_gswr); + printk("addr_gswr = 0x%08x\n", (unsigned int)addr_gswr); if (IS_ERR(addr_gswr)) return PTR_ERR(addr_gswr); + pr_err("%s:%s:%d (Register r base:0x%08x)\n", - __FILE__, __func__, __LINE__, (u32)addr_gswr); + __FILE__, __func__, __LINE__, (u32)addr_gswr); } /* Register Char Device */ if (device_id == 0) { result = gsw_api_drv_register(GSW_API_MAJOR_NUMBER); + if (result != 0) { pr_err("%s:%s:%d (Reg Char Device Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return result; } } - /*Enable Switch Power */ -#if 0 - clk = clk_get_sys("1c000000.eth", NULL); /*GSWIP-L*/ - clk_enable(clk); - clk = clk_get_sys("1a000000.eth", NULL); /*GSWIP-R*/ - clk_enable(clk); -#endif + + if (device_id == 0) { /* Init FLOW Switch Core Layer */ core_init.sdev = LTQ_FLOW_DEV_INT; core_init.gsw_base_addr = addr_gswl; core_init.pdev = (void *)pdev; - printk("addr_gswl = 0x%08x\n",(unsigned int)addr_gswl); + printk("addr_gswl = 0x%08x\n", (unsigned int)addr_gswl); pEDev0 = ethsw_api_core_init(&core_init); + if (pEDev0 == NULL) { pr_err("%s:%s:%d (Init Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + pEDev0->cport = GSW_3X_SOC_CPU_PORT; pEDev0->gsw_dev = LTQ_FLOW_DEV_INT; pEDev0->gswl_base = addr_gswl; pEDev0->gsw_base = addr_gswl; } + if (device_id == 1) { /* Init FLOW Switch Core Layer */ core_init.sdev = LTQ_FLOW_DEV_INT_R; core_init.gsw_base_addr = addr_gswr; core_init.pdev = (void *)pdev; pEDev1 = ethsw_api_core_init(&core_init); + if (pEDev1 == NULL) { pr_err("%s:%s:%d (Init Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + pEDev1->cport = GSW_3X_SOC_CPU_PORT; pEDev1->gsw_dev = LTQ_FLOW_DEV_INT_R; pEDev1->gswr_base = addr_gswr; pEDev1->gsw_base = addr_gswr; } + if (device_id == 0) { - ioct_cmd_start_node = gsw_create_ioctl_cmd_linklist (&pEDev0->ops); + ioct_cmd_start_node = gsw_create_ioctl_cmd_linklist(&pEDev0->ops); ioctlinit.pLlTable = ioct_cmd_start_node; ioctlinit.default_handler = NULL; pioctlctl = ioctl_wrapper_init(&ioctlinit); + if (pioctlctl == NULL) { pr_err("%s:%s:%d (WrapperInit Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } } + /* add Internal switch */ if ((device_id == 0) && pioctlctl && pEDev0) ioctl_wrapper_dev_add(pioctlctl, &pEDev0->ops, LTQ_INT_GSWITCH); + /* add Internal switch */ if ((device_id == 1) && pioctlctl && pEDev1) - ioctl_wrapper_dev_add(pioctlctl,&pEDev1->ops, LTQ_EXT_GSWITCH); + ioctl_wrapper_dev_add(pioctlctl, &pEDev1->ops, LTQ_EXT_GSWITCH); + return 0; } #endif /* CONFIG_SOC_GRX500 */ @@ -781,21 +958,25 @@ int ltq_ethsw_api_register(struct platform_device *pdev) /* Find and map our resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { pr_err("%s:%s:%d (Get IORESOURCE_MEM Failed)\n", - __FILE__, __func__, __LINE__); -/* dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");*/ + __FILE__, __func__, __LINE__); + /* dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");*/ return -ENOENT; } + addr_gsw = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(addr_gsw)) return PTR_ERR(addr_gsw); /* Register Char Device */ result = gsw_api_drv_register(GSW_API_MAJOR_NUMBER); + if (result != 0) { pr_err("%s:%s:%d (Register Char Device Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return result; } @@ -806,23 +987,27 @@ int ltq_ethsw_api_register(struct platform_device *pdev) /* Init FLOW Switch Core Layer */ core_init.sdev = LTQ_FLOW_DEV_INT; core_init.gsw_base_addr = addr_gsw; -/* core_init.pDev = pRALDev; */ + /* core_init.pDev = pRALDev; */ pethdev = ethsw_api_core_init(&core_init); + if (pethdev == NULL) { pr_err("%s:%s:%d (Init Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + pethdev->cport = GSW_2X_SOC_CPU_PORT; pethdev->gsw_base = addr_gsw; iowrapinit.pLlTable = <q_flow_fkt_tbl; iowrapinit.default_handler = NULL; iowrap = ioctl_wrapper_init(&iowrapinit); + if (iowrap == NULL) { pr_err("%s:%s:%d (WrapperInit Failed)\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + /* add Internal switch */ ioctl_wrapper_dev_add(iowrap, pethdev, LTQ_INT_GSWITCH); return 0; @@ -839,24 +1024,23 @@ int ltq_ethsw_api_unregister(void) } /*ltq_ethsw_api_init the init function, called when the module is loaded.*/ - /* Returns zero if successfully loaded, nonzero otherwise.*/ +/* Returns zero if successfully loaded, nonzero otherwise.*/ static int __init ltq_ethsw_api_init(struct platform_device *pdev) { /* Print Version Number */ - pr_info("LTQ ETH SWITCH API, Version %s.\n", GSW_API_DRV_VERSION); #ifdef CONFIG_SOC_GRX500 -/* if (of_machine_is_compatible("lantiq,grx500")) { */ - ltq_gsw_api_register(pdev); + /* if (of_machine_is_compatible("lantiq,grx500")) { */ + ltq_gsw_api_register(pdev); #endif -/* } else { */ + /* } else { */ #ifdef CONFIG_SOC_XWAY - ltq_ethsw_api_register(pdev); + ltq_ethsw_api_register(pdev); #endif #ifdef CONFIG_X86_INTEL_CE2700 - ltq_ethsw_api_register_p7(pdev); + ltq_ethsw_api_register_p7(pdev); #endif -/* } */ + /* } */ return 0; } @@ -868,7 +1052,7 @@ static void __exit ltq_etshw_api_exit(void) static int ltq_switch_api_probe(struct platform_device *pdev) { - printk("::::::: SWAPI Reached :::::: \n"); + printk("::::::: SWAPI Reached :::::: \n"); ltq_ethsw_api_init(pdev); return 0; } @@ -878,20 +1062,23 @@ static int ltq_switch_api_remove(struct platform_device *pdev) ltq_etshw_api_exit(); return 0; } -#ifdef CONFIG_SOC_GRX500 + +#if defined(CONFIG_SOC_GRX500) && CONFIG_SOC_GRX500 + static void __iomem *gswl_addr; static void __iomem *gswr_addr; /** read and update the GSWIP register */ static void ltq_gsw_w32(short offset, short shift, short size, u32 value) { u32 rvalue, mask; + if (gswl_addr != 0) { rvalue = gsw1_r32(gswl_addr + (offset * 4)); mask = (1 << size) - 1; mask = (mask << shift); value = ((value << shift) & mask); value = ((rvalue & ~mask) | value); -/* pr_info("writing %x to the address = %x \n", value, (u32) (gswl_addr + (offset * 4)));*/ + /* pr_info("writing %x to the address = %x \n", value, (u32) (gswl_addr + (offset * 4)));*/ gsw1_w32(value, (gswl_addr + (offset * 4))); } else { pr_err("%s:%s:%d,(ERROR)\n", __FILE__, __func__, __LINE__); @@ -901,13 +1088,14 @@ static void ltq_gsw_w32(short offset, short shift, short size, u32 value) static void ltq_gsw_r_w32(short offset, short shift, short size, u32 value) { u32 rvalue, mask; + if (gswr_addr != 0) { rvalue = gsw1_r32(gswr_addr + (offset * 4)); mask = (1 << size) - 1; mask = (mask << shift); value = ((value << shift) & mask); value = ((rvalue & ~mask) | value); -/* pr_info("writing %x to the address = %x \n", value, (u32) (gswr_addr + (offset * 4)));*/ + /* pr_info("writing %x to the address = %x \n", value, (u32) (gswr_addr + (offset * 4)));*/ gsw1_w32(value, (gswr_addr + (offset * 4))); } else { pr_err("%s:%s:%d,(ERROR)\n", __FILE__, __func__, __LINE__); @@ -916,47 +1104,54 @@ static void ltq_gsw_r_w32(short offset, short shift, short size, u32 value) void gsw_api_disable_switch_ports(void) { int pidx; - gswl_addr = (void __iomem *) (KSEG1 | 0x1c000000); - gswr_addr = (void __iomem *) (KSEG1 | 0x1a000000); + gswl_addr = (void __iomem *)(KSEG1 | 0x1c000000); + gswr_addr = (void __iomem *)(KSEG1 | 0x1a000000); - for(pidx = 2; pidx < 6; pidx++) { + for (pidx = 2; pidx < 6; pidx++) { /* Set SDMA_PCTRL_PEN PORT disable */ ltq_gsw_w32((SDMA_PCTRL_PEN_OFFSET + (6 * pidx)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); + SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); /* Set FDMA_PCTRL_EN PORT disable */ ltq_gsw_w32((FDMA_PCTRL_EN_OFFSET + (0x6 * pidx)), - FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 0); + FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 0); } - for(pidx = 0; pidx < 16; pidx++) { + + for (pidx = 0; pidx < 16; pidx++) { /* Set SDMA_PCTRL_PEN PORT disable */ ltq_gsw_r_w32((SDMA_PCTRL_PEN_OFFSET + (6 * pidx)), - SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); + SDMA_PCTRL_PEN_SHIFT, SDMA_PCTRL_PEN_SIZE, 0); /* Set FDMA_PCTRL_EN PORT disable */ ltq_gsw_r_w32((FDMA_PCTRL_EN_OFFSET + (0x6 * pidx)), - FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 0); + FDMA_PCTRL_EN_SHIFT, FDMA_PCTRL_EN_SIZE, 0); } } EXPORT_SYMBOL(gsw_api_disable_switch_ports); -#endif -#ifdef CONFIG_SOC_GRX500 static const struct of_device_id ltq_switch_api_match[] = { { .compatible = "intel,falconmx-gswapi" }, {}, }; + #endif /* CONFIG_SOC_GRX500 */ + #ifdef CONFIG_SOC_XWAY + static const struct of_device_id ltq_switch_api_match[] = { { .compatible = "lantiq,xway-gsw2x" }, {}, }; + #endif /* CONFIG_SOC_XWAY */ + #ifdef CONFIG_X86_INTEL_CE2700 + static const struct of_device_id ltq_switch_api_match[] = { { .compatible = "lantiq,xway-gsw2x" }, {}, }; + #endif /* CONFIG_X86_INTEL_CE2700 */ + MODULE_DEVICE_TABLE(of, ltq_switch_api_match); static struct platform_driver ltq_switch_api = { @@ -971,6 +1166,7 @@ static struct platform_driver ltq_switch_api = { #ifdef CONFIG_X86_INTEL_CE2700 + static struct platform_device *ltq_switch_api_dev; static int __init ltq_ethsw_api_init_p7(void) @@ -978,9 +1174,10 @@ static int __init ltq_ethsw_api_init_p7(void) int ret; ret = platform_driver_register(<q_switch_api); + if (ret < 0) { pr_err("%s:%s:%d switch_api driver register failed\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return ret; } @@ -989,10 +1186,11 @@ static int __init ltq_ethsw_api_init_p7(void) if (IS_ERR(ltq_switch_api_dev)) { pr_err("%s:%s:%d switch_api device register failed\n", - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); platform_driver_unregister(<q_switch_api); return PTR_ERR(ltq_switch_api_dev); } + return 0; } @@ -1004,11 +1202,17 @@ static void __exit ltq_ethsw_api_exit_p7(void) module_init(ltq_ethsw_api_init_p7); module_exit(ltq_ethsw_api_exit_p7); + #else + module_platform_driver(ltq_switch_api); + #endif /*CONFIG_X86_INTEL_CE2700*/ MODULE_AUTHOR("LANTIQ"); MODULE_DESCRIPTION("LTQ ETHSW API"); MODULE_LICENSE("GPL"); MODULE_VERSION(GSW_API_DRV_VERSION); + +#endif + diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_init.h b/drivers/net/ethernet/lantiq/switch-api/gsw_init.h index ae75460cbe49f9e4b008f3b1b7c68c62e719f022..6da59b63c1783bfb745904d9b560dd01b4a2a495 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_init.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_init.h @@ -12,16 +12,6 @@ #ifndef _ETHSW_INIT_H_ #define _ETHSW_INIT_H_ -//#include <linux/module.h> -#include <linux/fs.h> -#include <linux/version.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/interrupt.h> -/*#include <asm/delay.h> */ -#include <linux/delay.h> -#include <linux/slab.h> - #define SWAPI_DRV_VERSION "3.0.1" /* Switch Features */ @@ -34,62 +24,146 @@ #define CONFIG_LTQ_PMAC 1 #define CONFIG_LTQ_RMON 1 + +#define CONFIG_MAC 1 + /* User configuration options */ -#define KERNEL_MODE 1 -#define WIN_PC_MODE 0 -#define UART_INTERFACE 0 + #define SMDIO_INTERFACE 0 #define GSW_IOCTL_SUPPORT 1 -#define CONFIG_SOC_GRX500 1 -//#define KSEG1 0 +#if defined(WIN_PC_MODE) && WIN_PC_MODE +#define CONFIG_SOC_GRX500 0 +#define KSEG1 0 +#endif -#define CONFIG_MAC 0 -#define CONFIG_MACSEC 0 #define ENABLE_MICROCODE 0 #define PTR_TO_INT_CAST void * +#ifdef __KERNEL__ +#else +#define printk printf +#define pr_err printf +#define pr_info printf +#endif -#define GSWIP_GET_BITS(x, msb, lsb) \ - (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) -#define GSWIP_SET_BITS(x, msb, lsb, value) \ - (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) \ - | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb))) -#define LTQ_GSW_DEV_MAX 2 -#define GSW_API_MODULE_NAME "GSW SWITCH API" -#define GSW_API_DRV_VERSION "3.0.2" -#define MICRO_CODE_VERSION "212" + +#ifdef __KERNEL__ +//#include <linux/module.h> +#include <linux/fs.h> +#include <linux/version.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/interrupt.h> +//#include <asm/delay.h> */ +#include <linux/delay.h> +#include <linux/slab.h> #ifndef CONFIG_X86_INTEL_CE2700 #include <net/switch_api/lantiq_gsw_api.h> #else -#include <net/switch-api/lantiq_gsw_api.h> +#include <net/switch_api/lantiq_gsw_api.h> #endif /* CONFIG_X86_INTEL_CE2700 */ #include <net/switch_api/gsw_dev.h> #include <linux/netdevice.h> #include <net/lantiq_cbm_api.h> +#include <net/switch_api/gsw_tbl_rw.h> + /*#include <xway/switch-api/lantiq_gsw_routing.h>*/ /*#include <xway/switch-api/gsw_types.h>*/ -#include "gsw_ioctl_wrapper.h" -#include "gsw_flow_core.h" -#include "gsw_ll_func.h" -#include "gsw_reg.h" -#include "gsw_reg_top.h" -#include "gsw30_reg_top.h" - -#ifdef CONFIG_SOC_GRX500 -#include "gsw_pae.h" -#endif -#if defined(CONFIG_MAC) && CONFIG_MAC -#include <xgmac_common.h> +#define LTQ_GSW_DEV_MAX 2 +#endif /* KERNEL_MODE */ + +#if defined(WIN_PC_MODE) && WIN_PC_MODE +#include <stdio.h> +#include <stdlib.h> +#include <memory.h> +#include <string.h> +#include <malloc.h> +#include <conio.h> +#include <signal.h> +#include <tchar.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <stdint.h> +//#include <sys/ioctl.h> #endif -#if defined(CONFIG_MACSEC) && CONFIG_MACSEC -#include <macsec/macsec.h> +/* IOCTL handling incase the OS is not supporetd */ +#if defined(WIN_PC_MODE) && WIN_PC_MODE +#define LTQ_GSW_DEV_MAX 1 +#define NRBITS 8 +#define TYPEBITS 8 +#define SIZEBITS 13 +#define DIRBITS 3 +#define NRMASK ((1 << NRBITS)-1) +#define TYPEMASK ((1 << TYPEBITS)-1) +#define SIZEMASK ((1 << SIZEBITS)-1) +#define XSIZEMASK ((1 << (SIZEBITS+1))-1) +#define DIRMASK ((1 << DIRBITS)-1) +#define NRSHIFT 0 +#define TYPESHIFT (NRSHIFT + NRBITS) +#define SIZESHIFT (TYPESHIFT + TYPEBITS) +#define DIRSHIFT (SIZESHIFT + SIZEBITS) +#define NN 1U +#define RD 2U +#define WR 4U +#define IOC(dir, type, nr, size) \ + (((dir) << DIRSHIFT) | \ + ((type) << TYPESHIFT) | \ + ((nr) << NRSHIFT) | \ + ((size) << SIZESHIFT)) +#define IO(type, nr) IOC(NN, (type), (nr), 0) +#define IOR(type, nr, size) IOC(RD, (type), (nr), sizeof(size)) +#define IOW(type, nr, size) IOC(WR, (type), (nr), sizeof(size)) +#define IOWR(type, nr, size) IOC(RD | WR, (type), (nr), sizeof(size)) +#define IO_TYPE(nr) (((nr) >> TYPESHIFT) & TYPEMASK) +#define NR(nr) (((nr) >> NRSHIFT) & NRMASK) +#define SIZE(nr) \ + ((((((nr) >> DIRSHIFT) & DIRMASK) & (WR|RD)) == 0) ? \ + 0 : (((nr) >> SIZESHIFT) & XSIZEMASK)) +#define _IO IO +#define _IOW IOWR +#define _IOR IOR +#define _IOWR IOWR +#define _IOC_TYPE IO_TYPE +#define _IOC_NR NR +#define _IOC_SIZE SIZE +/* GSW Specific Include files */ +#include <lantiq_gsw_api.h> +#include <gsw_tbl_rw.h> + +#endif /* WIN_PC_MODE */ + + +/*include*/ +#include <gsw_ioctl_wrapper.h> +#include <gsw_flow_core.h> +#include <gsw_ll_func.h> +#include <gsw_reg.h> +#include <gsw_reg_top.h> +#include <gsw30_reg_top.h> + + + +#if defined(CONFIG_SOC_GRX500) && CONFIG_SOC_GRX500 +#include <gsw_pae.h> #endif +#define GSWIP_GET_BITS(x, msb, lsb) \ + (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) +#define GSWIP_SET_BITS(x, msb, lsb, value) \ + (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) \ + | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb))) + +#define GSW_API_MODULE_NAME "GSW SWITCH API" +#define GSW_API_DRV_VERSION "3.0.2" +#define MICRO_CODE_VERSION "212" + typedef struct { void *ecdev; @@ -104,12 +178,11 @@ void *ethsw_api_core_init(ethsw_core_init_t *pinit); void gsw_corecleanup(void); int gsw_pmicro_code_init(void *cdev); int gsw_swapi_init(void); -void gsw_sp_r32(void *cdev, unsigned int offset, short shift, short size, u32 *value); -void gsw_sp_w32(void *cdev, unsigned int offset, short shift, short size, u32 value); -//static inline u32 gsw_field_r32(u32 rval, short shift, short size); -//static inline u32 gsw_field_w32(u32 rval, short shift, short size, u32 val); -//static inline void gsw_r32_raw(void *cdev, short offset, u32 *value); -//static inline void gsw_w32_raw(void *cdev, short offset, u32 value); + +#if defined(WIN_PC_MODE) && WIN_PC_MODE +struct core_ops *gsw_get_swcore_ops(u32 devid); +#endif + #if defined(UART_INTERFACE) && UART_INTERFACE int pc_uart_dataread(u32 Offset, u32 *value); @@ -118,46 +191,76 @@ int pc_uart_dataread_32(u32 Offset, u32 *value); int pc_uart_datawrite_32(u32 Offset, u32 value); #endif /* UART_INTERFACE */ +#ifdef __KERNEL__ void gsw_r32_raw(void *cdev, short offset, u32 *value); void gsw_w32_raw(void *cdev, short offset, u32 value); +#endif static inline u32 gsw_field_r32(u32 rval, short shift, short size) { - return (rval>>shift)&((1<<size)-1); + return (rval >> shift) & ((1 << size) - 1); } static inline u32 gsw_field_w32(u32 rval, short shift, short size, u32 val) { u32 mask; - mask = ((1<<size)-1)<<shift; - val = (val<<shift)&mask; - return (rval&~mask)|val; + mask = ((1 << size) - 1) << shift; + val = (val << shift)&mask; + return (rval & ~mask) | val; } -static inline ethsw_api_dev_t * GSW_PDATA_GET(void *pdev) +#if defined(WIN_PC_MODE) && WIN_PC_MODE +static inline void gsw_r32_raw(void *cdev, short offset, u32 *value) +{ + ethsw_api_dev_t *pethdev = (ethsw_api_dev_t *)cdev; +#if defined(UART_INTERFACE) && UART_INTERFACE + pc_uart_dataread((uintptr_t)pethdev->gsw_base + (offset * 4), value); +#endif /* UART_INTERFACE */ +} + +static inline void gsw_w32_raw(void *cdev, short offset, u32 value) +{ + ethsw_api_dev_t *pethdev = (ethsw_api_dev_t *)cdev; +#if defined(UART_INTERFACE) && UART_INTERFACE + pc_uart_datawrite((uintptr_t)pethdev->gsw_base + (offset * 4), value); +#endif +} +#endif + +static inline ethsw_api_dev_t *GSW_PDATA_GET(void *pdev) { struct core_ops *gsw_ops; - ethsw_api_dev_t *pdata=NULL; - + ethsw_api_dev_t *pdata = NULL; + if (pdev == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return pdata; } - -#if defined(KERNEL_MODE) && KERNEL_MODE - gsw_ops = (struct core_ops *)pdev; + +#ifdef __KERNEL__ + gsw_ops = (struct core_ops *)pdev; + if (gsw_ops == NULL) { - pr_err("%s:%s:%d",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); return pdata; } - pdata= container_of(gsw_ops,ethsw_api_dev_t,ops); + + pdata = container_of(gsw_ops, ethsw_api_dev_t, ops); #else - pdata = (ethsw_api_dev_t *)pdev; + pdata = (ethsw_api_dev_t *)pdev; #endif - return pdata; + return pdata; } +typedef enum { + IRQ_REGISTER = 0, + IRQ_UNREGISTER = 1, + IRQ_ENABLE = 2, + IRQ_DISABLE = 3, +} IRQ_TYPE; + + #endif /* _ETHSW_INIT_H_ */ diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.c b/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.c index 1788657726e88499b1b78bd5c6a4df1ba3c2ab3d..e81ac057fa2c7e58959844f8712ba3ab7169dd3e 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.c @@ -11,161 +11,220 @@ -#include "gsw_init.h" -#include <linux/uaccess.h> +#include <gsw_init.h> ioctl_wrapper_ctx_t *ioctlwrapctx = NULL; #define ETHSW_API_DEV_NAME "switch_api" +#ifdef __KERNEL__ +#include <linux/uaccess.h> static spinlock_t swapi_sem; - static int gsw_api_open(struct inode *inode, struct file *filp); static int gsw_api_release(struct inode *inode, struct file *filp); static long gsw_api_ioctl(struct file *filp, u32 cmd, unsigned long arg); +#endif int gsw_spi_lock_init(void) { +#ifdef __KERNEL__ spin_lock_init(&swapi_sem); +#endif return 0; } int gsw_api_lock(void) { +#ifdef __KERNEL__ + if (unlikely(in_irq())) { pr_err("Not allowed to call gsw_api_lock in_irq mode\n"); return -1; } + raw_spin_lock_bh(&swapi_sem.rlock); +#endif return 0; } int gsw_api_unlock(void) { +#ifdef __KERNEL__ + if (unlikely(in_irq())) { pr_err("Not allowed to call gsw_api_unlock in_irq mode\n"); return -1; } + raw_spin_unlock_bh(&swapi_sem.rlock); +#endif return 0; } ioctl_cmd_handle_t *gsw_api_alloc_cmd_handle(void) { +#ifdef __KERNEL__ gfp_t flags; +#endif ioctl_cmd_handle_t *cmd_handle; - + if (!ioctlwrapctx) { pr_err("ioctlwrapctx not initilized\n"); return NULL; } - if ( in_atomic() || in_interrupt() ) + +#ifdef __KERNEL__ + + if (in_atomic() || in_interrupt()) flags = GFP_ATOMIC; else flags = GFP_KERNEL; + cmd_handle = kmalloc(sizeof(ioctl_cmd_handle_t), flags); +#else + cmd_handle = malloc(sizeof(ioctl_cmd_handle_t)); +#endif + if (cmd_handle) { cmd_handle->pLlTable = ioctlwrapctx->pIoctlHandle->pLlTable; cmd_handle->default_handler = ioctlwrapctx->pIoctlHandle->default_handler; } + return cmd_handle; } /** searching for Switch API IOCTL command */ int gsw_command_search(void *phandle, u32 command, - u32 arg, ethsw_api_type_t apitype) + u32 arg, ethsw_api_type_t apitype) { int retvalue; ioctl_cmd_handle_t *pdrv = (ioctl_cmd_handle_t *) phandle; const ltq_lowlevel_fkts_t *pLlTable = pdrv->pLlTable; /* attempt to acquire the semaphore ...*/ - -/* This table contains the low-level function for the */ -/* IOCTL commands with the same MAGIC-Type numer. */ + + /* This table contains the low-level function for the */ + /* IOCTL commands with the same MAGIC-Type numer. */ while (pLlTable != NULL) { if (_IOC_TYPE(command) == pLlTable->nType) { LTQ_ll_fkt fkt; u32 size; u32 cmdnr = _IOC_NR(command); - /* Number out of range. No function available */ - /* for this command number. */ - if (cmdnr >= pLlTable->nNumFkts) + + /* Number out of range. No function available */ + /* for this command number. */ + if (cmdnr >= pLlTable->nNumFkts) { + pr_err("pLlTable->nNumFkts =%d,cmdnr=%d\n", pLlTable->nNumFkts, cmdnr); + pr_err("gsw_command_search :Number out of range. No function available\n"); goto fail; + } + fkt = (LTQ_ll_fkt)pLlTable->pFkts[cmdnr]; + /* No low-level function given for this command. */ if (fkt == NULL) { pr_err("ERROR %s[%d]: cmdnr=%d, nNumFkts=%d\n", - __func__, __LINE__, cmdnr, pLlTable->nNumFkts); + __func__, __LINE__, cmdnr, pLlTable->nNumFkts); goto fail; } + /* Copy parameter from userspace. */ size = _IOC_SIZE(command); - /* Local temporary buffer to store the parameter is to small. */ + + /* Local temporary buffer to store the parameter is to small. */ if (size > PARAM_BUFFER_SIZE) { pr_err("ERROR %s[%d]: cmdnr=%d, nNumFkts=%d\n", - __func__, __LINE__, cmdnr, pLlTable->nNumFkts); + __func__, __LINE__, cmdnr, pLlTable->nNumFkts); goto fail; } + if (apitype == ETHSW_API_USERAPP) { +#ifdef __KERNEL__ copy_from_user((void *)(pdrv->paramBuffer), - (const void __user *)arg, (unsigned long)size); - /* Now call the low-level function with the right low-level context */ - /* handle and the local copy of the parameter structure of 'arg'. */ + (const void __user *)arg, (unsigned long)size); + /* Now call the low-level function with the right low-level context */ + /* handle and the local copy of the parameter structure of 'arg'. */ + if (gsw_api_lock()) return -1; + + /*Calling function pointer*/ retvalue = fkt(pdrv->pLlHandle, - (u32)pdrv->paramBuffer); + (u32)pdrv->paramBuffer); + gsw_api_unlock(); - /* Copy parameter to userspace. */ - /* Only copy back to userspace if really required */ + + /* Copy parameter to userspace. */ + /* Only copy back to userspace if really required */ if (_IOC_DIR(command) & _IOC_READ) { copy_to_user((void __user *)arg, - (const void *)(pdrv->paramBuffer), - (unsigned long)size); + (const void *)(pdrv->paramBuffer), + (unsigned long)size); } + +#endif } else { memcpy((void *)(pdrv->paramBuffer), - (const void *) arg, (unsigned long)size); + (const void *) arg, (unsigned long)size); + if (gsw_api_lock()) return -1; + + + /*Calling function pointer*/ retvalue = fkt(pdrv->pLlHandle, - (u32)pdrv->paramBuffer); + (u32)pdrv->paramBuffer); + gsw_api_unlock(); + + memcpy((void *)arg, - (const void *)(pdrv->paramBuffer), - (unsigned long)size); + (const void *)(pdrv->paramBuffer), + (unsigned long)size); + } -/* pr_err(" %s[%d]: cmdnr=%d, nNumFkts=%d, retvalue:%d\n",*/ - /*__func__, __LINE__, cmdnr, pLlTable->nNumFkts, retvalue);*/ + + /* pr_err(" %s[%d]: cmdnr=%d, nNumFkts=%d, retvalue:%d\n",*/ + /*__func__, __LINE__, cmdnr, pLlTable->nNumFkts, retvalue);*/ return retvalue; } - /* If command was not found in the current table index, */ - /* look for the next linked table. Search till it is found */ - /* or we run out of tables.*/ + + /* If command was not found in the current table index, */ + /* look for the next linked table. Search till it is found */ + /* or we run out of tables.*/ pLlTable = pLlTable->pNext; } + if (pdrv->default_handler != NULL) { - if(gsw_api_lock()) + if (gsw_api_lock()) { + printk(" gsw_api_lock ERROR5\n"); return -1; + } + retvalue = pdrv->default_handler(pdrv->pLlHandle, command, arg); -/*pr_err(" %s[%d]: retvalue:%d\n", __func__, __LINE__, retvalue);*/ + /*pr_err(" %s[%d]: retvalue:%d\n", __func__, __LINE__, retvalue);*/ gsw_api_unlock(); return retvalue; } + fail: /* release the given semaphore */ // up(&swapi_sem); - /* No supported command low-level function found.*/ + /* No supported command low-level function found.*/ return -1; } /**The driver callbacks that will be registered with the kernel*/ /*static*/ +#ifdef __KERNEL__ const struct file_operations swapi_fops = { - owner:THIS_MODULE, - unlocked_ioctl : gsw_api_ioctl, - open : gsw_api_open, - release : gsw_api_release +owner: + THIS_MODULE, +unlocked_ioctl : + gsw_api_ioctl, +open : + gsw_api_open, +release : + gsw_api_release }; static long gsw_api_ioctl(struct file *filp, u32 cmd, unsigned long arg) @@ -179,16 +238,19 @@ static long gsw_api_ioctl(struct file *filp, u32 cmd, unsigned long arg) pr_err("ioctlwrapctx not initilized\n"); return -1; } + p = filp->private_data; pdev = ioctlwrapctx; cmd_handle = gsw_api_alloc_cmd_handle(); - if(!cmd_handle) return -1; + + if (!cmd_handle) return -1; + if (!p->minor_number) { if (pdev->bInternalSwitch == 1) cmd_handle->pLlHandle = pdev->pEthSWDev[0]; else { pr_err("%s[%d]: Not support internal switch\n\n", - __func__, __LINE__); + __func__, __LINE__); kfree(cmd_handle); return -1; } @@ -197,13 +259,14 @@ static long gsw_api_ioctl(struct file *filp, u32 cmd, unsigned long arg) cmd_handle->pLlHandle = pdev->pEthSWDev[p->minor_number]; } else { pr_err("(Not support external switch number: %d) %s:%s:%d\n", - p->minor_number, __FILE__, __func__, __LINE__); + p->minor_number, __FILE__, __func__, __LINE__); kfree(cmd_handle); return -1; } } + ret = gsw_command_search(cmd_handle, cmd, - arg, ETHSW_API_USERAPP); + arg, ETHSW_API_USERAPP); kfree(cmd_handle); return ret; } @@ -216,23 +279,26 @@ static int gsw_api_open(struct inode *inode, struct file *filp) minornum = MINOR(inode->i_rdev); majornum = MAJOR(inode->i_rdev); p = kmalloc(sizeof(dev_minor_num_t), GFP_KERNEL); + if (!p) { pr_err("%s[%d]: memory allocation failed !!\n", - __func__, __LINE__); + __func__, __LINE__); return -ENOMEM; } + p->minor_number = minornum; filp->private_data = p; return 0; } static int gsw_api_release(struct inode *inode, - struct file *filp) + struct file *filp) { if (filp->private_data) { kfree(filp->private_data); filp->private_data = NULL; } + return 0; } @@ -240,12 +306,14 @@ int gsw_api_drv_register(u32 major) { int result; result = register_chrdev(major, ETHSW_API_DEV_NAME, &swapi_fops); + if (result < 0) { pr_err("SWAPI: Register Char Dev failed with %d !!!\n", result); return result; } + pr_info("SWAPI: Registered char device [%s] with major no [%d]\n", - ETHSW_API_DEV_NAME, major); + ETHSW_API_DEV_NAME, major); return 0; } @@ -255,61 +323,99 @@ int gsw_api_drv_unregister(u32 major) return 0; } +#endif /*KERNAL Mode*/ + void *ioctl_wrapper_init(ioctl_wrapper_init_t *pinit) { u8 i; ioctl_wrapper_ctx_t *pdev; gsw_spi_lock_init(); +#ifdef __KERNEL__ pdev = (ioctl_wrapper_ctx_t *)kmalloc(sizeof(ioctl_wrapper_ctx_t), GFP_KERNEL); +#else + pdev = (ioctl_wrapper_ctx_t *)malloc(sizeof(ioctl_wrapper_ctx_t)); +#endif + if (!pdev) { pr_err("%s memory allocation failed !!\n", __func__); return pdev; } + pdev->bInternalSwitch = 0; /* internal switch, the value is 0 */ pdev->nExternalSwitchNum = 0; +#ifdef __KERNEL__ pdev->pIoctlHandle = (ioctl_cmd_handle_t *)kmalloc(sizeof(ioctl_cmd_handle_t), GFP_KERNEL); +#else + pdev->pIoctlHandle = (ioctl_cmd_handle_t *)malloc(sizeof(ioctl_cmd_handle_t)); +#endif + if (!pdev->pIoctlHandle) { pr_err("%s memory allocation failed !!\n", __func__); + if (pdev) +#ifdef __KERNEL__ kfree(pdev); + +#else + free(pdev); +#endif return NULL; /*pdev->pIoctlHandle;*/ } + pdev->pIoctlHandle->pLlTable = pinit->pLlTable; pdev->pIoctlHandle->default_handler = pinit->default_handler; + for (i = 0; i < LTQ_GSW_DEV_MAX; i++) pdev->pEthSWDev[i] = NULL; + ioctlwrapctx = pdev; return pdev; } int ioctl_wrapper_dev_add(ioctl_wrapper_ctx_t *pioctldev, - void *pcoredev, u8 mnum) + void *pcoredev, u8 mnum) { if (mnum >= LTQ_GSW_DEV_MAX) { pr_err("(Device number: %d) %s:%s:%d\n", mnum, - __FILE__, __func__, __LINE__); + __FILE__, __func__, __LINE__); return -1; } + pioctldev->pEthSWDev[mnum] = pcoredev; + if (!mnum) pioctldev->bInternalSwitch = 1; else /* other than 0 means external switch */ pioctldev->nExternalSwitchNum++; + return 0; } int gsw_api_ioctl_wrapper_cleanup(void) { ioctl_wrapper_ctx_t *pdev = ioctlwrapctx; + if (pdev != NULL) { ioctlwrapctx = NULL; + if (pdev->pIoctlHandle != NULL) { +#ifdef __KERNEL__ kfree(pdev->pIoctlHandle); +#else + free(pdev->pIoctlHandle); +#endif pdev->pIoctlHandle = NULL; } + +#ifdef __KERNEL__ kfree(pdev); +#else + free(pdev); +#endif + pdev = NULL; } + return 0; } @@ -325,18 +431,25 @@ GSW_API_HANDLE gsw_api_kopen(char *name) pr_err("ioctlwrapctx not initilized\n"); return 0; } + pdev = ioctlwrapctx; - name = buf+strlen(needle); /* pointer to dev */ + name = buf + strlen(needle); /* pointer to dev */ + if (name != NULL) { buf = strstr(name, needle); } - name = buf+strlen(needle); /* pointer to switch */ + + name = buf + strlen(needle); /* pointer to switch */ + if (name != NULL) { buf = strstr(name, needle); } - name = buf+strlen(needle); /* pointer to minor */ + + name = buf + strlen(needle); /* pointer to minor */ + if (name == NULL) return 0; + if (!strcmp(name, "0")) { if (pdev->bInternalSwitch == 1) pLlHandle = pdev->pEthSWDev[0]; @@ -350,9 +463,12 @@ GSW_API_HANDLE gsw_api_kopen(char *name) pr_err("\nNot support external switch number = %s\n\n", name); return 0; } + return (GSW_API_HANDLE)pLlHandle; } +#ifdef __KERNEL__ EXPORT_SYMBOL(gsw_api_kopen); +#endif int gsw_api_kioctl(GSW_API_HANDLE handle, u32 command, u32 arg) { @@ -364,29 +480,53 @@ int gsw_api_kioctl(GSW_API_HANDLE handle, u32 command, u32 arg) pr_err("ioctlwrapctx not initilized\n"); return -1; } + pdev = ioctlwrapctx; cmd_handle = gsw_api_alloc_cmd_handle(); - if(!cmd_handle) return -1; + + if (!cmd_handle) { + printk("ERROR :Wrong cmd_handle ,gsw_api_alloc_cmd_handle return -1\n"); + return -1; + } + if (handle == (GSW_API_HANDLE)pdev->pEthSWDev[0]) { - cmd_handle->pLlHandle = pdev->pEthSWDev[0]; + cmd_handle->pLlHandle = pdev->pEthSWDev[0]; } else if (handle == (GSW_API_HANDLE)pdev->pEthSWDev[1]) { cmd_handle->pLlHandle = pdev->pEthSWDev[1]; } else { - pr_err("ERROR:Provided wrong address ( Address:0x%08x) %s:%s:%d\n", - handle, __FILE__, __func__, __LINE__); + pr_err("ERROR:Provided wrong address ( Address:0x%08x) %s:%s:%d\n", + handle, __FILE__, __func__, __LINE__); +#ifdef __KERNEL__ kfree(cmd_handle); +#else + free(cmd_handle); +#endif return -1; } - ret = gsw_command_search(cmd_handle, command, - arg, ETHSW_API_KERNEL); + + ret = gsw_command_search(cmd_handle, command, arg, ETHSW_API_KERNEL); + + if (ret == -1) { + pr_err("CMD ERROR :Command return %d\n", ret); + pr_err("Command Excution UnSusscesful\n"); + } + +#ifdef __KERNEL__ kfree(cmd_handle); +#else + free(cmd_handle); +#endif + return ret; } +#ifdef __KERNEL__ EXPORT_SYMBOL(gsw_api_kioctl); - +#endif int gsw_api_kclose(GSW_API_HANDLE handle) { /* Nothing to do for kernel API's */ return 0; } +#ifdef __KERNEL__ EXPORT_SYMBOL(gsw_api_kclose); +#endif diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.h b/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.h index 1e5de675076e14de8d08396a8bdeffc00150cc0c..c2021ca556e7b76504a36a2f6f077d78531bf6c5 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_ioctl_wrapper.h @@ -22,7 +22,7 @@ typedef enum { /* general declaration fits for all low-level functions. */ -typedef int (*LTQ_ll_fkt) (void *, u32); +typedef int (*LTQ_ll_fkt)(void *, u32); typedef struct ltq_lowlevel_fkts_t ltq_lowlevel_fkts_t; /* Switch API low-level function tables to map all supported IOCTL commands */ struct ltq_lowlevel_fkts_t { @@ -47,7 +47,7 @@ struct ltq_lowlevel_fkts_t { /* function type declaration for the default IOCTL low-level function in case the command cannot be found in the low-level function table, or in case no low-level function table is provided.. */ -typedef int (*ioctl_default_fkt) (void*, int, int); +typedef int (*ioctl_default_fkt)(void *, int, int); /*typedef*/ typedef struct { ltq_lowlevel_fkts_t *pLlTable; @@ -95,7 +95,7 @@ int gsw_api_drv_register(u32 major); int gsw_api_drv_unregister(u32 major); void *ioctl_wrapper_init(ioctl_wrapper_init_t *pinit); int ioctl_wrapper_dev_add(ioctl_wrapper_ctx_t *pioctldev, - void *pcoredev, u8 mnum); + void *pcoredev, u8 mnum); int gsw_api_ioctl_wrapper_cleanup(void); diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_irq.c b/drivers/net/ethernet/lantiq/switch-api/gsw_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..8b6b988d8b4717c81e815c69251032b928894884 --- /dev/null +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_irq.c @@ -0,0 +1,746 @@ +/****************************************************************************** + Copyright (c) 2016, 2017 Intel Corporation + +For licensing information, see the file 'LICENSE' in the root folder of +this software module. +******************************************************************************/ + +#include <gsw_init.h> + +typedef void (*gsw_call_back)(void *param); + +extern ethsw_api_dev_t *ecoredev[LTQ_FLOW_DEV_MAX]; + +GSW_return_t GSW_Debug_PrintPceIrqList(void *cdev) +{ + gsw_pce_irq *irq; + unsigned int i = 0; + unsigned int port = 0; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + irq = gswdev->PceIrqList->first_ptr; + printk("\n"); + + while (irq != NULL) { + printk("PCE Node %d:\n", i); + printk("Irq address = 0x%x\n", (u32)irq); + printk("Next Irq Address = 0x%x\n\n", (u32)irq->pNext); + + if (irq->Port_ier_enabled) + printk("\tPort IER = ENABLED\n"); + else + printk("\tPort IER = DISABLED\n"); + + for (i = 0; i < 12; i++) { + if (irq->P_IER_MASK & (1 << i)) { + port = i; + break; + } + } + + printk("\tP_IER_MASK = %u (port no)\n", port); + + if (irq->Event_ier_enable) + printk("\tEvent IER = ENABLED\n"); + else + printk("\tEvent IER = DISABLED\n"); + + switch (irq->E_IER_MASK) { + case PCE_MAC_TABLE_CHANGE: + printk("\tE_IER_MASK = PCE_MAC_TABLE_CHANGE\n"); + break; + + case PCE_FLOW_TABLE_RULE_MATCHED: + printk("\tE_IER_MASK = PCE_FLOW_TABLE_RULE_MATCHED\n"); + break; + + case PCE_CLASSIFICATION_PHASE_2: + printk("\tE_IER_MASK = PCE_CLASSIFICATION_PHASE_2\n"); + break; + + case PCE_CLASSIFICATION_PHASE_1: + printk("\tE_IER_MASK = PCE_CLASSIFICATION_PHASE_1\n"); + break; + + case PCE_CLASSIFICATION_PHASE_0: + printk("\tE_IER_MASK = PCE_CLASSIFICATION_PHASE_0\n"); + break; + + case PCE_PARSER_READY: + printk("\tE_IER_MASK = PCE_PARSER_READY\n"); + break; + + case PCE_IGMP_TABLE_FULL: + printk("\tE_IER_MASK = PCE_IGMP_TABLE_FULL\n"); + break; + + case PCE_MAC_TABLE_FULL: + printk("\tE_IER_MASK = PCE_MAC_TABLE_FULL\n"); + break; + } + + printk("\tP_ISR_MASK = %u\n", irq->P_ISR_MASK); + printk("\tE_ISR_MASK = %u\n", irq->E_ISR_MASK); + printk("\tcall_back = 0x%x\n", (u32)irq->call_back); + printk("\n"); + irq = irq->pNext; + i++; + } + + return GSW_statusOk; +} + +static unsigned int PortIrq_Match(gsw_pce_irq *p1, + gsw_pce_irq *p2) +{ + if (p1->P_IER_MASK == p2->P_IER_MASK && + p1->P_ISR_MASK == p2->P_ISR_MASK) + return 1; + else + return 0; +} + +static unsigned int EventIrq_Match(gsw_pce_irq *p1, + gsw_pce_irq *p2) +{ + if (p1->E_IER_MASK == p2->E_IER_MASK && + p1->E_ISR_MASK == p2->E_ISR_MASK) + return 1; + else + return 0; +} + +static GSW_return_t pce_irq_add(void *cdev, gsw_pce_irq pce_irg, + struct pce_irq_linklist *node) +{ + gsw_pce_irq *register_irq = NULL; + gsw_pce_irq *irq = NULL; + irq = node->first_ptr; + + while (irq != NULL) { + if (PortIrq_Match(&pce_irg, irq) && + EventIrq_Match(&pce_irg, irq)) { + pr_err("ERROR : Invalid operation , IRQ already registered %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + irq = irq->pNext; + } + +#ifdef __KERNEL__ + register_irq = (gsw_pce_irq *)kmalloc(sizeof(gsw_pce_irq), GFP_KERNEL); + memset(register_irq, 0, sizeof(gsw_pce_irq)); +#else + register_irq = (gsw_pce_irq *)malloc(sizeof(gsw_pce_irq)); + memset(register_irq, 0, sizeof(gsw_pce_irq)); +#endif + + register_irq->pNext = NULL; + register_irq->Port_ier_enabled = 0; + register_irq->P_IER_MASK = pce_irg.P_IER_MASK; + register_irq->Event_ier_enable = 0; + register_irq->E_IER_MASK = pce_irg.E_IER_MASK; + register_irq->P_ISR_MASK = pce_irg.P_ISR_MASK; + register_irq->E_ISR_MASK = pce_irg.E_ISR_MASK; + register_irq->call_back = pce_irg.call_back; + register_irq->param = pce_irg.param; + + if (node->first_ptr != NULL) { + node->last_ptr->pNext = register_irq; + node->last_ptr = register_irq; + } else { + node->first_ptr = node->last_ptr = register_irq; + } + + return GSW_statusOk; +} + +static GSW_return_t pce_irq_del(void *cdev, gsw_pce_irq pce_irg, + struct pce_irq_linklist *node) +{ + gsw_pce_irq *prv_irq = NULL, *delete_irq = NULL; + u32 p_ierq = 0; + delete_irq = node->first_ptr; + + while (delete_irq != NULL) { + if (PortIrq_Match(&pce_irg, delete_irq) && + EventIrq_Match(&pce_irg, delete_irq)) { + + gsw_r32(cdev, PCE_IER_0_OFFSET, + delete_irq->P_IER_MASK, + 1, &p_ierq); + + /*Check only Port IER*/ + if (p_ierq) { + pr_err("ERROR : Can not Un-Register IRQ, disable IRQ first %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return -1; + } + + if (node->first_ptr == delete_irq && + node->last_ptr == delete_irq) { + node->first_ptr = delete_irq->pNext; + node->last_ptr = delete_irq->pNext; + } else if (node->first_ptr == delete_irq) { + node->first_ptr = delete_irq->pNext; + } else if (node->last_ptr == delete_irq) { + node->last_ptr = prv_irq; + prv_irq->pNext = delete_irq->pNext; + } else { + prv_irq->pNext = delete_irq->pNext; + } + +#ifdef __KERNEL__ + kfree(delete_irq); +#else + free(delete_irq); +#endif + return GSW_statusOk; + } + + prv_irq = delete_irq; + delete_irq = delete_irq->pNext; + } + + pr_err("ERROR : Invalid operation , IRQ not registered %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; +} + +static GSW_return_t pce_irq_enable(void *cdev, gsw_pce_irq pce_irg, + struct pce_irq_linklist *node) +{ + u32 p_ierq = 0, e_ierq = 0, irq_registered = 0; + gsw_pce_irq *irq = NULL; + + irq = node->first_ptr; + + while (irq != NULL) { + p_ierq = 0; + e_ierq = 0; + + if (PortIrq_Match(&pce_irg, irq)) + p_ierq = 1; + + if (EventIrq_Match(&pce_irg, irq)) + e_ierq = 1; + + if (p_ierq && e_ierq && + pce_irg.P_IER_MASK != PCE_INVALID_PORT_IERQ && + pce_irg.E_IER_MASK != PCE_INVALID_EVENT_IERQ) { + /*If both Port IER and Event IER found + in the IRQ register list*/ + irq->Port_ier_enabled = 1; + gsw_w32(cdev, PCE_IER_0_OFFSET, + irq->P_IER_MASK, 1, 1); + + irq->Event_ier_enable = 1; + gsw_w32(cdev, PCE_IER_1_OFFSET, + irq->E_IER_MASK, 1, 1); + + return 1; + } else if (pce_irg.P_IER_MASK == PCE_INVALID_PORT_IERQ + && e_ierq) { + /*if only Event IER in + the IRQ register list*/ + irq->Event_ier_enable = 1; + gsw_w32(cdev, PCE_IER_1_OFFSET, + irq->E_IER_MASK, 1, 1); + irq_registered = 1; + } else if (pce_irg.E_IER_MASK == PCE_INVALID_EVENT_IERQ + && p_ierq) { + /*if only Port IER in + the IRQ register list*/ + irq->Port_ier_enabled = 1; + gsw_w32(cdev, PCE_IER_0_OFFSET, + irq->P_IER_MASK, 1, 1); + irq_registered = 1; + } + + irq = irq->pNext; + } + + if (!irq_registered) { + pr_err("ERROR : Invalid operation , IRQ not registered %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + return GSW_statusOk; +} + +static GSW_return_t pce_irq_disable(void *cdev, gsw_pce_irq pce_irg, + struct pce_irq_linklist *node) +{ + u32 p_ierq = 0, e_ierq = 0; + gsw_pce_irq *irq = NULL; + irq = node->first_ptr; + + if (pce_irg.P_IER_MASK == PCE_INVALID_PORT_IERQ) { + p_ierq = 1; + irq = NULL; + } else { + irq = node->first_ptr; + } + + while (irq != NULL) { + if (PortIrq_Match(&pce_irg, irq)) { + irq->Port_ier_enabled = 0; + gsw_w32(cdev, PCE_IER_0_OFFSET, + irq->P_IER_MASK, 1, 0); + p_ierq = 1; + } + + irq = irq->pNext; + } + + if (!p_ierq) { + pr_err("ERROR : Invalid operation , PORT not registered %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (pce_irg.E_IER_MASK == PCE_INVALID_EVENT_IERQ) { + e_ierq = 1; + irq = NULL; + } else { + irq = node->first_ptr; + } + + while (irq != NULL) { + if (EventIrq_Match(&pce_irg, irq)) { + irq->Event_ier_enable = 0; + gsw_w32(cdev, PCE_IER_1_OFFSET, + irq->E_IER_MASK, 1, 0); + e_ierq = 1; + } + + irq = irq->pNext; + } + + if (!e_ierq) { + pr_err("ERROR : Invalid operation , EVENT not registered %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + return GSW_statusOk; +} + +static GSW_return_t pce_irq_config(void *cdev, GSW_Irq_Op_t *irq, IRQ_TYPE IrqType) +{ + gsw_pce_irq pce_irg; + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (irq->portid > gswdev->tpnum && + irq->portid != PCE_INVALID_PORT_IERQ) { + pr_err("ERROR : PortId %d is not with in GSWIP capabilty %s:%s:%d\n", + irq->portid, __FILE__, __func__, __LINE__); + return GSW_statusErr; + } else if (irq->portid == PCE_INVALID_PORT_IERQ) { + pce_irg.P_IER_MASK = PCE_INVALID_PORT_IERQ; + } else { + pce_irg.P_IER_MASK = PCE_IER_0_PORT_MASK_GET(irq->portid); + pce_irg.P_ISR_MASK = PCE_ISR_0_PORT_MASK_GET(irq->portid); + } + + switch (irq->event) { + case PCE_MAC_TABLE_CHANGE: + pce_irg.E_IER_MASK = PCE_IER_1_CHG_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_CHG_SHIFT; + break; + + case PCE_FLOW_TABLE_RULE_MATCHED: + pce_irg.E_IER_MASK = PCE_IER_1_FLOWINT_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_FLOWINT_SHIFT; + break; + + case PCE_CLASSIFICATION_PHASE_2: + pce_irg.E_IER_MASK = PCE_IER_1_CPH2_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_CPH2_SHIFT; + break; + + case PCE_CLASSIFICATION_PHASE_1: + pce_irg.E_IER_MASK = PCE_IER_1_CPH1_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_CPH1_SHIFT; + break; + + case PCE_CLASSIFICATION_PHASE_0: + pce_irg.E_IER_MASK = PCE_IER_1_CPH0_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_CPH0_SHIFT; + break; + + case PCE_PARSER_READY: + pce_irg.E_IER_MASK = PCE_IER_1_PRDY_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_PRDY_SHIFT; + break; + + case PCE_IGMP_TABLE_FULL: + pce_irg.E_IER_MASK = PCE_IER_1_IGTF_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_IGTF_SHIFT; + break; + + case PCE_MAC_TABLE_FULL: + pce_irg.E_IER_MASK = PCE_IER_1_MTF_SHIFT; + pce_irg.E_ISR_MASK = PCE_ISR_1_MTF_SHIFT; + break; + + case PCE_INVALID_EVENT_IERQ: + pce_irg.E_IER_MASK = PCE_INVALID_EVENT_IERQ; + break; + + default: + pr_err("ERROR : Invalid pce blk event ENUM = %d %s:%s:%d\n", + irq->event, __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + switch (IrqType) { + case IRQ_REGISTER: + if (irq->event == PCE_INVALID_EVENT_IERQ) { + pr_err("ERROR : PCE_INVALID_EVENT_IERQ %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (irq->portid == PCE_INVALID_PORT_IERQ) { + pr_err("ERROR : PCE PCE_INVALID_PORT_IERQ %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (irq->call_back != NULL) { + pce_irg.call_back = irq->call_back; + pce_irg.param = irq->param; + } else { + pr_err("ERROR : callback handle is NULL %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + pce_irq_add(cdev, pce_irg, gswdev->PceIrqList); + break; + + case IRQ_UNREGISTER: + if (irq->event == PCE_INVALID_EVENT_IERQ) { + pr_err("ERROR : PCE_INVALID_EVENT_IERQ %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + if (irq->portid == PCE_INVALID_PORT_IERQ) { + pr_err("ERROR : PCE PCE_INVALID_PORT_IERQ %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + pce_irq_del(cdev, pce_irg, gswdev->PceIrqList); + break; + + case IRQ_ENABLE: + pce_irq_enable(cdev, pce_irg, gswdev->PceIrqList); + break; + + case IRQ_DISABLE: + pce_irq_disable(cdev, pce_irg, gswdev->PceIrqList); + break; + + default: + pr_err("invalid irq type %s:%s:%d\n", + __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + return GSW_statusOk; +} + +static GSW_return_t swcore_irq_config(void *cdev, GSW_Irq_Op_t *irq, IRQ_TYPE IrqType) +{ + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_irq); +#endif + + switch (irq->blk) { + case BM: + pr_err("BM BLK IRQ not supported %s:%s:%d\n", + __FILE__, __func__, __LINE__); + break; + + case SDMA: + pr_err("SDMA IRQ not supported %s:%s:%d\n", + __FILE__, __func__, __LINE__); + break; + + case FDMA: + pr_err("FDMA IRQ not supported %s:%s:%d\n", + __FILE__, __func__, __LINE__); + break; + + case PMAC: + pr_err("PMAC IRQ not supported %s:%s:%d\n", + __FILE__, __func__, __LINE__); + break; + + case PCE: + printk("Switch Core PCE BLK %s:%s:%d\n" + , __FILE__, __func__, __LINE__); + pce_irq_config(cdev, irq, IrqType); + break; + + default: + pr_err("invalid Switch IRQ Blk %s:%s:%d\n", + __FILE__, __func__, __LINE__); + ret = GSW_statusErr; + goto UNLOCK_AND_RETURN; + } + + ret = GSW_statusOk; + +UNLOCK_AND_RETURN: + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_irq); +#endif + return ret; +} + +void GSW_Irq_tasklet(unsigned long prvdata) +{ + gsw_pce_irq *pceirq = NULL; + gsw_call_back callback; + u32 p_isr = 0, e_isr = 0; + ethsw_api_dev_t *cdev = (ethsw_api_dev_t *)prvdata; + u32 pce_event = 0; + + if (cdev) { + + /*PCE IRQ*/ + /* Read PCE ETHSW_ISR if anything is set , + disable the global PCEINT IER + and Service PCE register IRQ list and Enable back + global PCEINT IER */ + /*Global PCE ISR is read only,Hardware Status*/ + gsw_r32(cdev, ETHSW_ISR_PCEINT_OFFSET, + ETHSW_ISR_PCEINT_SHIFT, ETHSW_ISR_PCEINT_SIZE, + &pce_event); + + if (pce_event) { + /*Disable PCE Global IER*/ + gsw_w32(cdev, ETHSW_IER_PCEIE_OFFSET, + ETHSW_IER_PCEIE_SHIFT, ETHSW_IER_PCEIE_SIZE, 0); + + /*PCE : Service registered IRQ list*/ + if (cdev->PceIrqList) + pceirq = cdev->PceIrqList->first_ptr; + + while (pceirq != NULL) { + callback = NULL; + + if (pceirq->Port_ier_enabled && + pceirq->Event_ier_enable) { + /*Check for Pending Interrupt*/ + gsw_r32(cdev, PCE_ISR_0_OFFSET, + pceirq->P_ISR_MASK, + 1, &p_isr); + gsw_r32(cdev, PCE_ISR_1_OFFSET, + pceirq->E_ISR_MASK, + 1, &e_isr); + + if (p_isr && e_isr) { + /*Clear only the Event + ISR (lhsc)-> cleared by writting 1. + PORT ISR cleared by Hardware (Read Only)*/ + gsw_w32(cdev, PCE_ISR_1_OFFSET, + pceirq->P_ISR_MASK, 1, 1); + + callback = pceirq->call_back; + + /*Call back Service*/ + if (callback) + callback(pceirq->param); + } + } + + pceirq = pceirq->pNext; + } + + /*Enable PCE Global IER*/ + gsw_w32(cdev, ETHSW_IER_PCEIE_OFFSET, + ETHSW_IER_PCEIE_SHIFT, ETHSW_IER_PCEIE_SIZE, 1); + } + + + /*BM : Service registered IRQ list*/ + /*yet to be done*/ + + /*SDMA : Service registered IRQ list*/ + /*yet to be done*/ + + /*FDMA : Service registered IRQ list*/ + /*yet to be done*/ + + /*PMAC : Service registered IRQ list*/ + /*yet to be done*/ + + } +} + + +#ifdef __KERNEL__ +static irqreturn_t GSW_ISR(int irq, void *dev_id) +{ + struct core_ops *sw_ops; + ethsw_api_dev_t *gswdev; + u32 dev; + + for (dev = 0; dev < LTQ_FLOW_DEV_MAX; dev++) { + sw_ops = NULL; + gswdev = NULL; + sw_ops = gsw_get_swcore_ops(dev); + + if (sw_ops) { + gswdev = GSW_PDATA_GET(sw_ops); + + if (gswdev) { + printk("\tSwitch IRQ tasklet for device %d\n", dev); + tasklet_schedule(&gswdev->gswip_tasklet); + } + } + } + + return IRQ_HANDLED; +} +#endif + + +GSW_return_t GSW_Irq_init(void *cdev) +{ + + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + u32 ret; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + /*GSWIP PCE BLK IRQ Pointer*/ +#ifdef __KERNEL__ + gswdev->PceIrqList = + (struct pce_irq_linklist *)kmalloc(sizeof(struct pce_irq_linklist), GFP_KERNEL); +#else + gswdev->PceIrqList = + (struct pce_irq_linklist *)malloc(sizeof(struct pce_irq_linklist)); +#endif + + gswdev->PceIrqList->first_ptr = NULL; + gswdev->PceIrqList->last_ptr = NULL; + + /*Enable PCE Global IER*/ + gsw_w32(cdev, ETHSW_IER_PCEIE_OFFSET, + ETHSW_IER_PCEIE_SHIFT, ETHSW_IER_PCEIE_SIZE, 1); + /*Enable BM Global IER*/ + /*yet to be done*/ + /*Enable SDMA Global IER*/ + /*yet to be done*/ + /*Enable FDMA Global IER*/ + /*yet to be done*/ + /*Enable PMAC Global IER*/ + /*yet to be done*/ + +#ifdef __KERNEL__ + + ret = request_irq(gswdev->irq_num, GSW_ISR, 0, "gswip", NULL); + + if (ret) { + pr_err("Switch irq request error %s:%s:%d", __FILE__, __func__, __LINE__); + return ret; + } + + tasklet_init(&gswdev->gswip_tasklet, + GSW_Irq_tasklet, + (unsigned long)gswdev); +#endif + + return GSW_statusOk; +} + +GSW_return_t GSW_Irq_deinit(void *cdev) +{ + + gsw_pce_irq *irq = NULL; + gsw_pce_irq *free_irq = NULL; + ethsw_api_dev_t *gswdev = (ethsw_api_dev_t *)cdev; + + if (gswdev == NULL) { + pr_err("%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + /*Free PCE Irq list*/ + if (gswdev->PceIrqList) { + irq = gswdev->PceIrqList->first_ptr; + + while (irq != NULL) { + free_irq = irq; + irq = irq->pNext; +#ifdef __KERNEL__ + kfree(free_irq); +#else + free(free_irq); +#endif + } + + /*Free PCE Irq blk*/ +#ifdef __KERNEL__ + kfree(gswdev->PceIrqList); +#else + free(gswdev->PceIrqList); +#endif + } + + return GSW_statusOk; +} + + + +GSW_return_t GSW_Irq_register(void *cdev, GSW_Irq_Op_t *irq) +{ + return swcore_irq_config(cdev, irq, IRQ_REGISTER); +} + +GSW_return_t GSW_Irq_unregister(void *cdev, GSW_Irq_Op_t *irq) +{ + return swcore_irq_config(cdev, irq, IRQ_UNREGISTER); +} + +GSW_return_t GSW_Irq_enable(void *cdev, GSW_Irq_Op_t *irq) +{ + return swcore_irq_config(cdev, irq, IRQ_ENABLE); +} + +GSW_return_t GSW_Irq_disable(void *cdev, GSW_Irq_Op_t *irq) +{ + return swcore_irq_config(cdev, irq, IRQ_DISABLE); +} + + diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_ll_func.h b/drivers/net/ethernet/lantiq/switch-api/gsw_ll_func.h index 10c48241178d1433d7db0acc64766fceca406b6c..f42c937d0dfcdb8ca1921b4e018988b7e758486c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_ll_func.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_ll_func.h @@ -79,7 +79,7 @@ - An error code in case an error occurs */ GSW_return_t GSW_8021X_EAPOL_RuleGet(void *cdev, - GSW_8021X_EAPOL_Rule_t *parm); + GSW_8021X_EAPOL_Rule_t *parm); /** This is the switch API low-level function for @@ -98,7 +98,7 @@ GSW_return_t GSW_8021X_EAPOL_RuleGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_8021X_EAPOL_RuleSet(void *cdev, - GSW_8021X_EAPOL_Rule_t *parm); + GSW_8021X_EAPOL_Rule_t *parm); /** This is the switch API low-level function for @@ -119,7 +119,7 @@ GSW_return_t GSW_8021X_EAPOL_RuleSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_8021X_PortCfgGet(void *cdev, - GSW_8021X_portCfg_t *parm); + GSW_8021X_portCfg_t *parm); /** This is the switch API low-level function for @@ -140,7 +140,7 @@ GSW_return_t GSW_8021X_PortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_8021X_PortCfgSet(void *cdev, - GSW_8021X_portCfg_t *parm); + GSW_8021X_portCfg_t *parm); /** This is the switch API low-level function for @@ -177,7 +177,7 @@ GSW_return_t GSW_MAC_TableClear(void *cdev); - An error code in case an error occurs */ GSW_return_t GSW_MAC_TableEntryAdd(void *cdev, - GSW_MAC_tableAdd_t *parm); + GSW_MAC_tableAdd_t *parm); /** This is the switch API low-level function for @@ -198,7 +198,7 @@ GSW_return_t GSW_MAC_TableEntryAdd(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MAC_TableEntryQuery(void *cdev, - GSW_MAC_tableQuery_t *parm); + GSW_MAC_tableQuery_t *parm); /** This is the switch API low-level function for @@ -219,7 +219,7 @@ GSW_return_t GSW_MAC_TableEntryQuery(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MAC_TableEntryRead(void *cdev, - GSW_MAC_tableRead_t *parm); + GSW_MAC_tableRead_t *parm); /** This is the switch API low-level function for @@ -239,7 +239,7 @@ GSW_return_t GSW_MAC_TableEntryRead(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MAC_TableEntryRemove(void *cdev, - GSW_MAC_tableRemove_t *parm); + GSW_MAC_tableRemove_t *parm); /** This is the switch API low-level function for @@ -258,7 +258,7 @@ GSW_return_t GSW_MAC_TableEntryRemove(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_STP_BPDU_RuleGet(void *cdev, - GSW_STP_BPDU_Rule_t *parm); + GSW_STP_BPDU_Rule_t *parm); /** This is the switch API low-level function for @@ -277,7 +277,7 @@ GSW_return_t GSW_STP_BPDU_RuleGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_STP_BPDU_RuleSet(void *cdev, - GSW_STP_BPDU_Rule_t *parm); + GSW_STP_BPDU_Rule_t *parm); /** This is the switch API low-level function for @@ -296,7 +296,7 @@ GSW_return_t GSW_STP_BPDU_RuleSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_STP_PortCfgGet(void *cdev, - GSW_STP_portCfg_t *parm); + GSW_STP_portCfg_t *parm); /** This is the switch API low-level function for @@ -315,7 +315,7 @@ GSW_return_t GSW_STP_PortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_STP_PortCfgSet(void *cdev, - GSW_STP_portCfg_t *parm); + GSW_STP_portCfg_t *parm); /** This is the switch API low-level function for @@ -335,7 +335,7 @@ GSW_return_t GSW_STP_PortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_TrunkingCfgGet(void *cdev, - GSW_trunkingCfg_t *parm); + GSW_trunkingCfg_t *parm); /** This is the switch API low-level function for @@ -355,7 +355,7 @@ GSW_return_t GSW_TrunkingCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_TrunkingCfgSet(void *cdev, - GSW_trunkingCfg_t *parm); + GSW_trunkingCfg_t *parm); /** This is the switch API low-level function for @@ -375,7 +375,7 @@ GSW_return_t GSW_TrunkingCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_TrunkingPortCfgGet(void *cdev, - GSW_trunkingPortCfg_t *parm); + GSW_trunkingPortCfg_t *parm); /** This is the switch API low-level function for @@ -395,7 +395,7 @@ GSW_return_t GSW_TrunkingPortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_TrunkingPortCfgSet(void *cdev, - GSW_trunkingPortCfg_t *parm); + GSW_trunkingPortCfg_t *parm); /*@}*/ /* FLOW_LL_BRIDGE */ /** \addtogroup FLOW_LL_VLAN */ @@ -418,7 +418,7 @@ GSW_return_t GSW_TrunkingPortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_SVLAN_CfgGet(void *cdev, - GSW_SVLAN_cfg_t *parm); + GSW_SVLAN_cfg_t *parm); /** This is the switch API low-level function for @@ -438,7 +438,7 @@ GSW_return_t GSW_SVLAN_CfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_SVLAN_CfgSet(void *cdev, - GSW_SVLAN_cfg_t *parm); + GSW_SVLAN_cfg_t *parm); /** This is the switch API low-level function for @@ -460,7 +460,7 @@ GSW_return_t GSW_SVLAN_CfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_SVLAN_PortCfgGet(void *cdev, - GSW_SVLAN_portCfg_t *parm); + GSW_SVLAN_portCfg_t *parm); /** This is the switch API low-level function for @@ -480,7 +480,7 @@ GSW_return_t GSW_SVLAN_PortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_SVLAN_PortCfgSet(void *cdev, - GSW_SVLAN_portCfg_t *parm); + GSW_SVLAN_portCfg_t *parm); /** This is the switch API low-level function for the \ref GSW_VLAN_MEMBER_INIT command. @@ -499,7 +499,7 @@ GSW_return_t GSW_SVLAN_PortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_Member_Init(void *cdev, - GSW_VLAN_memberInit_t *parm); + GSW_VLAN_memberInit_t *parm); /** This is the switch API low-level function for the \ref GSW_VLAN_ID_CREATE command. @@ -518,7 +518,7 @@ GSW_return_t GSW_VLAN_Member_Init(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_IdCreate(void *cdev, - GSW_VLAN_IdCreate_t *parm); + GSW_VLAN_IdCreate_t *parm); /** This is the switch API low-level function for @@ -541,7 +541,7 @@ GSW_return_t GSW_VLAN_IdCreate(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_IdDelete(void *cdev, - GSW_VLAN_IdDelete_t *parm); + GSW_VLAN_IdDelete_t *parm); /** This is the switch API low-level function for @@ -560,7 +560,7 @@ GSW_return_t GSW_VLAN_IdDelete(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_IdGet(void *cdev, - GSW_VLAN_IdGet_t *parm); + GSW_VLAN_IdGet_t *parm); /** This is the switch API low-level function for @@ -582,7 +582,7 @@ GSW_return_t GSW_VLAN_IdGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_PortCfgGet(void *cdev, - GSW_VLAN_portCfg_t *parm); + GSW_VLAN_portCfg_t *parm); /** This is the switch API low-level function for @@ -602,7 +602,7 @@ GSW_return_t GSW_VLAN_PortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_PortCfgSet(void *cdev, - GSW_VLAN_portCfg_t *parm); + GSW_VLAN_portCfg_t *parm); /** This is the switch API low-level function for @@ -622,7 +622,7 @@ GSW_return_t GSW_VLAN_PortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, - GSW_VLAN_portMemberAdd_t *parm); + GSW_VLAN_portMemberAdd_t *parm); /** This is the switch API low-level function for @@ -642,7 +642,7 @@ GSW_return_t GSW_VLAN_PortMemberAdd(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_PortMemberRead(void *cdev, - GSW_VLAN_portMemberRead_t *parm); + GSW_VLAN_portMemberRead_t *parm); /** This is the switch API low-level function for @@ -662,7 +662,7 @@ GSW_return_t GSW_VLAN_PortMemberRead(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, - GSW_VLAN_portMemberRemove_t *parm); + GSW_VLAN_portMemberRemove_t *parm); /** This is the switch API low-level function for @@ -682,7 +682,7 @@ GSW_return_t GSW_VLAN_PortMemberRemove(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_ReservedAdd(void *cdev, - GSW_VLAN_reserved_t *parm); + GSW_VLAN_reserved_t *parm); /** This is the switch API low-level function for @@ -702,7 +702,7 @@ GSW_return_t GSW_VLAN_ReservedAdd(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_VLAN_ReservedRemove(void *cdev, - GSW_VLAN_reserved_t *parm); + GSW_VLAN_reserved_t *parm); /** This is the switch API low-level function for @@ -722,7 +722,7 @@ GSW_return_t GSW_VLAN_ReservedRemove(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_PCE_EG_VLAN_CfgSet(void *cdev, - GSW_PCE_EgVLAN_Cfg_t *parm); + GSW_PCE_EgVLAN_Cfg_t *parm); /** This is the switch API low-level function for @@ -742,7 +742,7 @@ GSW_return_t GSW_PCE_EG_VLAN_CfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_PCE_EG_VLAN_CfgGet(void *cdev, - GSW_PCE_EgVLAN_Cfg_t *parm); + GSW_PCE_EgVLAN_Cfg_t *parm); /** This is the switch API low-level function for @@ -762,7 +762,7 @@ GSW_return_t GSW_PCE_EG_VLAN_CfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_PCE_EG_VLAN_EntryWrite(void *cdev, - GSW_PCE_EgVLAN_Entry_t *parm); + GSW_PCE_EgVLAN_Entry_t *parm); /** This is the switch API low-level function for @@ -782,7 +782,7 @@ GSW_return_t GSW_PCE_EG_VLAN_EntryWrite(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_PCE_EG_VLAN_EntryRead(void *cdev, - GSW_PCE_EgVLAN_Entry_t *parm); + GSW_PCE_EgVLAN_Entry_t *parm); /*@}*/ /* FLOW_LL_VLAN */ /** \addtogroup FLOW_LL_QOS */ @@ -805,7 +805,7 @@ GSW_return_t GSW_PCE_EG_VLAN_EntryRead(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ClassDSCP_Get(void *cdev, - GSW_QoS_ClassDSCP_Cfg_t *parm); + GSW_QoS_ClassDSCP_Cfg_t *parm); /** This is the switch API low-level function for @@ -825,7 +825,7 @@ GSW_return_t GSW_QoS_ClassDSCP_Get(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ClassDSCP_Set(void *cdev, - GSW_QoS_ClassDSCP_Cfg_t *parm); + GSW_QoS_ClassDSCP_Cfg_t *parm); /** This is the switch API low-level function for @@ -845,7 +845,7 @@ GSW_return_t GSW_QoS_ClassDSCP_Set(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ClassPCP_Get(void *cdev, - GSW_QoS_ClassPCP_Cfg_t *parm); + GSW_QoS_ClassPCP_Cfg_t *parm); /** This is the switch API low-level function for @@ -865,7 +865,7 @@ GSW_return_t GSW_QoS_ClassPCP_Get(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ClassPCP_Set(void *cdev, - GSW_QoS_ClassPCP_Cfg_t *parm); + GSW_QoS_ClassPCP_Cfg_t *parm); /** This is the switch API low-level function for @@ -885,7 +885,7 @@ GSW_return_t GSW_QoS_ClassPCP_Set(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_DSCP_ClassGet(void *cdev, - GSW_QoS_DSCP_ClassCfg_t *parm); + GSW_QoS_DSCP_ClassCfg_t *parm); /** This is the switch API low-level function for @@ -905,7 +905,7 @@ GSW_return_t GSW_QoS_DSCP_ClassGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_DSCP_ClassSet(void *cdev, - GSW_QoS_DSCP_ClassCfg_t *parm); + GSW_QoS_DSCP_ClassCfg_t *parm); /** This is the switch API low-level function for @@ -926,7 +926,7 @@ GSW_return_t GSW_QoS_DSCP_ClassSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgGet(void *cdev, - GSW_QoS_DSCP_DropPrecedenceCfg_t *parm); + GSW_QoS_DSCP_DropPrecedenceCfg_t *parm); /** This is the switch API low-level function for @@ -947,7 +947,7 @@ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgSet(void *cdev, - GSW_QoS_DSCP_DropPrecedenceCfg_t *parm); + GSW_QoS_DSCP_DropPrecedenceCfg_t *parm); /** This is the switch API low-level function for @@ -964,7 +964,7 @@ GSW_return_t GSW_QoS_DSCP_DropPrecedenceCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_FlowctrlCfgGet(void *cdev, - GSW_QoS_FlowCtrlCfg_t *parm); + GSW_QoS_FlowCtrlCfg_t *parm); /** This is the switch API low-level function for @@ -981,7 +981,7 @@ GSW_return_t GSW_QoS_FlowctrlCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_FlowctrlCfgSet(void *cdev, - GSW_QoS_FlowCtrlCfg_t *parm); + GSW_QoS_FlowCtrlCfg_t *parm); /** This is the switch API low-level function for @@ -998,7 +998,7 @@ GSW_return_t GSW_QoS_FlowctrlCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_FlowctrlPortCfgGet(void *cdev, - GSW_QoS_FlowCtrlPortCfg_t *parm); + GSW_QoS_FlowCtrlPortCfg_t *parm); /** This is the switch API low-level function for @@ -1015,7 +1015,7 @@ GSW_return_t GSW_QoS_FlowctrlPortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_FlowctrlPortCfgSet(void *cdev, - GSW_QoS_FlowCtrlPortCfg_t *parm); + GSW_QoS_FlowCtrlPortCfg_t *parm); /** This is the switch API low-level function for the \ref GSW_QOS_METER_CFG_GET command. @@ -1031,7 +1031,7 @@ GSW_return_t GSW_QoS_FlowctrlPortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, - GSW_QoS_meterCfg_t *parm); + GSW_QoS_meterCfg_t *parm); /** This is the switch API low-level function for @@ -1048,7 +1048,7 @@ GSW_return_t GSW_QoS_MeterCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, - GSW_QoS_meterCfg_t *parm); + GSW_QoS_meterCfg_t *parm); /** This is the switch API low-level function for @@ -1065,7 +1065,7 @@ GSW_return_t GSW_QoS_MeterCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_MeterPortAssign(void *cdev, - GSW_QoS_meterPort_t *parm); + GSW_QoS_meterPort_t *parm); /** This is the switch API low-level function for @@ -1082,7 +1082,7 @@ GSW_return_t GSW_QoS_MeterPortAssign(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_MeterPortDeassign(void *cdev, - GSW_QoS_meterPort_t *parm); + GSW_QoS_meterPort_t *parm); /** This is the switch API low-level function for @@ -1099,7 +1099,7 @@ GSW_return_t GSW_QoS_MeterPortDeassign(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_MeterPortGet(void *cdev, - GSW_QoS_meterPortGet_t *parm); + GSW_QoS_meterPortGet_t *parm); /** This is the switch API low-level function for @@ -1119,7 +1119,7 @@ GSW_return_t GSW_QoS_MeterPortGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PCP_ClassGet(void *cdev, - GSW_QoS_PCP_ClassCfg_t *parm); + GSW_QoS_PCP_ClassCfg_t *parm); /** This is the switch API low-level function for @@ -1139,7 +1139,7 @@ GSW_return_t GSW_QoS_PCP_ClassGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PCP_ClassSet(void *cdev, - GSW_QoS_PCP_ClassCfg_t *parm); + GSW_QoS_PCP_ClassCfg_t *parm); /** This is the switch API low-level function for @@ -1159,7 +1159,7 @@ GSW_return_t GSW_QoS_PCP_ClassSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PortCfgGet(void *cdev, - GSW_QoS_portCfg_t *parm); + GSW_QoS_portCfg_t *parm); /** This is the switch API low-level function for @@ -1179,7 +1179,7 @@ GSW_return_t GSW_QoS_PortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PortCfgSet(void *cdev, - GSW_QoS_portCfg_t *parm); + GSW_QoS_portCfg_t *parm); /** This is the switch API low-level function for @@ -1199,7 +1199,7 @@ GSW_return_t GSW_QoS_PortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PortRemarkingCfgGet(void *cdev, - GSW_QoS_portRemarkingCfg_t *parm); + GSW_QoS_portRemarkingCfg_t *parm); /** This is the switch API low-level function for @@ -1219,7 +1219,7 @@ GSW_return_t GSW_QoS_PortRemarkingCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, - GSW_QoS_portRemarkingCfg_t *parm); + GSW_QoS_portRemarkingCfg_t *parm); /** This is the switch API low-level function for @@ -1236,7 +1236,7 @@ GSW_return_t GSW_QoS_PortRemarkingCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_QueueBufferReserveCfgGet(void *cdev, - GSW_QoS_QueueBufferReserveCfg_t *parm); + GSW_QoS_QueueBufferReserveCfg_t *parm); /** This is the switch API low-level function for @@ -1253,7 +1253,7 @@ GSW_return_t GSW_QoS_QueueBufferReserveCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_QueueBufferReserveCfgSet(void *cdev, - GSW_QoS_QueueBufferReserveCfg_t *parm); + GSW_QoS_QueueBufferReserveCfg_t *parm); /** This is the switch API low-level function for the \ref GSW_QOS_QUEUE_PORT_GET command. @@ -1269,7 +1269,7 @@ GSW_return_t GSW_QoS_QueueBufferReserveCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_QueuePortGet(void *cdev, - GSW_QoS_queuePort_t *parm); + GSW_QoS_queuePort_t *parm); /** This is the switch API low-level function for @@ -1286,7 +1286,7 @@ GSW_return_t GSW_QoS_QueuePortGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_QueuePortSet(void *cdev, - GSW_QoS_queuePort_t *parm); + GSW_QoS_queuePort_t *parm); /** This is the switch API low-level function for @@ -1306,7 +1306,7 @@ GSW_return_t GSW_QoS_QueuePortSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortGet(void *cdev, - GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm); + GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm); /** This is the switch API low-level function for @@ -1326,7 +1326,7 @@ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortSet(void *cdev, - GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm); + GSW_QoS_SVLAN_ClassPCP_PortCfg_t *parm); /** This is the switch API low-level function for @@ -1346,7 +1346,7 @@ GSW_return_t GSW_QoS_SVLAN_ClassPCP_PortSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SVLAN_PCP_ClassGet(void *cdev, - GSW_QoS_SVLAN_PCP_ClassCfg_t *parm); + GSW_QoS_SVLAN_PCP_ClassCfg_t *parm); /** This is the switch API low-level function for @@ -1366,7 +1366,7 @@ GSW_return_t GSW_QoS_SVLAN_PCP_ClassGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SVLAN_PCP_ClassSet(void *cdev, - GSW_QoS_SVLAN_PCP_ClassCfg_t *parm); + GSW_QoS_SVLAN_PCP_ClassCfg_t *parm); /** This is the switch API low-level function for the \ref GSW_QOS_SCHEDULER_CFG_GET command. @@ -1382,7 +1382,7 @@ GSW_return_t GSW_QoS_SVLAN_PCP_ClassSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SchedulerCfgGet(void *cdev, - GSW_QoS_schedulerCfg_t *parm); + GSW_QoS_schedulerCfg_t *parm); /** This is the switch API low-level function for @@ -1399,7 +1399,7 @@ GSW_return_t GSW_QoS_SchedulerCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_SchedulerCfgSet(void *cdev, - GSW_QoS_schedulerCfg_t *parm); + GSW_QoS_schedulerCfg_t *parm); /** This is the switch API low-level function for @@ -1416,7 +1416,7 @@ GSW_return_t GSW_QoS_SchedulerCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ShaperCfgGet(void *cdev, - GSW_QoS_ShaperCfg_t *parm); + GSW_QoS_ShaperCfg_t *parm); /** This is the switch API low-level function for @@ -1433,7 +1433,7 @@ GSW_return_t GSW_QoS_ShaperCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ShaperCfgSet(void *cdev, - GSW_QoS_ShaperCfg_t *parm); + GSW_QoS_ShaperCfg_t *parm); /** This is the switch API low-level function for @@ -1450,7 +1450,7 @@ GSW_return_t GSW_QoS_ShaperCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ShaperQueueAssign(void *cdev, - GSW_QoS_ShaperQueue_t *parm); + GSW_QoS_ShaperQueue_t *parm); /** This is the switch API low-level function for @@ -1467,7 +1467,7 @@ GSW_return_t GSW_QoS_ShaperQueueAssign(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ShaperQueueDeassign(void *cdev, - GSW_QoS_ShaperQueue_t *parm); + GSW_QoS_ShaperQueue_t *parm); /** This is the switch API low-level function for @@ -1484,7 +1484,7 @@ GSW_return_t GSW_QoS_ShaperQueueDeassign(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_ShaperQueueGet(void *cdev, - GSW_QoS_ShaperQueueGet_t *parm); + GSW_QoS_ShaperQueueGet_t *parm); /** This is the switch API low-level function for @@ -1565,7 +1565,7 @@ GSW_return_t GSW_QoS_WredCfgSet(void *cdev, GSW_QoS_WRED_Cfg_t *parm); - An error code in case an error occurs */ GSW_return_t GSW_QoS_WredPortCfgGet(void *cdev, - GSW_QoS_WRED_PortCfg_t *parm); + GSW_QoS_WRED_PortCfg_t *parm); /** This is the switch API low-level function for @@ -1582,7 +1582,7 @@ GSW_return_t GSW_QoS_WredPortCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_WredPortCfgSet(void *cdev, - GSW_QoS_WRED_PortCfg_t *parm); + GSW_QoS_WRED_PortCfg_t *parm); /** This is the switch API low-level function for the \ref GSW_QOS_WRED_QUEUE_CFG_GET command. @@ -1598,7 +1598,7 @@ GSW_return_t GSW_QoS_WredPortCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_WredQueueCfgGet(void *cdev, - GSW_QoS_WRED_QueueCfg_t *parm); + GSW_QoS_WRED_QueueCfg_t *parm); /** This is the switch API low-level function for @@ -1615,7 +1615,7 @@ GSW_return_t GSW_QoS_WredQueueCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_QoS_WredQueueCfgSet(void *cdev, - GSW_QoS_WRED_QueueCfg_t *parm); + GSW_QoS_WRED_QueueCfg_t *parm); /*@}*/ /* FLOW_LL_QOS */ /** \addtogroup FLOW_LL_MULTICAST */ @@ -1637,7 +1637,7 @@ GSW_return_t GSW_QoS_WredQueueCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, - GSW_multicastRouter_t *parm); + GSW_multicastRouter_t *parm); /** This is the switch API low-level function for @@ -1657,7 +1657,7 @@ GSW_return_t GSW_MulticastRouterPortAdd(void *cdev, (e.g. Ethernet port parameter out of range) */ GSW_return_t GSW_MulticastRouterPortRead(void *cdev, - GSW_multicastRouterRead_t *parm); + GSW_multicastRouterRead_t *parm); /** This is the switch API low-level function for @@ -1677,7 +1677,7 @@ GSW_return_t GSW_MulticastRouterPortRead(void *cdev, (e.g. Ethernet port parameter out of range) */ GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, - GSW_multicastRouter_t *parm); + GSW_multicastRouter_t *parm); /** This is the switch API low-level function for @@ -1701,7 +1701,7 @@ GSW_return_t GSW_MulticastRouterPortRemove(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, - GSW_multicastSnoopCfg_t *parm); + GSW_multicastSnoopCfg_t *parm); /** This is the switch API low-level function for @@ -1725,7 +1725,7 @@ GSW_return_t GSW_MulticastSnoopCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, - GSW_multicastSnoopCfg_t *parm); + GSW_multicastSnoopCfg_t *parm); /** This is the switch API low-level function for @@ -1748,7 +1748,7 @@ GSW_return_t GSW_MulticastSnoopCfgSet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastTableEntryAdd(void *cdev, - GSW_multicastTable_t *parm); + GSW_multicastTable_t *parm); /** This is the switch API low-level function for @@ -1770,7 +1770,7 @@ GSW_return_t GSW_MulticastTableEntryAdd(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, - GSW_multicastTableRead_t *parm); + GSW_multicastTableRead_t *parm); /** This is the switch API low-level function for @@ -1793,7 +1793,7 @@ GSW_return_t GSW_MulticastTableEntryRead(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_MulticastTableEntryRemove(void *cdev, - GSW_multicastTable_t *parm); + GSW_multicastTable_t *parm); /*@}*/ /* FLOW_LL_MULTICAST */ /** \addtogroup FLOW_LL_OAM */ @@ -1854,7 +1854,7 @@ GSW_return_t GSW_CPU_PortCfgSet(void *cdev, GSW_CPU_PortCfg_t *parm); */ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, - GSW_CPU_PortExtendCfg_t *parm); + GSW_CPU_PortExtendCfg_t *parm); /** This is the switch API low-level function for @@ -1874,7 +1874,7 @@ GSW_return_t GSW_CPU_PortExtendCfgGet(void *cdev, - An error code in case an error occurs */ GSW_return_t GSW_CPU_PortExtendCfgSet(void *cdev, - GSW_CPU_PortExtendCfg_t *parm); + GSW_CPU_PortExtendCfg_t *parm); /** This is the switch API low-level function for @@ -2151,6 +2151,42 @@ GSW_return_t GSW_GswssCfg(void *cdev, GSW_MAC_cfg_t *parm); */ GSW_return_t GSW_LmacCfg(void *cdev, GSW_MAC_cfg_t *parm); +/** + This is the switch API low-level function for + the GSW_MACSEC_CFG command. + + \param cdev This parameter is a pointer to the device context + which contains all information related to this special + instance of the device. + \param parm Pointer to \ref GSW_MAC_cfg_t. + + \remarks The function returns an error code in case an error occurs. + The error code is described in \ref GSW_status_t. + + \return Return value as follows: + - GSW_statusOk: if successful + - An error code in case an error occurs +*/ +GSW_return_t GSW_MacsecCfg(void *cdev, GSW_MAC_cfg_t *parm); + +/** + This is the switch API low-level function for + the GSW_DUMP_MEM command. + + \param cdev This parameter is a pointer to the device context + which contains all information related to this special + instance of the device. + \param parm Pointer to \ref GSW_debug_t. + + \remarks The function returns an error code in case an error occurs. + The error code is described in \ref GSW_status_t. + + \return Return value as follows: + - GSW_statusOk: if successful + - An error code in case an error occurs +*/ +GSW_return_t GSW_DumpTable(void *cdev, GSW_table_t *parm); + /** This is the switch API low-level function for @@ -2407,11 +2443,11 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm); This is the switch API low-level function for the \ref GSW_RMON_TFLOW_CLEAR command. - \param cdev This parameter is a pointer to the device context which contains + \param cdev This parameter is a pointer to the device context which contains all information related to this special instance of the device. - - \param parm Pointer to a pre-allocated \ref GSW_RMON_extendGet_t structure. - The structure element 'nPortId' is an input parameter stating on which + + \param parm Pointer to a pre-allocated \ref GSW_RMON_extendGet_t structure. + The structure element 'nPortId' is an input parameter stating on which TFLOW's index to clear RMON counters. By default it clears at index 0. @@ -2425,14 +2461,14 @@ GSW_return_t GSW_RMON_Clear(void *cdev, GSW_RMON_clear_t *parm); GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm); /** - This is the switch API low-level function for + This is the switch API low-level function for the \ref GSW_TFLOW_COUNT_MODE_SET command. - \param cdev This parameter is a pointer to the device context which contains + \param cdev This parameter is a pointer to the device context which contains all information related to this special instance of the device. - - \param parm Pointer to a pre-allocated \ref GSW_TflowCmodeConf_t structure. - The structure element 'eCountType' is the optional input parameter + + \param parm Pointer to a pre-allocated \ref GSW_TflowCmodeConf_t structure. + The structure element 'eCountType' is the optional input parameter stating on to which PCE counting mode config to set. By default it sets all PCE Rx/Tx/Bp-Tx configs to same value. @@ -2446,18 +2482,18 @@ GSW_return_t GSW_RmonTflowClear(void *cdev, GSW_RMON_flowGet_t *parm); GSW_return_t GSW_TflowCountModeSet(void *cdev, GSW_TflowCmodeConf_t *parm); /** - This is the switch API low-level function for + This is the switch API low-level function for the \ref GSW_TFLOW_COUNT_MODE_GET command. - \param cdev This parameter is a pointer to the device context which contains + \param cdev This parameter is a pointer to the device context which contains all information related to this special instance of the device. - \param parm Pointer to a pre-allocated \ref GSW_TflowCmodeConf_t structure. - The structure element 'eCountType' is the only and optional input parameter + \param parm Pointer to a pre-allocated \ref GSW_TflowCmodeConf_t structure. + The structure element 'eCountType' is the only and optional input parameter stating on to which PCE counting mode config to get. By default it gets PCE Rx config register. \remarks The function does validate input params. - + \return Return value as follows: - GSW_statusOk: if successful - An error code in case an error occurs @@ -3216,24 +3252,43 @@ GSW_return_t GSW_CtpPortConfigReset(void *cdev, GSW_CTP_portConfig_t *parm); GSW_return_t GSW_DefaultMacFilterSet(void *cdev, GSW_MACFILTER_default_t *parm); GSW_return_t GSW_DefaultMacFilterGet(void *cdev, GSW_MACFILTER_default_t *parm); -GSW_return_t GSW_Debug_CtpTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_BrgPortTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_BrgTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_ExvlanTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_VlanFilterTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_MeterTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_Dscp2PcpTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PmapperTableStatus(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PmacBpTable(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PmacEgTable(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PmacIgTable(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PceBypassTable(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_PceQTable(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_GetLpStatistics(void *cdev,GSW_debug_t *parm); -GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev,GSW_debug_t *parm); +GSW_return_t GSW_Debug_CtpTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_BrgPortTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_BrgTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_ExvlanTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_VlanFilterTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_MeterTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_Dscp2PcpTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PmapperTableStatus(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PmacBpTable(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PmacEgTable(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PmacIgTable(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PceBypassTable(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PceQTable(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_GetLpStatistics(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_GetCtpStatistics(void *cdev, GSW_debug_t *parm); +GSW_return_t GSW_Debug_PrintPceIrqList(void *cdev); +GSW_return_t GSW_Debug_RMON_Port_Get(void *cdev, GSW_Debug_RMON_Port_cnt_t *parm); + + + +GSW_return_t GSW_Irq_register(void *cdev, GSW_Irq_Op_t *irq); +GSW_return_t GSW_Irq_unregister(void *cdev, GSW_Irq_Op_t *irq); +GSW_return_t GSW_Irq_enable(void *cdev, GSW_Irq_Op_t *irq); +GSW_return_t GSW_Irq_disable(void *cdev, GSW_Irq_Op_t *irq); + +GSW_return_t GSW_Irq_init(void *cdev); +GSW_return_t GSW_Irq_deinit(void *cdev); + +void GSW_Irq_tasklet(unsigned long prvdata); -/*@}*/ /* FLOW_LL_OAM */ + + + + +/*@}*/ /* FLOW_LL_OAM */ +#ifdef __KERNEL__ /** \addtogroup GSWIP_ROUTE */ /*@{*/ /** @@ -3349,7 +3404,7 @@ int GSW_ROUTE_TunnelEntryRead(void *cdev, GSW_ROUTE_Tunnel_Entry_t *pTunnel); - An error code < 0 in case an error occurs */ int GSW_ROUTE_L2NATCfgWrite(void *cdev, - GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); + GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); /** \brief This function reads currently configured L2NAT entry in @@ -3364,7 +3419,7 @@ int GSW_ROUTE_L2NATCfgWrite(void *cdev, - An error code in case an error occurs */ int GSW_ROUTE_L2NATCfgRead(void *cdev, - GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); + GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); /** \brief This function reads or reads-n-clears Session Hit @@ -3393,5 +3448,5 @@ int GSW_ROUTE_SessHitOp(void *cdev, GSW_ROUTE_Session_Hit_t *pHitOp); int GSW_ROUTE_SessDestModify(void *cdev, GSW_ROUTE_Session_Dest_t *pDestCfg); /*@}*/ /* GSWIP_ROUTE */ - +#endif #endif /* _LTQ_ETHSW_FLOW_LL_H_ */ diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_ll_table.c b/drivers/net/ethernet/lantiq/switch-api/gsw_ll_table.c index a74993c9414eef18d2bf29d13dec08ee61b289a0..c13a50e6e48fad6a74fa2cb37ee7fe22e144539e 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_ll_table.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_ll_table.c @@ -10,63 +10,63 @@ ******************************************************************************/ -#include "gsw_init.h" +#include <gsw_init.h> #ifdef GSW_SW_FKT - #undef GSW_SW_FKT +#undef GSW_SW_FKT #endif /* GSW_SW_FKT */ #define GSW_SW_FKT(x, y) x ? (LTQ_ll_fkt)y : NULL #ifdef CONFIG_LTQ_8021X - #undef CONFIG_LTQ_8021X - #define CONFIG_LTQ_8021X 1 +#undef CONFIG_LTQ_8021X +#define CONFIG_LTQ_8021X 1 #else - #define CONFIG_LTQ_8021X 0 +#define CONFIG_LTQ_8021X 0 #endif #ifdef CONFIG_LTQ_MULTICAST - #undef CONFIG_LTQ_MULTICAST - #define CONFIG_LTQ_MULTICAST 1 +#undef CONFIG_LTQ_MULTICAST +#define CONFIG_LTQ_MULTICAST 1 #else - #define CONFIG_LTQ_MULTICAST 0 +#define CONFIG_LTQ_MULTICAST 0 #endif #ifdef CONFIG_LTQ_QOS - #undef CONFIG_LTQ_QOS - #define CONFIG_LTQ_QOS 1 +#undef CONFIG_LTQ_QOS +#define CONFIG_LTQ_QOS 1 #else - #define CONFIG_LTQ_QOS 0 +#define CONFIG_LTQ_QOS 0 #endif #ifdef CONFIG_LTQ_STP - #undef CONFIG_LTQ_STP - #define CONFIG_LTQ_STP 1 +#undef CONFIG_LTQ_STP +#define CONFIG_LTQ_STP 1 #else - #define CONFIG_LTQ_STP 0 +#define CONFIG_LTQ_STP 0 #endif #ifdef CONFIG_LTQ_VLAN - #undef CONFIG_LTQ_VLAN - #define CONFIG_LTQ_VLAN 1 +#undef CONFIG_LTQ_VLAN +#define CONFIG_LTQ_VLAN 1 #else - #define CONFIG_LTQ_VLAN 0 +#define CONFIG_LTQ_VLAN 0 #endif #ifdef CONFIG_LTQ_WOL - #undef CONFIG_LTQ_WOL - #define CONFIG_LTQ_WOL 1 +#undef CONFIG_LTQ_WOL +#define CONFIG_LTQ_WOL 1 #else - #define CONFIG_LTQ_WOL 0 +#define CONFIG_LTQ_WOL 0 #endif #ifdef CONFIG_LTQ_PMAC - #undef CONFIG_LTQ_PMAC - #define CONFIG_LTQ_PMAC 1 +#undef CONFIG_LTQ_PMAC +#define CONFIG_LTQ_PMAC 1 #else - #define CONFIG_LTQ_PMAC 0 +#define CONFIG_LTQ_PMAC 0 #endif //#define CONFIG_LTQ_PMAC 1 #ifdef CONFIG_LTQ_RMON - #undef CONFIG_LTQ_RMON - #define CONFIG_LTQ_RMON 1 +#undef CONFIG_LTQ_RMON +#define CONFIG_LTQ_RMON 1 #else - #define CONFIG_LTQ_RMON 0 +#define CONFIG_LTQ_RMON 0 #endif //#define CONFIG_LTQ_RMON 1 LTQ_ll_fkt ltq_fkt_ptr_tbl[] = { @@ -260,7 +260,7 @@ LTQ_ll_fkt ltq_fkt_ptr_tbl[] = { (LTQ_ll_fkt) GSW_MDIO_DataRead, /* Command: GSW_MDIO_DATA_WRITE ; Index: 0x5E */ (LTQ_ll_fkt) GSW_MDIO_DataWrite, - /* Command: GSW_MMD_DATA_READ ; Index: 0x5F */ + /* Command: GSW_MMD_DATA_READ ; Index: 0x5F */ (LTQ_ll_fkt) GSW_MmdDataRead, /* Command: GSW_MMD_DATA_WRITE ; Index: 0x60 */ (LTQ_ll_fkt) GSW_MmdDataWrite, @@ -428,7 +428,7 @@ LTQ_ll_fkt ltq_fkt_ptr_tbl[] = { (LTQ_ll_fkt) GSW_DefaultMacFilterSet, /* Command: GSW_DEFAUL_MAC_FILTER_GET ; Index: 0xBB */ (LTQ_ll_fkt) GSW_DefaultMacFilterGet, - /* Command: GSW_CTP_PORT_CONFIG_RESET ; Index: 0xBC */ + /* Command: GSW_CTP_PORT_CONFIG_RESET ; Index: 0xBC */ (LTQ_ll_fkt) GSW_CtpPortConfigReset, /* Command: GSW_RMON_TFLOW_CLEAR ; Index: 0xBD */ (LTQ_ll_fkt) GSW_RmonTflowClear, @@ -437,13 +437,13 @@ LTQ_ll_fkt ltq_fkt_ptr_tbl[] = { /* Command: GSW_TFLOW_COUNT_MODE_GET ; Index: 0xBF */ (LTQ_ll_fkt) GSW_TflowCountModeGet, /* Command: GSW_TFLOW_COUNT_MODE_GET ; Index: 0xC0 */ - (LTQ_ll_fkt) GSW_CTP_PortAssignmentAlloc, + (LTQ_ll_fkt) GSW_CTP_PortAssignmentAlloc, /* Command: GSW_TFLOW_COUNT_MODE_GET ; Index: 0xC1 */ - (LTQ_ll_fkt) GSW_CTP_PortAssignmentFree, + (LTQ_ll_fkt) GSW_CTP_PortAssignmentFree, /* Command: GSW_EXTENDEDVLAN_ALLOC ; Index: 0xC2 */ - (LTQ_ll_fkt) GSW_ExtendedVlanAlloc, + (LTQ_ll_fkt) GSW_ExtendedVlanAlloc, /* Command: GSW_VLANFILTER_ALLOC ; Index: 0xC3 */ - (LTQ_ll_fkt) GSW_VlanFilterAlloc, + (LTQ_ll_fkt) GSW_VlanFilterAlloc, /* Command: GSW_BRIDGE_ALLOC ; Index: 0xC4 */ (LTQ_ll_fkt) GSW_BridgeAlloc, /* Command: GSW_BRIDGE_PORT_ALLOC ; Index: 0xC5 */ @@ -451,9 +451,13 @@ LTQ_ll_fkt ltq_fkt_ptr_tbl[] = { /* Command: GSW_XGMAC_CFG ; Index: 0xC6 */ (LTQ_ll_fkt) GSW_XgmacCfg, /* Command: GSW_GSWSS_CFG ; Index: 0xC7 */ - (LTQ_ll_fkt) GSW_GswssCfg, + (LTQ_ll_fkt) GSW_GswssCfg, /* Command: GSW_LMAC_CFG ; Index: 0xC8 */ - (LTQ_ll_fkt) GSW_LmacCfg, + (LTQ_ll_fkt) GSW_LmacCfg, + /* Command: GSW_MACSEC_CFG ; Index: 0xC9 */ + (LTQ_ll_fkt) GSW_MacsecCfg, + /* Command: GSW_DUMP_MEM ; Index: 0xCA */ + (LTQ_ll_fkt) GSW_DumpTable, }; ltq_lowlevel_fkts_t GSW_FLOW_fkt_tbl = { @@ -488,14 +492,14 @@ LTQ_ll_fkt gsw_flow_fkt_ptr_tbl[] = { (LTQ_ll_fkt) GSW_Reset, /* Command: GSW_RMON_EXTEND_GET ; Index: 0x0B */ (LTQ_ll_fkt) GSW_RMON_ExtendGet, - /* Command: GSW_TIMESTAMP_TIMER_SET ; Index: 0x0C */ + /* Command: GSW_TIMESTAMP_TIMER_SET ; Index: 0x0C */ (LTQ_ll_fkt) GSW_TimestampTimerSet, /* Command: GSW_TIMESTAMP_TIMER_GET ; Index: 0x0D */ (LTQ_ll_fkt) GSW_TimestampTimerGet, /* Command: GSW_TIMESTAMP_PORT_READ ; Index: 0x0E */ (LTQ_ll_fkt) GSW_TimestampPortRead, /* Command: GSW_RMON_FLOW_GET ; Index: 0x0F */ - (LTQ_ll_fkt) GSW_RMON_FlowGet, + (LTQ_ll_fkt) GSW_RMON_FlowGet, }; ltq_lowlevel_fkts_t ltq_flow_fkt_tbl = { @@ -505,7 +509,7 @@ ltq_lowlevel_fkts_t ltq_flow_fkt_tbl = { gsw_flow_fkt_ptr_tbl /* pFkts */ }; -#if 1 +#ifdef __KERNEL__ LTQ_ll_fkt gsw_rt_fkt_ptr_tbl[] = { /* 0x00 */ (LTQ_ll_fkt) NULL, diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_pae.c b/drivers/net/ethernet/lantiq/switch-api/gsw_pae.c index b82baee8c9b090f25b23d35b47efce4573533d4f..a457ced2ff21192b0eaa73662ddf2a4e0bea363c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_pae.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_pae.c @@ -15,329 +15,28 @@ ltq_rt_table_t *rthandler = NULL; #define RT_ASSERT(t) {if ((t)) {\ - return -1; } } + return -1; } } #define RT_DEBUG 0 -int route_table_read(void *cdev, pctbl_prog_t *rdata) -{ - u32 value; - do { - gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, - PCE_TBL_ADDR_ADDR_SHIFT, - PCE_TBL_ADDR_ADDR_SIZE, rdata->pcindex); - gsw_w32(cdev, PCE_RTBL_CTRL_ADDR_OFFSET, - PCE_RTBL_CTRL_ADDR_SHIFT, - PCE_RTBL_CTRL_ADDR_SIZE, rdata->table); - gsw_w32(cdev, PCE_RTBL_CTRL_OPMOD_OFFSET, - PCE_RTBL_CTRL_OPMOD_SHIFT, - PCE_RTBL_CTRL_OPMOD_SIZE, rdata->op_mode); - gsw_w32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_r32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, &value); - rdata->key[15] = value; - gsw_r32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, &value); - rdata->key[14] = value; - gsw_r32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, &value); - rdata->key[13] = value; - gsw_r32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, &value); - rdata->key[12] = value; - gsw_r32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, &value); - rdata->key[11] = value; - gsw_r32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, &value); - rdata->key[10] = value; - gsw_r32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, &value); - rdata->key[9] = value; - gsw_r32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, &value); - rdata->key[8] = value; - gsw_r32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, &value); - rdata->key[7] = value; - gsw_r32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, &value); - rdata->key[6] = value; - gsw_r32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, &value); - rdata->key[5] = value; - gsw_r32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, &value); - rdata->key[4] = value; - gsw_r32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, &value); - rdata->key[3] = value; - gsw_r32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, &value); - rdata->key[2] = value; - gsw_r32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, &value); - rdata->key[1] = value; - gsw_r32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, &value); - rdata->key[0] = value; - - gsw_r32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, &value); - rdata->val[15] = value; - gsw_r32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, &value); - rdata->val[14] = value; - gsw_r32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, &value); - rdata->val[13] = value; - gsw_r32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, &value); - rdata->val[12] = value; - gsw_r32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, &value); - rdata->val[11] = value; - gsw_r32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, &value); - rdata->val[10] = value; - gsw_r32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, &value); - rdata->val[9] = value; - gsw_r32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, &value); - rdata->val[8] = value; - gsw_r32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, &value); - rdata->val[7] = value; - gsw_r32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, &value); - rdata->val[6] = value; - gsw_r32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, &value); - rdata->val[5] = value; - gsw_r32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, &value); - rdata->val[4] = value; - gsw_r32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, &value); - rdata->val[3] = value; - gsw_r32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, &value); - rdata->val[2] = value; - gsw_r32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, &value); - rdata->val[1] = value; - gsw_r32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, &value); - rdata->val[0] = value; - gsw_r32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, &value); - rdata->mask[0] = value; - gsw_r32(cdev, PCE_RTBL_CTRL_VLD_OFFSET, - PCE_RTBL_CTRL_VLD_SHIFT, - PCE_RTBL_CTRL_VLD_SIZE, &value); - rdata->valid = value; - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); - return GSW_statusOk; -} - -int route_table_write(void *cdev, pctbl_prog_t *rdata) -{ - u32 value; - u16 udata; - do { - gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, &value); - } while (value); - gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, - PCE_TBL_ADDR_ADDR_SHIFT, PCE_TBL_ADDR_ADDR_SIZE, - rdata->pcindex); - - udata = rdata->table; - gsw_w32(cdev, PCE_RTBL_CTRL_ADDR_OFFSET, - PCE_RTBL_CTRL_ADDR_SHIFT, - PCE_RTBL_CTRL_ADDR_SIZE, udata); - - gsw_w32(cdev, PCE_RTBL_CTRL_OPMOD_OFFSET, - PCE_RTBL_CTRL_OPMOD_SHIFT, - PCE_RTBL_CTRL_OPMOD_SIZE, rdata->op_mode); - - gsw_w32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, - PCE_TBL_KEY_15_KEY15_SHIFT, - PCE_TBL_KEY_15_KEY15_SIZE, rdata->key[15]); - gsw_w32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, - PCE_TBL_KEY_14_KEY14_SHIFT, - PCE_TBL_KEY_14_KEY14_SIZE, rdata->key[14]); - gsw_w32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, - PCE_TBL_KEY_13_KEY13_SHIFT, - PCE_TBL_KEY_13_KEY13_SIZE, rdata->key[13]); - gsw_w32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, - PCE_TBL_KEY_12_KEY12_SHIFT, - PCE_TBL_KEY_12_KEY12_SIZE, rdata->key[12]); - gsw_w32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, - PCE_TBL_KEY_11_KEY11_SHIFT, - PCE_TBL_KEY_11_KEY11_SIZE, rdata->key[11]); - gsw_w32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, - PCE_TBL_KEY_10_KEY10_SHIFT, - PCE_TBL_KEY_10_KEY10_SIZE, rdata->key[10]); - gsw_w32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, - PCE_TBL_KEY_9_KEY9_SHIFT, - PCE_TBL_KEY_9_KEY9_SIZE, rdata->key[9]); - gsw_w32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, - PCE_TBL_KEY_8_KEY8_SHIFT, - PCE_TBL_KEY_8_KEY8_SIZE, rdata->key[8]); - gsw_w32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, - PCE_TBL_KEY_7_KEY7_SHIFT, - PCE_TBL_KEY_7_KEY7_SIZE, rdata->key[7]); - gsw_w32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, - PCE_TBL_KEY_6_KEY6_SHIFT, - PCE_TBL_KEY_6_KEY6_SIZE, rdata->key[6]); - gsw_w32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, - PCE_TBL_KEY_5_KEY5_SHIFT, - PCE_TBL_KEY_5_KEY5_SIZE, rdata->key[5]); - gsw_w32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, - PCE_TBL_KEY_4_KEY4_SHIFT, - PCE_TBL_KEY_4_KEY4_SIZE, rdata->key[4]); - gsw_w32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, - PCE_TBL_KEY_3_KEY3_SHIFT, - PCE_TBL_KEY_3_KEY3_SIZE, rdata->key[3]); - gsw_w32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, - PCE_TBL_KEY_2_KEY2_SHIFT, - PCE_TBL_KEY_2_KEY2_SIZE, rdata->key[2]); - gsw_w32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, - PCE_TBL_KEY_1_KEY1_SHIFT, - PCE_TBL_KEY_1_KEY1_SIZE, rdata->key[1]); - gsw_w32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, - PCE_TBL_KEY_0_KEY0_SHIFT, - PCE_TBL_KEY_0_KEY0_SIZE, rdata->key[0]); - - gsw_w32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, - PCE_TBL_MASK_0_MASK0_SHIFT, - PCE_TBL_MASK_0_MASK0_SIZE, rdata->mask[0]); - - gsw_w32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, - PCE_TBL_VAL_15_VAL15_SHIFT, - PCE_TBL_VAL_15_VAL15_SIZE, rdata->val[15]); - gsw_w32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, - PCE_TBL_VAL_14_VAL14_SHIFT, - PCE_TBL_VAL_14_VAL14_SIZE, rdata->val[14]); - gsw_w32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, - PCE_TBL_VAL_13_VAL13_SHIFT, - PCE_TBL_VAL_13_VAL13_SIZE, rdata->val[13]); - gsw_w32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, - PCE_TBL_VAL_12_VAL12_SHIFT, - PCE_TBL_VAL_12_VAL12_SIZE, rdata->val[12]); - gsw_w32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, - PCE_TBL_VAL_11_VAL11_SHIFT, - PCE_TBL_VAL_11_VAL11_SIZE, rdata->val[11]); - gsw_w32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, - PCE_TBL_VAL_10_VAL10_SHIFT, - PCE_TBL_VAL_10_VAL10_SIZE, rdata->val[10]); - gsw_w32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, - PCE_TBL_VAL_9_VAL9_SHIFT, - PCE_TBL_VAL_9_VAL9_SIZE, rdata->val[9]); - gsw_w32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, - PCE_TBL_VAL_8_VAL8_SHIFT, - PCE_TBL_VAL_8_VAL8_SIZE, rdata->val[8]); - gsw_w32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, - PCE_TBL_VAL_7_VAL7_SHIFT, - PCE_TBL_VAL_7_VAL7_SIZE, rdata->val[7]); - gsw_w32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, - PCE_TBL_VAL_6_VAL6_SHIFT, - PCE_TBL_VAL_6_VAL6_SIZE, rdata->val[6]); - gsw_w32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, - PCE_TBL_VAL_5_VAL5_SHIFT, - PCE_TBL_VAL_5_VAL5_SIZE, rdata->val[5]); - gsw_w32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, - PCE_TBL_VAL_4_VAL4_SHIFT, - PCE_TBL_VAL_4_VAL4_SIZE, rdata->val[4]); - gsw_w32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, - PCE_TBL_VAL_3_VAL3_SHIFT, - PCE_TBL_VAL_3_VAL3_SIZE, rdata->val[3]); - gsw_w32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, - PCE_TBL_VAL_2_VAL2_SHIFT, - PCE_TBL_VAL_2_VAL2_SIZE, rdata->val[2]); - gsw_w32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, - PCE_TBL_VAL_1_VAL1_SHIFT, - PCE_TBL_VAL_1_VAL1_SIZE, rdata->val[1]); - gsw_w32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, - PCE_TBL_VAL_0_VAL0_SHIFT, - PCE_TBL_VAL_0_VAL0_SIZE, rdata->val[0]); - gsw_w32(cdev, PCE_RTBL_CTRL_VLD_OFFSET, - PCE_RTBL_CTRL_VLD_SHIFT, - PCE_RTBL_CTRL_VLD_SIZE, rdata->valid); - gsw_w32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, 1); - do { - gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, - PCE_RTBL_CTRL_BAS_SHIFT, - PCE_RTBL_CTRL_BAS_SIZE, &value); - } while (value != 0); - gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); - return GSW_statusOk; -} /* Static Function Declaration */ static int rt_tbl_write(void *tstart, u16 *rcnt, - void *rpar, u32 ts, u32 tentry) + void *rpar, u32 ts, u32 tentry) { int i; -/* search if the entry is already available and can be re-used */ + + /* search if the entry is already available and can be re-used */ for (i = 0; i < tentry; i++) { /* entry is used, check if the entry content fits */ if (rcnt[i] > 0) { if (memcmp((((char *)tstart) + i * ts), - rpar, (u8)ts) == 0) { + rpar, (u8)ts) == 0) { rcnt[i]++; return i; } } } + /* find an empty entry and add information */ for (i = 0; i < tentry; i++) { if (rcnt[i] == 0) { @@ -346,36 +45,40 @@ static int rt_tbl_write(void *tstart, u16 *rcnt, return i; } } + /* table is full, return an error */ return -1; } static int sw_ip_tbl_write(void *tstart, u16 *rcnt, - void *rpar, u32 ts, u32 tnum, int start) + void *rpar, u32 ts, u32 tnum, int start) { int i = 0; + /* search if the entry is already available and can be re-used */ if (start == 0) { for (i = 0; i < tnum; i++) { if ((rcnt[i] > 0)) { if (memcmp((((char *)tstart) + i * ts), - rpar, (u8)ts) == 0) { + rpar, (u8)ts) == 0) { rcnt[i]++; return i; } } } + /* find an empty entry and add information */ for (i = 0; i < tnum;) { char *abc = ((char *)tstart + (i * sizeof(riptbl_t))); riptbl_t *itbl = (riptbl_t *)abc; + if (((i % 4) == 0) && (itbl->itype == GSW_RT_IP_V6) - && (itbl->valid == 1)) { + && (itbl->valid == 1)) { i += 4; } else { if (rcnt[i] == 0) { memcpy((((char *)tstart) + i * ts), - rpar, (u8)ts); + rpar, (u8)ts); rcnt[i]++; return i; } else { @@ -388,42 +91,46 @@ static int sw_ip_tbl_write(void *tstart, u16 *rcnt, /* entry is used, check if the entry content fits */ if (rcnt[i] > 0) { if (memcmp((((char *)tstart) + i * ts), - rpar, (u8)ts) == 0) { + rpar, (u8)ts) == 0) { rcnt[i]++; return i; } } } + /* find an empty entry and add information */ for (i = 0; i < tnum; i += 4) { - if (rcnt[i] == 0 && rcnt[i+1] == 0 - && rcnt[i+2] == 0 && rcnt[i+3] == 0) { + if (rcnt[i] == 0 && rcnt[i + 1] == 0 + && rcnt[i + 2] == 0 && rcnt[i + 3] == 0) { memcpy((((char *)tstart) + i * ts), - rpar, (u8)ts); + rpar, (u8)ts); rcnt[i]++; return i; } } } + /* table is full, return an error */ return -1; } static int sw_mac_tbl_write(void *tstart, u16 *rcnt, - void *rpar, u32 ts, u32 tentry) + void *rpar, u32 ts, u32 tentry) { int i; + /* search if the entry is already available and can be re-used */ for (i = 1; i < tentry; i++) { if (rcnt[i] > 0) { /* entry is used, check if the entry content fits */ if (memcmp((((char *)tstart) + i * ts), - rpar, (u8)ts) == 0) { + rpar, (u8)ts) == 0) { rcnt[i]++; return i; } } } + /* find an empty entry and add information */ for (i = 1; i < tentry; i++) { if (rcnt[i] == 0) { @@ -432,20 +139,23 @@ static int sw_mac_tbl_write(void *tstart, u16 *rcnt, return i; } } + /* table is full, return an error */ return -1; } static int get_rt_tbl_index(void *tstart, void *rpar, - u32 ts, u32 tentry) + u32 ts, u32 tentry) { int i; + /* search if the entry is already available and can be re-used */ for (i = 0; i < tentry; i++) { /* entry is used, check if the entry content fits */ if (memcmp(((char *)tstart) + i * ts, rpar, (u8)ts) == 0) return i; } + return 0x7FFF; } @@ -453,11 +163,11 @@ static int get_rt_tbl_index(void *tstart, void *rpar, int find_ip_tbl_entry(rt_table_handle_t *tm, riptbl_t *rpar) { return get_rt_tbl_index(tm->rt_ip_tbl, rpar, - sizeof(riptbl_t), RT_IP_TBL_SIZE); + sizeof(riptbl_t), RT_IP_TBL_SIZE); } static int rt_iptable_rd(void *cdev, - int index, riptbl_t *rpar) + int index, riptbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -467,22 +177,25 @@ static int rt_iptable_rd(void *cdev, ptable.pcindex = index; ptable.op_mode = OPMOD_IPv4_READ; route_table_read(cdev, &ptable); + if ((ptable.val[8] >> 15) & 0x1) { rpar->itype = GSW_RT_IP_V6; + for (i = 0; i < 8; i++) rpar->iaddr.i6addr[i] = (ptable.val[i] & 0xFFFF); } else { rpar->itype = GSW_RT_IP_V4; - rpar->iaddr.i4addr[0] = (ptable.val[0] & 0xFF); - rpar->iaddr.i4addr[1] = ((ptable.val[0] >> 8) & 0xFF); - rpar->iaddr.i4addr[2] = (ptable.val[1] & 0xFF); - rpar->iaddr.i4addr[3] = ((ptable.val[1] >> 8) & 0xFF); + rpar->iaddr.i4addr[0] = (ptable.val[0] & 0xFF); + rpar->iaddr.i4addr[1] = ((ptable.val[0] >> 8) & 0xFF); + rpar->iaddr.i4addr[2] = (ptable.val[1] & 0xFF); + rpar->iaddr.i4addr[3] = ((ptable.val[1] >> 8) & 0xFF); } + return GSW_statusOk; } static int rt_iptable_wr(void *cdev, - int index, riptbl_t *rpar) + int index, riptbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -490,68 +203,78 @@ static int rt_iptable_wr(void *cdev, memset(&ptable, 0, sizeof(ptable)); ptable.table = PCE_R_IP_INDEX; ptable.pcindex = index; + if (rpar->itype == GSW_RT_IP_V4) { ptable.op_mode = OPMOD_IPv4_WRITE; ptable.val[0] = ((rpar->iaddr.i4addr[0]) - | (rpar->iaddr.i4addr[1] << 8)); + | (rpar->iaddr.i4addr[1] << 8)); ptable.val[1] = ((rpar->iaddr.i4addr[2]) - | (rpar->iaddr.i4addr[3] << 8)); + | (rpar->iaddr.i4addr[3] << 8)); ptable.val[8] &= ~(1 << 15); } else if (rpar->itype == GSW_RT_IP_V6) { ptable.pcindex = index & 0xFFFC; ptable.op_mode = OPMOD_IPv4_WRITE; + for (i = 0, j = 7; i < 8; i++, j--) ptable.val[i] = (rpar->iaddr.i6addr[j] & 0xFFFF); + ptable.val[8] &= ~(1 << 15); ptable.val[8] |= (1 << 15); } + route_table_write(cdev, &ptable); return GSW_statusOk; } /* Routing IP Table */ static int rt_ip_tbl_write(void *cdev, - rt_table_handle_t *rtbl, riptbl_t *rpar) + rt_table_handle_t *rtbl, riptbl_t *rpar) { int pcindex = -1; + if (rpar->itype == GSW_RT_IP_V4) { pcindex = sw_ip_tbl_write(rtbl->rt_ip_tbl, - rtbl->rt_ip_tbl_cnt, rpar, - sizeof(riptbl_t), RT_IP_TBL_SIZE, 0); + rtbl->rt_ip_tbl_cnt, rpar, + sizeof(riptbl_t), RT_IP_TBL_SIZE, 0); } else if (rpar->itype == GSW_RT_IP_V6) { pcindex = sw_ip_tbl_write(rtbl->rt_ip_tbl, - rtbl->rt_ip_tbl_cnt, rpar, - sizeof(riptbl_t), RT_IP_TBL_SIZE, 1); + rtbl->rt_ip_tbl_cnt, rpar, + sizeof(riptbl_t), RT_IP_TBL_SIZE, 1); } + if (pcindex < 0) return -1; + rt_iptable_wr(cdev, pcindex, rpar); return pcindex; } /* IP DA/SA lsb Table delete */ static int rt_ip_tbl_delete(void *cdev, - rt_table_handle_t *rtbl, int index) + rt_table_handle_t *rtbl, int index) { pctbl_prog_t ptable; RT_ASSERT(index >= RT_IP_TBL_SIZE); + if (rtbl->rt_ip_tbl_cnt[index] > 0) rtbl->rt_ip_tbl_cnt[index]--; + if (rtbl->rt_ip_tbl_cnt[index] == 0) { memset((((char *)rtbl->rt_ip_tbl) + (index * sizeof(riptbl_t))), - 0, sizeof(riptbl_t)); + 0, sizeof(riptbl_t)); memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_IP_INDEX; ptable.op_mode = OPMOD_IPv4_WRITE; ptable.pcindex = index; route_table_write(cdev, &ptable); } + return 0; } static int rt_mtutable_wr(void *cdev, u16 index, - rt_mtu_tbl_t *rpar) + rt_mtu_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -566,41 +289,46 @@ static int rt_mtutable_wr(void *cdev, u16 index, /* MTU Table Write */ static int rt_mtu_tbl_write(void *cdev, - rt_table_handle_t *rtbl, rt_mtu_tbl_t *rpar) + rt_table_handle_t *rtbl, rt_mtu_tbl_t *rpar) { int pcindex; pcindex = rt_tbl_write(rtbl->rt_mtu_tbl, rtbl->rt_mtu_tbl_cnt, - rpar, sizeof(rt_mtu_tbl_t), RT_MTU_TBL_SIZE); + rpar, sizeof(rt_mtu_tbl_t), RT_MTU_TBL_SIZE); + if (pcindex < 0) return -1; + rt_mtutable_wr(cdev, pcindex, rpar); return pcindex; } /* MTU Table Delete */ static int rt_mtu_tbl_delete(void *cdev, - rt_table_handle_t *rtbl, u32 index) + rt_table_handle_t *rtbl, u32 index) { pctbl_prog_t ptable; RT_ASSERT(index >= RT_MTU_TBL_SIZE); + if (rtbl->rt_mtu_tbl_cnt[index] > 0) rtbl->rt_mtu_tbl_cnt[index]--; + if (rtbl->rt_mtu_tbl_cnt[index] == 0) { memset((((char *)rtbl->rt_mtu_tbl) + - (index * sizeof(rt_mtu_tbl_t))), - 0, sizeof(rt_mtu_tbl_t)); + (index * sizeof(rt_mtu_tbl_t))), + 0, sizeof(rt_mtu_tbl_t)); memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_MTU_INDEX; ptable.op_mode = OPMOD_ADDRESS_WRITE; ptable.pcindex = index; route_table_write(cdev, &ptable); } + return 0; } static int rt_mtutable_rd(void *cdev, - u16 index, rt_mtu_tbl_t *rpar) + u16 index, rt_mtu_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -614,7 +342,7 @@ static int rt_mtutable_rd(void *cdev, } static int rt_mactable_wr(void *cdev, int index, - rt_mac_tbl_t *rpar) + rt_mac_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -631,33 +359,36 @@ static int rt_mactable_wr(void *cdev, int index, /* MAC DA/SA Table index write */ static int rt_mac_tbl_write(void *cdev, - rt_table_handle_t *rtbl, rt_mac_tbl_t *rpar) + rt_table_handle_t *rtbl, rt_mac_tbl_t *rpar) { int pcindex; pcindex = sw_mac_tbl_write(rtbl->rt_mac_tbl, - rtbl->rt_mac_tbl_cnt, rpar, - sizeof(rt_mac_tbl_t), RT_MAC_TBL_SIZE); + rtbl->rt_mac_tbl_cnt, rpar, + sizeof(rt_mac_tbl_t), RT_MAC_TBL_SIZE); + if (pcindex < 0) return -1; + rt_mactable_wr(cdev, pcindex, rpar); return pcindex; } /* MAC DA/SA Table delete */ static int rt_mac_tbl_delete(void *cdev, - rt_table_handle_t *rtbl, u32 index) + rt_table_handle_t *rtbl, u32 index) { pctbl_prog_t ptable; RT_ASSERT(index >= RT_MAC_TBL_SIZE); + if (rtbl->rt_mac_tbl_cnt[index] > 0) rtbl->rt_mac_tbl_cnt[index]--; if (rtbl->rt_mac_tbl_cnt[index] == 0) { memset((((char *)rtbl->rt_mac_tbl) + - (index * sizeof(rt_mac_tbl_t))), - 0, sizeof(rt_mac_tbl_t)); + (index * sizeof(rt_mac_tbl_t))), + 0, sizeof(rt_mac_tbl_t)); /* initialize the data structure before using it */ memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_MAC_INDEX; @@ -665,11 +396,12 @@ static int rt_mac_tbl_delete(void *cdev, ptable.pcindex = index; route_table_write(cdev, &ptable); } + return 0; } static int rt_mactable_rd(void *cdev, - int index, rt_mac_tbl_t *rpar) + int index, rt_mac_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -688,7 +420,7 @@ static int rt_mactable_rd(void *cdev, } static int rt_ppoetable_rd(void *cdev, - int index, rt_ppoe_tbl_t *rpar) + int index, rt_ppoe_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -703,7 +435,7 @@ static int rt_ppoetable_rd(void *cdev, } static int rt_ppoetable_wr(void *cdev, - int index, rt_ppoe_tbl_t *rpar) + int index, rt_ppoe_tbl_t *rpar) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -720,37 +452,42 @@ static int rt_ppoetable_wr(void *cdev, /* PPPoE Table Write */ static int rt_pppoe_tbl_write(void *cdev, - rt_table_handle_t *rtbl, rt_ppoe_tbl_t *rpar) + rt_table_handle_t *rtbl, rt_ppoe_tbl_t *rpar) { int pcindex; pcindex = rt_tbl_write(rtbl->rt_ppoe_tbl, - rtbl->rt_ppoe_tbl_cnt, - rpar, sizeof(rt_ppoe_tbl_t), RT_PPPOE_TBL_SIZE); + rtbl->rt_ppoe_tbl_cnt, + rpar, sizeof(rt_ppoe_tbl_t), RT_PPPOE_TBL_SIZE); + if (pcindex < 0) return -1; + rt_ppoetable_wr(cdev, pcindex, rpar); return pcindex; } /* PPPoE Table Delete */ static int rt_pppoe_tbl_delete(void *cdev, - rt_table_handle_t *rtbl, u32 index) + rt_table_handle_t *rtbl, u32 index) { pctbl_prog_t ptable; RT_ASSERT(index >= RT_PPPOE_TBL_SIZE); + if (rtbl->rt_ppoe_tbl_cnt[index] > 0) rtbl->rt_ppoe_tbl_cnt[index]--; + if (rtbl->rt_ppoe_tbl_cnt[index] == 0) { memset((((char *)rtbl->rt_ppoe_tbl) + - (index * sizeof(rt_ppoe_tbl_t))), - 0, sizeof(rt_ppoe_tbl_t)); + (index * sizeof(rt_ppoe_tbl_t))), + 0, sizeof(rt_ppoe_tbl_t)); memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_PPPOE_INDEX; ptable.op_mode = OPMOD_ADDRESS_WRITE; ptable.pcindex = index; route_table_write(cdev, &ptable); } + return 0; } @@ -769,61 +506,8 @@ static int rt_rtptable_cnt_clr(void *cdev, int index) return GSW_statusOk; } -#if 0 -static int rt_rtptable_wr(void *cdev, int index, - rt_rtp_tbl_t *rtptableentry) -{ - /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ - pctbl_prog_t ptable; - - memset(&ptable, 0, sizeof(ptable)); - ptable.table = PCE_R_RTP_INDEX; - ptable.pcindex = index; - ptable.op_mode = OPMOD_ADDRESS_WRITE; - ptable.val[0] = rtptableentry->rtpseqnum; - ptable.val[1] = rtptableentry->rtpsespcnt; - route_table_write(cdev, &ptable); - return GSW_statusOk; -} -/* RTP Table Write */ -static int rt_rtp_tbl_write(void *cdev, - rt_table_handle_t *rtbl, rt_rtp_tbl_t *rpar) -{ - int pcindex; - pcindex = rt_tbl_write(rtbl->rt_rtp_tbl, - rtbl->rt_rtp_tbl_cnt, - rpar, sizeof(rt_rtp_tbl_t), RT_RTP_TBL_SIZE); - if (pcindex < 0) - return -1; - rt_rtptable_wr(cdev, pcindex, rpar); - return pcindex; -} - -/* RTP Table Delete */ -static int rt_rtp_tbl_delete(void *cdev, - rt_table_handle_t *rtbl, u32 index) -{ - pctbl_prog_t ptable; - - RT_ASSERT(index >= RT_RTP_TBL_SIZE); - if (rtbl->rt_rtp_tbl_cnt[index] > 0) - rtbl->rt_rtp_tbl_cnt[index]--; - if (rtbl->rt_rtp_tbl_cnt[index] == 0) { - memset((((char *)rtbl->rt_rtp_tbl) + - (index * sizeof(rt_rtp_tbl_t))), - 0, sizeof(rt_rtp_tbl_t)); - memset(&ptable, 0, sizeof(pctbl_prog_t)); - ptable.table = PCE_R_RTP_INDEX; - ptable.op_mode = OPMOD_ADDRESS_WRITE; - ptable.pcindex = index; - route_table_write(cdev, &ptable); - } - return 0; -} -#endif - static int rt_rtptable_rd(void *cdev, int index, - rt_rtp_tbl_t *rtptableentry) + rt_rtp_tbl_t *rtptableentry) { /*ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev);*/ pctbl_prog_t ptable; @@ -833,7 +517,7 @@ static int rt_rtptable_rd(void *cdev, int index, ptable.pcindex = index; ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); - rtptableentry->rtpseqnum = ptable.val[1]; //swapped in hw implementation + rtptableentry->rtpseqnum = ptable.val[1]; //swapped in hw implementation rtptableentry->rtpsespcnt = ptable.val[0]; //swapped in hw impementation return GSW_statusOk; } @@ -841,18 +525,22 @@ static int rt_rtptable_rd(void *cdev, int index, int calhash(const u8 *data, size_t len) { int crc = 0, i; + if (len) do { - crc ^= ((*data)<<8); + crc ^= ((*data) << 8); data++; + for (i = 0; i < 8; i++) { if (crc & 0x8000) crc = (crc << 1) ^ 0x1021; else crc <<= 1; + crc = crc & 0xFFFF; } } while (--len); + return crc; } @@ -860,42 +548,52 @@ int pae_hash_index(GSW_ROUTE_Entry_t *rpar) { u8 hdata[13] = {0}; int i, j, hashc; + if (rpar->routeEntry.pattern.eIpType == GSW_RT_IP_V4) { for (i = 0; i < 4; i++) hdata[i] = - ((rpar->routeEntry.pattern.nSrcIP.nIPv4 >> - ((3-i) * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nSrcIP.nIPv4 >> + ((3 - i) * 8)) & 0xFF); + for (i = 0; i < 4; i++) hdata[i + 4] = - ((rpar->routeEntry.pattern.nDstIP.nIPv4 >> - ((3 - i) * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nDstIP.nIPv4 >> + ((3 - i) * 8)) & 0xFF); } else if (rpar->routeEntry.pattern.eIpType == GSW_RT_IP_V6) { u32 ip6data[4]; u32 xdata; + for (i = 0, j = 0; i < 4; i++, j += 2) { ip6data[i] = - ((rpar->routeEntry.pattern.nSrcIP.nIPv6[j] << 16) | - ((rpar->routeEntry.pattern.nSrcIP.nIPv6[j+1]))); + ((rpar->routeEntry.pattern.nSrcIP.nIPv6[j] << 16) | + ((rpar->routeEntry.pattern.nSrcIP.nIPv6[j + 1]))); } + xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); + for (i = 0; i < 4; i++) hdata[i] = ((xdata >> ((3 - i) * 8)) & 0xFF); for (i = 0, j = 0; i < 4; i++, j += 2) { ip6data[i] = - ((rpar->routeEntry.pattern.nDstIP.nIPv6[j] << 16) | - ((rpar->routeEntry.pattern.nDstIP.nIPv6[j+1]))); + ((rpar->routeEntry.pattern.nDstIP.nIPv6[j] << 16) | + ((rpar->routeEntry.pattern.nDstIP.nIPv6[j + 1]))); } + xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); + for (i = 0; i < 4; i++) hdata[i + 4] = ((xdata >> ((3 - i) * 8)) & 0xFF); } + for (i = 0; i < 2; i++) hdata[i + 8] = - ((rpar->routeEntry.pattern.nSrcPort >> ((1-i) * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nSrcPort >> ((1 - i) * 8)) & 0xFF); + for (i = 0; i < 2; i++) hdata[i + 10] = - ((rpar->routeEntry.pattern.nDstPort >> ((1-i) * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nDstPort >> ((1 - i) * 8)) & 0xFF); + hdata[12] = rpar->routeEntry.pattern.nRoutExtId & 0xFF; hashc = calhash(hdata, sizeof(hdata)); @@ -909,12 +607,13 @@ int rt_free_entry(void *cdev, int free_index) memset(&ptable, 0, sizeof(pctbl_prog_t)); rthandler->rstbl.node[free_index].fflag = 1; rthandler->rstbl.nfentries++; + if ((rthandler->rstbl.node[free_index].pprt == -1) && - (rthandler->rstbl.node[free_index].nptr != -1)) { + (rthandler->rstbl.node[free_index].nptr != -1)) { temp2 = rthandler->rstbl.node[free_index].nptr; rthandler->rstbl.node[temp2].pprt = -1; } else if ((rthandler->rstbl.node[free_index].pprt != -1) - && (rthandler->rstbl.node[free_index].nptr == -1)) { + && (rthandler->rstbl.node[free_index].nptr == -1)) { temp1 = rthandler->rstbl.node[free_index].pprt; rthandler->rstbl.node[temp1].nptr = -1; rthandler->rstbl.hw_table[temp1].hwnextptr = temp1; @@ -934,7 +633,7 @@ int rt_free_entry(void *cdev, int free_index) ptable.op_mode = OPMOD_RT_SESSION_NEXT; route_table_write(cdev, &ptable); } else if ((rthandler->rstbl.node[free_index].pprt != -1) - && (rthandler->rstbl.node[free_index].nptr != -1)) { + && (rthandler->rstbl.node[free_index].nptr != -1)) { temp1 = rthandler->rstbl.node[free_index].pprt; temp2 = rthandler->rstbl.node[free_index].nptr; rthandler->rstbl.node[temp2].pprt = temp1; @@ -946,7 +645,7 @@ int rt_free_entry(void *cdev, int free_index) ptable.pcindex = temp1; ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); - + ptable.table = PCE_R_SESSION_INDEX; ptable.pcindex = temp1; ptable.valid = 1; @@ -956,6 +655,7 @@ int rt_free_entry(void *cdev, int free_index) ptable.op_mode = OPMOD_RT_SESSION_NEXT; route_table_write(cdev, &ptable); } + if (rthandler->rstbl.nfentries <= 1) { rthandler->rstbl.ffptr = free_index; rthandler->rstbl.lfptr = free_index; @@ -968,6 +668,7 @@ int rt_free_entry(void *cdev, int free_index) rthandler->rstbl.node[temp1].nptr = free_index; rthandler->rstbl.node[free_index].nptr = -1; } + rthandler->rstbl.hw_table[free_index].hwnextptr = free_index; rthandler->rstbl.hw_table[free_index].hwvalid = 0; memset(&ptable, 0, sizeof(pctbl_prog_t)); @@ -992,13 +693,15 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); pctbl_prog_t ptable; int hindex, tab_index, i, index, retval = GSW_statusErr; - int sindex, dindex, aindex, smindex, dmindex, ppindex, tuindex,rrindex, mtindex = 0xFF; + int sindex, dindex, aindex, smindex, dmindex, ppindex, tuindex, rrindex, mtindex = 0xFF; riptbl_t dstip, srcip; rt_mtu_tbl_t mtval; + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { if (rpar->nHashVal < 0) { /* calculate hash index */ @@ -1006,25 +709,30 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) } else { hindex = rpar->nHashVal; } + index = hindex; memset(&ptable, 0, sizeof(pctbl_prog_t)); tab_index = 0x7FFF; sindex = tab_index; dindex = tab_index; aindex = tab_index; + if (rpar->routeEntry.pattern.eIpType == GSW_RT_IP_V4) { memset(&dstip, 0, sizeof(riptbl_t)); memset(&srcip, 0, sizeof(riptbl_t)); dstip.itype = GSW_RT_IP_V4; srcip.itype = GSW_RT_IP_V4; + for (i = 0; i < 4; i++) { dstip.iaddr.i4addr[i] = - ((rpar->routeEntry.pattern.nDstIP.nIPv4 >> (i * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nDstIP.nIPv4 >> (i * 8)) & 0xFF); srcip.iaddr.i4addr[i] = - ((rpar->routeEntry.pattern.nSrcIP.nIPv4 >> (i * 8)) & 0xFF); + ((rpar->routeEntry.pattern.nSrcIP.nIPv4 >> (i * 8)) & 0xFF); } + dstip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &dstip); + if (tab_index < 0) return GSW_ROUTE_ERROR_IP_FULL; else @@ -1034,11 +742,11 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) srcip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &srcip); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_IP_FULL; goto errexit1; - } - else + } else dindex = tab_index; ptable.key[1] = (tab_index & 0x7FF); @@ -1047,12 +755,15 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) memset(&srcip, 0, sizeof(riptbl_t)); dstip.itype = GSW_RT_IP_V6; srcip.itype = GSW_RT_IP_V6; + for (i = 0; i < 8; i++) { dstip.iaddr.i6addr[i] = (rpar->routeEntry.pattern.nDstIP.nIPv6[i]); srcip.iaddr.i6addr[i] = (rpar->routeEntry.pattern.nSrcIP.nIPv6[i]); } + dstip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &dstip); + if (tab_index < 0) return GSW_ROUTE_ERROR_IP_FULL; else @@ -1061,17 +772,19 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) ptable.key[0] = (tab_index & 0x7FF); srcip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &srcip); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_IP_FULL; goto errexit1; - } - else + } else dindex = tab_index; + ptable.key[1] = (tab_index & 0x7FF); } else { ptable.key[0] = (tab_index & 0x7FF); ptable.key[1] = (tab_index & 0x7FF); } + ptable.key[2] = rpar->routeEntry.pattern.nDstPort; ptable.key[3] = rpar->routeEntry.pattern.nSrcPort; ptable.key[4] = rpar->routeEntry.pattern.nRoutExtId & 0xFF; @@ -1082,34 +795,40 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) /* New IP Address Index */ tab_index = 0x7FFF; + if (rpar->routeEntry.action.eIpType == GSW_RT_IP_V4) { memset(&dstip, 0, sizeof(riptbl_t)); dstip.itype = GSW_RT_IP_V4; + for (i = 0; i < 4; i++) dstip.iaddr.i4addr[i] = - ((rpar->routeEntry.action.nNATIPaddr.nIPv4 >> (i * 8)) & 0xFF); + ((rpar->routeEntry.action.nNATIPaddr.nIPv4 >> (i * 8)) & 0xFF); + dstip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &dstip); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_IP_FULL; goto errexit2; - } - else + } else aindex = tab_index; } else if (rpar->routeEntry.action.eIpType == GSW_RT_IP_V6) { memset(&dstip, 0, sizeof(riptbl_t)); dstip.itype = GSW_RT_IP_V6; + for (i = 0; i < 8; i++) dstip.iaddr.i6addr[i] = (rpar->routeEntry.action.nNATIPaddr.nIPv6[i]); + dstip.valid = 1; tab_index = rt_ip_tbl_write(cdev, &rthandler->rt_sub_tbl, &dstip); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_IP_FULL; goto errexit2; - } - else + } else aindex = tab_index; } + ptable.val[2] = tab_index & 0x7FF; /* New UDP/TCP Port */ @@ -1122,52 +841,59 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) mtval.valid = 1; mtval.mtsize = (rpar->routeEntry.action.nMTUvalue + 1); tab_index = rt_mtu_tbl_write(cdev, &rthandler->rt_sub_tbl, &mtval); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_MTU_FULL; goto errexit3; - } - else + } else mtindex = tab_index; + ptable.val[4] |= (tab_index & 0x7); - /* New Source MAC Address Index */ + /* New Source MAC Address Index */ if (rpar->routeEntry.action.bMAC_SrcEnable == 1) { rt_mac_tbl_t src_mac_tbl; memset(&src_mac_tbl, 0, sizeof(rt_mac_tbl_t)); - /* Destination MAC address */ + + /* Destination MAC address */ for (i = 0; i < 6; i++) src_mac_tbl.mdata[i] = - rpar->routeEntry.action.nSrcMAC[i]; + rpar->routeEntry.action.nSrcMAC[i]; + src_mac_tbl.valid = 1; tab_index = rt_mac_tbl_write(cdev, &rthandler->rt_sub_tbl, &src_mac_tbl); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_MAC_FULL; goto errexit4; - } - else + } else smindex = tab_index; + ptable.val[4] |= ((tab_index & 0x3FF) << 8); } else { ptable.val[4] |= (0 << 8); smindex = 0; } - /* New Destination MAC Address Index */ + /* New Destination MAC Address Index */ if (rpar->routeEntry.action.bMAC_DstEnable == 1) { rt_mac_tbl_t dst_mac_tbl; memset(&dst_mac_tbl, 0, sizeof(rt_mac_tbl_t)); - /* Destination MAC address */ + + /* Destination MAC address */ for (i = 0; i < 6; i++) dst_mac_tbl.mdata[i] = - rpar->routeEntry.action.nDstMAC[i]; + rpar->routeEntry.action.nDstMAC[i]; + dst_mac_tbl.valid = 1; tab_index = rt_mac_tbl_write(cdev, &rthandler->rt_sub_tbl, &dst_mac_tbl); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_MAC_FULL; goto errexit5; - } - else + } else dmindex = tab_index; + ptable.val[5] = ((tab_index) & 0x3FF); } else { ptable.val[5] = 0; @@ -1176,15 +902,19 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) ptable.val[8] |= rpar->routeEntry.action.nFID & 0x3F; ptable.val[8] |= ((rpar->routeEntry.action.nFlowId & 0xFF) << 8); + if (rpar->routeEntry.action.bInnerDSCPRemark == 1) ptable.val[9] |= rpar->routeEntry.action.nDSCP & 0x3F; + if (rpar->routeEntry.action.bTCremarking == 1) ptable.val[9] |= ((rpar->routeEntry.action.nTrafficClass & 0xF) << 8); -/*ptable.val[10] = rpar->routeEntry.action.nSessionCtrs & 0xFFFF;*/ -/*ptable.val[11] = (rpar->routeEntry.action.nSessionCtrs >> 16) & 0xFFFF;*/ + + /*ptable.val[10] = rpar->routeEntry.action.nSessionCtrs & 0xFFFF;*/ + /*ptable.val[11] = (rpar->routeEntry.action.nSessionCtrs >> 16) & 0xFFFF;*/ ptable.val[10] = 0; ptable.val[11] = 0; + if (rpar->routeEntry.action.eSessDirection == 1) ptable.val[12] |= (1 << 0); else @@ -1195,12 +925,13 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) rt_ppoe_tbl_t sesid; sesid.psesid = rpar->routeEntry.action.nPPPoESessId; tab_index = rt_pppoe_tbl_write(cdev, &rthandler->rt_sub_tbl, &sesid); + if (tab_index < 0) { retval = GSW_ROUTE_ERROR_PPPOE_FULL; goto errexit6; - } - else + } else ppindex = tab_index; + ptable.val[6] |= (tab_index & 0xF); ptable.val[12] |= (1 << 1); } else { @@ -1208,27 +939,15 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) ptable.val[6] |= 0; ppindex = 0xFF; } + if (rpar->routeEntry.action.bRTPMeasEna == 1) { /* Routing RTP Table Index */ rt_rtp_tbl_t rtp_tbl; memset(&rtp_tbl, 0, sizeof(rt_rtp_tbl_t)); -#if 1 + ptable.val[7] |= ((rpar->routeEntry.action.nRTPSeqNumber & 0x3F) << 8); rt_rtptable_cnt_clr(cdev, (rpar->routeEntry.action.nRTPSeqNumber & 0x3F)); -#else - rtp_tbl.rtpseqnum = - rpar->routeEntry.action.nRTPSeqNumber; - rtp_tbl.rtpsespcnt = - rpar->routeEntry.action.nRTPSessionPktCnt; - tab_index = rt_rtp_tbl_write(cdev, &rthandler->rt_sub_tbl, &rtp_tbl); - if (tab_index < 0) { - retval = GSW_ROUTE_ERROR_RTP_FULL; - goto errexit; - } - else - rrindex = tab_index; - ptable.val[7] |= (tab_index << 8); -#endif + ptable.val[12] |= (1 << 11); } else { ptable.val[12] &= ~(1 << 11); @@ -1237,19 +956,24 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) } switch (rpar->routeEntry.action.eSessRoutingMode) { - ptable.val[12] &= ~(3 << 2); + ptable.val[12] &= ~(3 << 2); + case GSW_ROUTE_MODE_NULL: ptable.val[12] |= (0 << 2); break; + case GSW_ROUTE_MODE_ROUTING: ptable.val[12] |= (1 << 2); break; + case GSW_ROUTE_MODE_NAT: ptable.val[12] |= (2 << 2); break; + case GSW_ROUTE_MODE_NAPT: ptable.val[12] |= (3 << 2); break; + default: ptable.val[12] |= (0 << 2); } @@ -1257,31 +981,39 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) /* Tunnel Index */ if (rpar->routeEntry.action.bTunnel_Enable == 1) { ptable.val[12] &= ~(3 << 4); + switch (rpar->routeEntry.action.eTunType) { case GSW_ROUTE_TUNL_NULL: ptable.val[12] |= (0 << 4); break; + case GSW_ROUTE_TUNL_6RD: ptable.val[12] |= (1 << 4); break; + case GSW_ROUTE_TUNL_DSLITE: ptable.val[12] |= (2 << 4); break; + case GSW_ROUTE_TUNL_L2TP: if (rpar->routeEntry.pattern.eIpType == GSW_RT_IP_V4) { ptable.val[12] |= (2 << 4); } else if (rpar->routeEntry.pattern.eIpType == GSW_RT_IP_V6) { ptable.val[12] |= (1 << 4); } + break; + case GSW_ROUTE_TUNL_IPSEC: ptable.val[12] |= (3 << 4); break; + default: ptable.val[12] |= (0 << 4); } + ptable.val[6] |= - ((rpar->routeEntry.action.nTunnelIndex & 0xF) << 8); + ((rpar->routeEntry.action.nTunnelIndex & 0xF) << 8); tuindex = rpar->routeEntry.action.nTunnelIndex; } else { ptable.val[6] |= (0 << 8); @@ -1289,19 +1021,24 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) } switch (rpar->routeEntry.action.eOutDSCPAction) { - ptable.val[12] &= ~(3 << 6); + ptable.val[12] &= ~(3 << 6); + case GSW_ROUTE_OUT_DSCP_NULL: ptable.val[12] |= (0 << 6); break; + case GSW_ROUTE_OUT_DSCP_INNER: ptable.val[12] |= (1 << 6); break; + case GSW_ROUTE_OUT_DSCP_SESSION: ptable.val[12] |= (2 << 6); break; + case GSW_ROUTE_OUT_DSCP_RES: ptable.val[12] |= (3 << 6); break; + default: ptable.val[12] |= (0 << 6); } @@ -1310,10 +1047,12 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) ptable.val[12] |= (1 << 8); else ptable.val[12] &= ~(1 << 8); + if (rpar->routeEntry.action.bTCremarking == 1) ptable.val[12] |= (1 << 9); else ptable.val[12] &= ~(1 << 9); + if (rpar->routeEntry.action.bMeterAssign == 1) { ptable.val[12] |= (1 << 10); ptable.val[7] = rpar->routeEntry.action.nMeterId & 0x3F; @@ -1330,192 +1069,217 @@ int GSW_ROUTE_SessionEntryAdd(void *cdev, GSW_ROUTE_Entry_t *rpar) else ptable.val[12] &= ~(1 << 15); - { - int step = 0, success = 0; + { + int step = 0, success = 0; start: - if (rthandler->rstbl.node[index].vflag == 1) { - /* If entry is valid , check its next */ - /* entry in the search link list*/ - if (rthandler->rstbl.node[index].nptr == -1) { - /* This entry is the last node of the */ - /* search link list*/ - if (rthandler->rstbl.nfentries == 0) { - /* if no free entry, cannot add this session. */ - if (rpar->bPrio == 1) { - goto errexit; - retval = GSW_ROUTE_F_SWAP_OUT_ERR /*GSW_ROUTE_F_SWAP_OUT*/; + + if (rthandler->rstbl.node[index].vflag == 1) { + /* If entry is valid , check its next */ + /* entry in the search link list*/ + if (rthandler->rstbl.node[index].nptr == -1) { + /* This entry is the last node of the */ + /* search link list*/ + if (rthandler->rstbl.nfentries == 0) { + /* if no free entry, cannot add this session. */ + if (rpar->bPrio == 1) { + goto errexit; + retval = GSW_ROUTE_F_SWAP_OUT_ERR /*GSW_ROUTE_F_SWAP_OUT*/; + } else { + goto errexit; + retval = GSW_ROUTE_ERROR_RT_SESS_FULL; + } } else { - goto errexit; - retval = GSW_ROUTE_ERROR_RT_SESS_FULL; + int temp; + success = 1; + /* Get free entry from the head of the free link list , add this session. */ + rthandler->rstbl.node[hindex].nventries++; + temp = index; + index = rthandler->rstbl.ffptr; + rthandler->rstbl.node[index].hval = hindex; /* Store the hash value*/ + rthandler->rstbl.node[index].vflag = 1; + /* TODO: Session info add for a index */ + rthandler->rstbl.nfentries--; + rthandler->rstbl.nuentries++; + rthandler->rstbl.ffptr = rthandler->rstbl.node[index].nptr; + rthandler->rstbl.node[index].fflag = 0; + rthandler->rstbl.node[index].prio = rpar->bPrio; + rthandler->rstbl.node[temp].nptr = index; + rthandler->rstbl.node[index].pprt = temp; + rthandler->rstbl.node[index].nptr = -1; + /* Update the HW table */ + /* Add this session to hardware table. It is last node of*/ + /* this search link list. */ + rthandler->rstbl.hw_table[index].hwvalid = 1; + rthandler->rstbl.hw_table[index].hwnextptr = index; + ptable.table = PCE_R_SESSION_INDEX; + ptable.pcindex = index; + ptable.valid = rthandler->rstbl.hw_table[index].hwvalid; + ptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; + ptable.key[4] &= ~(1 << 15); + ptable.key[4] |= ((rthandler->rstbl.hw_table[index].hwvalid) << 15); + ptable.op_mode = OPMOD_ADDRESS_WRITE; + route_table_write(cdev, &ptable); + rpar->nRtIndex = index; + /* Update the HW temp entry table */ + /* Link previous entry to this new entry. */ + /*rthandler->rstbl.hw_table[temp].hwvalid = 1;*/ + rthandler->rstbl.hw_table[temp].hwnextptr = index; + memset(&ptable, 0, sizeof(pctbl_prog_t)); + ptable.table = PCE_R_SESSION_INDEX; + ptable.pcindex = temp; + ptable.op_mode = OPMOD_ADDRESS_READ; + route_table_read(cdev, &ptable); + + ptable.table = PCE_R_SESSION_INDEX; + ptable.pcindex = temp; //rthandler->rstbl.hw_table[temp].hwnextptr; + ptable.valid = rthandler->rstbl.hw_table[temp].hwvalid; + ptable.key[5] = rthandler->rstbl.hw_table[temp].hwnextptr; + ptable.key[4] &= ~(1 << 15); + ptable.key[4] |= ((rthandler->rstbl.hw_table[temp].hwvalid) << 15); + ptable.op_mode = OPMOD_RT_SESSION_NEXT; + route_table_write(cdev, &ptable); + + if (index == -1) + pr_err(" *SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); + + /* rpar->nRtIndex = index;*/ + return success; } } else { - int temp; - success = 1; - /* Get free entry from the head of the free link list , add this session. */ - rthandler->rstbl.node[hindex].nventries++; - temp = index; - index = rthandler->rstbl.ffptr; - rthandler->rstbl.node[index].hval = hindex; /* Store the hash value*/ - rthandler->rstbl.node[index].vflag = 1; - /* TODO: Session info add for a index */ - rthandler->rstbl.nfentries--; - rthandler->rstbl.nuentries++; - rthandler->rstbl.ffptr = rthandler->rstbl.node[index].nptr; + /* Move to the next node of the search link list until the last node*/ + /*or search step is greater than 15.*/ + step++; + + if (step >= 15) { + if (rpar->bPrio == 1) { + goto errexit; + retval = GSW_ROUTE_F_SWAP_OUT_ERR /*GSW_ROUTE_F_SWAP_OUT*/; + } else { + goto errexit; + retval = GSW_ROUTE_ERROR_RT_COLL_FULL; + } + } else { + index = rthandler->rstbl.node[index].nptr; + goto start; + } + } + } else { + success = 1; + /* If entry is not valid, can add the new session to this entry. */ + rthandler->rstbl.node[hindex].nventries++; + rthandler->rstbl.node[index].hval = hindex; /* Store the hash value*/ + rthandler->rstbl.node[index].vflag = 1; + rthandler->rstbl.node[index].prio = rpar->bPrio; + rthandler->rstbl.nuentries++; + + /* TODO: Add Pattern */ + if (rthandler->rstbl.node[index].fflag == 1) { + /* If this entry is free entry, */ + /* remove it from free link list. */ rthandler->rstbl.node[index].fflag = 0; - rthandler->rstbl.node[index].prio = rpar->bPrio; - rthandler->rstbl.node[temp].nptr = index; - rthandler->rstbl.node[index].pprt = temp; + rthandler->rstbl.nfentries--; + + if (index == rthandler->rstbl.ffptr) { + rthandler->rstbl.ffptr = rthandler->rstbl.node[index].nptr; + } else { + if (index == rthandler->rstbl.lfptr) { + rthandler->rstbl.lfptr = rthandler->rstbl.node[index].pprt; + } else { + int temp1, temp2; + temp1 = rthandler->rstbl.node[index].pprt; + temp2 = rthandler->rstbl.node[index].nptr; + rthandler->rstbl.node[temp2].pprt = temp1; + rthandler->rstbl.node[temp1].nptr = temp2; + } + } + + /* This entry is the single node for this hash. */ + rthandler->rstbl.node[index].pprt = -1; rthandler->rstbl.node[index].nptr = -1; - /* Update the HW table */ - /* Add this session to hardware table. It is last node of*/ - /* this search link list. */ + /* Update the hardware data structure. This is the single node for */ + /* this search link list add this session to hardware table. */ + /* It is last node of this search link list. */ rthandler->rstbl.hw_table[index].hwvalid = 1; rthandler->rstbl.hw_table[index].hwnextptr = index; - ptable.table = PCE_R_SESSION_INDEX; - ptable.pcindex = index; + /* TODO: Session update*/ + ptable.table = PCE_R_SESSION_INDEX; + ptable.pcindex = index; ptable.valid = rthandler->rstbl.hw_table[index].hwvalid; ptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; ptable.key[4] &= ~(1 << 15); + /*ptable.key[4] |= ((rpar->routeEntry.pattern.bValid & 1) << 15); */ ptable.key[4] |= ((rthandler->rstbl.hw_table[index].hwvalid) << 15); ptable.op_mode = OPMOD_ADDRESS_WRITE; route_table_write(cdev, &ptable); - rpar->nRtIndex = index; - /* Update the HW temp entry table */ - /* Link previous entry to this new entry. */ - /*rthandler->rstbl.hw_table[temp].hwvalid = 1;*/ - rthandler->rstbl.hw_table[temp].hwnextptr = index; - memset(&ptable, 0, sizeof(pctbl_prog_t)); - ptable.table = PCE_R_SESSION_INDEX; - ptable.pcindex = temp; - ptable.op_mode = OPMOD_ADDRESS_READ; - route_table_read(cdev, &ptable); + if (index == -1) + pr_err(" *SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); + + rpar->nRtIndex = index; + return success; + } else { + /* If this entry is not free entry, just update hardware data structure */ + /*to add this session.Next pointer in hardware will be unchanged since */ + /*there are more entries in this search link list. */ + /* Update the HW table */ + /* Add this session to hardware table. It is last node */ + /* of this search link list. */ + rthandler->rstbl.hw_table[index].hwvalid = 1; + /*rthandler->rstbl.hw_table[index].hwnextptr = unchanged */; + /* TODO*/ ptable.table = PCE_R_SESSION_INDEX; - ptable.pcindex = temp; //rthandler->rstbl.hw_table[temp].hwnextptr; - ptable.valid = rthandler->rstbl.hw_table[temp].hwvalid; - ptable.key[5] = rthandler->rstbl.hw_table[temp].hwnextptr; + ptable.pcindex = index; + ptable.valid = rthandler->rstbl.hw_table[index].hwvalid; + ptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; ptable.key[4] &= ~(1 << 15); - ptable.key[4] |= ((rthandler->rstbl.hw_table[temp].hwvalid) << 15); - ptable.op_mode = OPMOD_RT_SESSION_NEXT; + ptable.key[4] |= ((rthandler->rstbl.hw_table[index].hwvalid) << 15); + ptable.op_mode = OPMOD_ADDRESS_WRITE; route_table_write(cdev, &ptable); + if (index == -1) - pr_err(" *SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); -/* rpar->nRtIndex = index;*/ + pr_err(" * SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); + + rpar->nRtIndex = index; return success; } - } else { - /* Move to the next node of the search link list until the last node*/ - /*or search step is greater than 15.*/ - step++; - if (step >= 15) { - if (rpar->bPrio == 1) { - goto errexit; - retval = GSW_ROUTE_F_SWAP_OUT_ERR /*GSW_ROUTE_F_SWAP_OUT*/; - } else { - goto errexit; - retval = GSW_ROUTE_ERROR_RT_COLL_FULL; - } - } else { - index = rthandler->rstbl.node[index].nptr; - goto start; - } - } - } else { - success = 1; - /* If entry is not valid, can add the new session to this entry. */ - rthandler->rstbl.node[hindex].nventries++; - rthandler->rstbl.node[index].hval = hindex; /* Store the hash value*/ - rthandler->rstbl.node[index].vflag = 1; - rthandler->rstbl.node[index].prio = rpar->bPrio; - rthandler->rstbl.nuentries++; - /* TODO: Add Pattern */ - if (rthandler->rstbl.node[index].fflag == 1) { - /* If this entry is free entry, */ - /* remove it from free link list. */ - rthandler->rstbl.node[index].fflag = 0; - rthandler->rstbl.nfentries--; - if (index == rthandler->rstbl.ffptr) { - rthandler->rstbl.ffptr = rthandler->rstbl.node[index].nptr; - } else { - if (index == rthandler->rstbl.lfptr) { - rthandler->rstbl.lfptr = rthandler->rstbl.node[index].pprt; - } else { - int temp1, temp2; - temp1 = rthandler->rstbl.node[index].pprt; - temp2 = rthandler->rstbl.node[index].nptr; - rthandler->rstbl.node[temp2].pprt = temp1; - rthandler->rstbl.node[temp1].nptr = temp2; - } - } - /* This entry is the single node for this hash. */ - rthandler->rstbl.node[index].pprt = -1; - rthandler->rstbl.node[index].nptr = -1; - /* Update the hardware data structure. This is the single node for */ - /* this search link list add this session to hardware table. */ - /* It is last node of this search link list. */ - rthandler->rstbl.hw_table[index].hwvalid = 1; - rthandler->rstbl.hw_table[index].hwnextptr = index; - /* TODO: Session update*/ - ptable.table = PCE_R_SESSION_INDEX; - ptable.pcindex = index; - ptable.valid = rthandler->rstbl.hw_table[index].hwvalid; - ptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; - ptable.key[4] &= ~(1 << 15); - /*ptable.key[4] |= ((rpar->routeEntry.pattern.bValid & 1) << 15); */ - ptable.key[4] |= ((rthandler->rstbl.hw_table[index].hwvalid) << 15); - ptable.op_mode = OPMOD_ADDRESS_WRITE; - route_table_write(cdev, &ptable); - if (index == -1) - pr_err(" *SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); - rpar->nRtIndex = index; - return success; - } else { - /* If this entry is not free entry, just update hardware data structure */ - /*to add this session.Next pointer in hardware will be unchanged since */ - /*there are more entries in this search link list. */ - /* Update the HW table */ - /* Add this session to hardware table. It is last node */ - /* of this search link list. */ - rthandler->rstbl.hw_table[index].hwvalid = 1; - /*rthandler->rstbl.hw_table[index].hwnextptr = unchanged */; - /* TODO*/ - ptable.table = PCE_R_SESSION_INDEX; - ptable.pcindex = index; - ptable.valid = rthandler->rstbl.hw_table[index].hwvalid; - ptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; - ptable.key[4] &= ~(1 << 15); - ptable.key[4] |= ((rthandler->rstbl.hw_table[index].hwvalid) << 15); - ptable.op_mode = OPMOD_ADDRESS_WRITE; - route_table_write(cdev, &ptable); - if (index == -1) - pr_err(" * SW BUG*** %s:%s:%d \n", __FILE__, __func__, __LINE__); - rpar->nRtIndex = index; - return success; } } - } - return GSW_statusOk; + return GSW_statusOk; errexit: + if (ppindex != 0xFF) rt_pppoe_tbl_delete(cdev, &rthandler->rt_sub_tbl, ppindex); + errexit6: + if (dmindex != 0x0) rt_mac_tbl_delete(cdev, &rthandler->rt_sub_tbl, dmindex); + errexit5: + if (smindex != 0x0) rt_mac_tbl_delete(cdev, &rthandler->rt_sub_tbl, smindex); + errexit4: + if (mtindex != 0xFF) rt_mtu_tbl_delete(cdev, &rthandler->rt_sub_tbl, mtindex); + errexit3: + if (aindex != 0x7FFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, aindex); + errexit2: + if (dindex != 0x7FFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, dindex); + errexit1: + if (sindex != 0x7FFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, sindex); + return retval; } else { return GSW_statusErr; @@ -1526,35 +1290,43 @@ int GSW_ROUTE_SessionEntryDel(void *cdev, GSW_ROUTE_Entry_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); int hindex, index; + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; memset(&ptable, 0, sizeof(pctbl_prog_t)); index = rpar->nRtIndex; - if ((index < 0) || (index >= 4096)) + + if ((index < 0) || (index >= 4096)) return GSW_statusErr; + hindex = rthandler->rstbl.node[index].hval; + if (rthandler->rstbl.node[index].vflag == 1) { - rthandler->rstbl.node[index].vflag = 0; - if (rthandler->rstbl.node[hindex].nventries == 0) - pr_err(" ****SW BUG ****: %s:%s:%d, hindex:%d, index:%d\n",__FILE__, __func__, - __LINE__,hindex, index); + rthandler->rstbl.node[index].vflag = 0; + + if (rthandler->rstbl.node[hindex].nventries == 0) + pr_err(" ****SW BUG ****: %s:%s:%d, hindex:%d, index:%d\n", __FILE__, __func__, + __LINE__, hindex, index); + rthandler->rstbl.node[hindex].nventries--; rthandler->rstbl.nuentries--; rthandler->rstbl.node[index].vflag = 0; rthandler->rstbl.node[index].prio = 0; -/* rthandler->rstbl.node[index].fflag = 0;*/ + /* rthandler->rstbl.node[index].fflag = 0;*/ /* Update the HW table*/ rthandler->rstbl.hw_table[index].hwvalid = 0; -/* rthandler->rstbl.hw_table[index].hwnextptr = unchanged; */ + /* rthandler->rstbl.hw_table[index].hwnextptr = unchanged; */ ptable.table = PCE_R_SESSION_INDEX; ptable.pcindex = index; ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); + if (((ptable.key[4] >> 15) & 1) == 1) { pctbl_prog_t rptable; int pcindex; @@ -1564,62 +1336,76 @@ int GSW_ROUTE_SessionEntryDel(void *cdev, GSW_ROUTE_Entry_t *rpar) rptable.op_mode = OPMOD_ADDRESS_WRITE; rptable.valid = 0; rptable.key[5] = rthandler->rstbl.hw_table[index].hwnextptr; - /*rptable.key[4] &= ~((rthandler->rstbl.hw_table[temp].hwvalid) << 15);*/ + /*rptable.key[4] &= ~((rthandler->rstbl.hw_table[temp].hwvalid) << 15);*/ route_table_write(cdev, &rptable); pcindex = (ptable.key[0] & 0xFFF); + if (pcindex != 0xFFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); + pcindex = (ptable.key[1] & 0x7FF); + if (pcindex != 0xFFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); + pcindex = (ptable.val[2] & 0xFFF); + if (pcindex != 0xFFF) rt_ip_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); pcindex = (ptable.val[4] & 0x7); + if (pcindex != 0xF) rt_mtu_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); pcindex = ((ptable.val[4] >> 8) & 0xFF); + if (pcindex != 0x0) rt_mac_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); + pcindex = (ptable.val[5] & 0x1FF); + if (pcindex != 0x0) rt_mac_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); + if ((ptable.val[12] >> 1) & 0x1) { pcindex = (ptable.val[6] & 0xF); rt_pppoe_tbl_delete(cdev, &rthandler->rt_sub_tbl, pcindex); } } + if ((rthandler->rstbl.node[hindex].nventries == 0) && (rthandler->rstbl.node[hindex].vflag == 0)) { rt_free_entry(cdev, hindex); } + if ((rthandler->rstbl.node[index].nventries == 0) && (index != hindex)) { rt_free_entry(cdev, index); } } else { - pr_err(" No entry in the HW:%s:%s:%d, hindex:%d\n",__FILE__, __func__, - __LINE__,rthandler->rstbl.node[index].hval); + pr_err(" No entry in the HW:%s:%s:%d, hindex:%d\n", __FILE__, __func__, + __LINE__, rthandler->rstbl.node[index].hval); } } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_SessionEntryRead(void *cdev, - GSW_ROUTE_Entry_t *rpar) + GSW_ROUTE_Entry_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); u16 index; int i; + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; int hindex, rindex; riptbl_t iptbl; @@ -1648,52 +1434,60 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, \nrthandler->rstbl.lfptr:%d \ \nrthandler->rstbl.hw_table[rindex].hwnextptr:%d \ \nrthandler->rstbl.hw_table[rindex].hwvalid:%d \n", __FILE__, __func__, __LINE__, rindex, hindex, \ - rthandler->rstbl.node[rindex].vflag, \ - rthandler->rstbl.node[rindex].fflag, \ - rthandler->rstbl.node[rindex].nventries, \ - rthandler->rstbl.ffptr, \ - rthandler->rstbl.nfentries, \ - rthandler->rstbl.nuentries, \ - rthandler->rstbl.node[rindex].nptr, \ - rthandler->rstbl.node[rindex].pprt, \ - rthandler->rstbl.lfptr, \ - rthandler->rstbl.hw_table[rindex].hwnextptr, \ - rthandler->rstbl.hw_table[rindex].hwvalid); + rthandler->rstbl.node[rindex].vflag, \ + rthandler->rstbl.node[rindex].fflag, \ + rthandler->rstbl.node[rindex].nventries, \ + rthandler->rstbl.ffptr, \ + rthandler->rstbl.nfentries, \ + rthandler->rstbl.nuentries, \ + rthandler->rstbl.node[rindex].nptr, \ + rthandler->rstbl.node[rindex].pprt, \ + rthandler->rstbl.lfptr, \ + rthandler->rstbl.hw_table[rindex].hwnextptr, \ + rthandler->rstbl.hw_table[rindex].hwvalid); #endif /* RT_DEBUG */ + if (((ptable.key[4] >> 15) & 1) == 1) { index = (ptable.key[0] & 0x7FF); + if (index != 0x7ff) rt_iptable_rd(cdev, index, &iptbl); + rpar->routeEntry.pattern.eIpType = iptbl.itype; + if (rpar->routeEntry.pattern.eIpType == - GSW_RT_IP_V6) { + GSW_RT_IP_V6) { for (i = 0; i < 8; i++) rpar->routeEntry.pattern.nDstIP.nIPv6[i] = - (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); + (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); } else if (rpar->routeEntry.pattern.eIpType == - GSW_RT_IP_V4) { + GSW_RT_IP_V4) { rpar->routeEntry.pattern.nDstIP.nIPv4 = (iptbl.iaddr.i4addr[0] | - (iptbl.iaddr.i4addr[1] << 8) | - (iptbl.iaddr.i4addr[2] << 16) | - (iptbl.iaddr.i4addr[3] << 24)); + (iptbl.iaddr.i4addr[1] << 8) | + (iptbl.iaddr.i4addr[2] << 16) | + (iptbl.iaddr.i4addr[3] << 24)); } + memset(&iptbl, 0, sizeof(riptbl_t)); index = (ptable.key[1] & 0x7FF); + if (index != 0x7ff) rt_iptable_rd(cdev, index, &iptbl); + rpar->routeEntry.pattern.eIpType = iptbl.itype; + if (rpar->routeEntry.pattern.eIpType == - GSW_RT_IP_V6) { + GSW_RT_IP_V6) { for (i = 0; i < 8; i++) rpar->routeEntry.pattern.nSrcIP.nIPv6[i] = - (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); + (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); } else { rpar->routeEntry.pattern.nSrcIP.nIPv4 = (iptbl.iaddr.i4addr[0] | - (iptbl.iaddr.i4addr[1] << 8) | - (iptbl.iaddr.i4addr[2] << 16) | - (iptbl.iaddr.i4addr[3] << 24)); + (iptbl.iaddr.i4addr[1] << 8) | + (iptbl.iaddr.i4addr[2] << 16) | + (iptbl.iaddr.i4addr[3] << 24)); } rpar->routeEntry.pattern.nDstPort = (ptable.key[2]); @@ -1709,21 +1503,23 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, memset(&iptbl, 0, sizeof(riptbl_t)); index = (ptable.val[2] & 0x7FF); + if (index != 0x7ff) rt_iptable_rd(cdev, index, &iptbl); + rpar->routeEntry.action.eIpType = iptbl.itype; if (rpar->routeEntry.action.eIpType == GSW_RT_IP_V6) { for (i = 0; i < 8; i++) rpar->routeEntry.action.nNATIPaddr.nIPv6[i] = - (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); + (iptbl.iaddr.i6addr[7 - i] & 0xFFFF); } else if (rpar->routeEntry.action.eIpType == - GSW_RT_IP_V4) { + GSW_RT_IP_V4) { rpar->routeEntry.action.nNATIPaddr.nIPv4 = - (iptbl.iaddr.i4addr[0] | - (iptbl.iaddr.i4addr[1] << 8) | - (iptbl.iaddr.i4addr[2] << 16) | - (iptbl.iaddr.i4addr[3] << 24)); + (iptbl.iaddr.i4addr[0] | + (iptbl.iaddr.i4addr[1] << 8) | + (iptbl.iaddr.i4addr[2] << 16) | + (iptbl.iaddr.i4addr[3] << 24)); } rpar->routeEntry.action.nTcpUdpPort = (ptable.val[3]); @@ -1734,47 +1530,55 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, memset(&mentry, 0, sizeof(rt_mac_tbl_t)); index = ((ptable.val[4] >> 8) & 0xFF); + if (index != 0) { rt_mactable_rd(cdev, index, &mentry); + for (i = 0; i < 6; i++) rpar->routeEntry.action.nSrcMAC[i] = - mentry.mdata[i]; + mentry.mdata[i]; + rpar->routeEntry.action.bMAC_SrcEnable = 1; } + index = ((ptable.val[5]) & 0x1FF); memset(&mentry, 0, sizeof(rt_mac_tbl_t)); + if (index != 0) { rt_mactable_rd(cdev, index, &mentry); + for (i = 0; i < 6; i++) rpar->routeEntry.action.nDstMAC[i] = - mentry.mdata[i]; + mentry.mdata[i]; + rpar->routeEntry.action.bMAC_DstEnable = 1; } rpar->routeEntry.action.nFID = (ptable.val[8] & 0x3F); rpar->routeEntry.action.nFlowId = - ((ptable.val[8] >> 8) & 0xFF); + ((ptable.val[8] >> 8) & 0xFF); rpar->routeEntry.action.nDSCP = - (ptable.val[9] & 0x3F); + (ptable.val[9] & 0x3F); rpar->routeEntry.action.nTrafficClass = - ((ptable.val[9] >> 8) & 0x3F); + ((ptable.val[9] >> 8) & 0x3F); rpar->routeEntry.action.nSessionCtrs = - (ptable.val[10]); + (ptable.val[10]); rpar->routeEntry.action.nSessionCtrs |= - ((ptable.val[11] << 16)); + ((ptable.val[11] << 16)); + if ((ptable.val[12] >> 0) & 0x1) rpar->routeEntry.action.eSessDirection = - GSW_ROUTE_DIRECTION_UPSTREAM; + GSW_ROUTE_DIRECTION_UPSTREAM; else rpar->routeEntry.action.eSessDirection = - GSW_ROUTE_DIRECTION_DNSTREAM; + GSW_ROUTE_DIRECTION_DNSTREAM; if ((ptable.val[12] >> 1) & 0x1) { rt_ppoe_tbl_t sesid; index = (ptable.val[6] & 0xF); rt_ppoetable_rd(cdev, index, &sesid); rpar->routeEntry.action.nPPPoESessId = - sesid.psesid; + sesid.psesid; rpar->routeEntry.action.bPPPoEmode = 1; } else rpar->routeEntry.action.bPPPoEmode = 0; @@ -1783,71 +1587,85 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, case 0: rpar->routeEntry.action.eSessRoutingMode = GSW_ROUTE_MODE_NULL; - break; + break; + case 1: rpar->routeEntry.action.eSessRoutingMode = GSW_ROUTE_MODE_ROUTING; - break; + break; + case 2: rpar->routeEntry.action.eSessRoutingMode = GSW_ROUTE_MODE_NAT; - break; + break; + case 3: rpar->routeEntry.action.eSessRoutingMode = GSW_ROUTE_MODE_NAPT; break; } + switch ((ptable.val[12] >> 4) & 0x3) { case 0: rpar->routeEntry.action.eTunType = GSW_ROUTE_TUNL_NULL; - break; + break; + case 1: rpar->routeEntry.action.eTunType = GSW_ROUTE_TUNL_6RD; - break; + break; + case 2: rpar->routeEntry.action.eTunType = GSW_ROUTE_TUNL_DSLITE; - break; + break; + case 3: rpar->routeEntry.action.eTunType = GSW_ROUTE_TUNL_IPSEC; - break; + break; } + rpar->routeEntry.action.nTunnelIndex = - ((ptable.val[6] >> 8) & 0xF); + ((ptable.val[6] >> 8) & 0xF); switch ((ptable.val[12] >> 6) & 0x3) { case 0: rpar->routeEntry.action.eOutDSCPAction = GSW_ROUTE_OUT_DSCP_NULL; - break; + break; + case 1: rpar->routeEntry.action.eOutDSCPAction = GSW_ROUTE_OUT_DSCP_INNER; - break; + break; + case 2: rpar->routeEntry.action.eOutDSCPAction = GSW_ROUTE_OUT_DSCP_SESSION; - break; + break; + case 3: rpar->routeEntry.action.eOutDSCPAction = GSW_ROUTE_OUT_DSCP_RES; - break; + break; } + if ((ptable.val[12] >> 8) & 0x1) rpar->routeEntry.action.bInnerDSCPRemark = 1; else rpar->routeEntry.action.bInnerDSCPRemark = 0; + if ((ptable.val[12] >> 9) & 0x1) rpar->routeEntry.action.bTCremarking = 1; else rpar->routeEntry.action.bTCremarking = 0; + if ((ptable.val[12] >> 10) & 0x1) { rpar->routeEntry.action.bMeterAssign = 1; rpar->routeEntry.action.nMeterId = - ptable.val[7] & 0x3F; + ptable.val[7] & 0x3F; } else rpar->routeEntry.action.bMeterAssign = 0; @@ -1856,17 +1674,19 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, index = ((ptable.val[7] >> 8) & 0x3F); rt_rtptable_rd(cdev, index, &rtp_tbl); rpar->routeEntry.action.nRTPSeqNumber = - rtp_tbl.rtpseqnum; + rtp_tbl.rtpseqnum; rpar->routeEntry.action.nRTPSessionPktCnt = - rtp_tbl.rtpsespcnt; + rtp_tbl.rtpsespcnt; rpar->routeEntry.action.bRTPMeasEna = 1; } else { rpar->routeEntry.action.bRTPMeasEna = 0; } + if ((ptable.val[12] >> 12) & 0x1) rpar->routeEntry.action.bTTLDecrement = 1; else rpar->routeEntry.action.bTTLDecrement = 0; + if ((ptable.val[12] >> 15) & 0x1) rpar->routeEntry.action.bHitStatus = 1; else @@ -1875,86 +1695,100 @@ int GSW_ROUTE_SessionEntryRead(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_TunnelEntryAdd(void *cdev, - GSW_ROUTE_Tunnel_Entry_t *rpar) + GSW_ROUTE_Tunnel_Entry_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); int i, j; + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; u16 data[20] = { 0 }; + if (rpar->tunnelEntry.eTunnelType == GSW_ROUTE_TUNL_6RD) { - data[0] = 0x0045; data[1] = 0x5678; - data[2] = 0x90ab; data[3] = 0x0000; - data[4] = 0x293f; data[5] = 0x3344; + data[0] = 0x0045; + data[1] = 0x5678; + data[2] = 0x90ab; + data[3] = 0x0000; + data[4] = 0x293f; + data[5] = 0x3344; data[6] = - ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 24) - & 0xFF); + ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 24) + & 0xFF); data[6] |= - (((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 16) - & 0xFF) << 8); + (((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 16) + & 0xFF) << 8); data[7] = - ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 8) - & 0xFF); + ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 >> 8) + & 0xFF); data[7] |= - ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 - & 0xFF) << 8); + ((rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 + & 0xFF) << 8); data[8] = - ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 24) - & 0xFF); + ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 24) + & 0xFF); data[8] |= - (((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 16) - & 0xFF) << 8); + (((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 16) + & 0xFF) << 8); data[9] = - ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 8) - & 0xFF); + ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 >> 8) + & 0xFF); data[9] |= - ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 - & 0xFF) << 8); + ((rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 + & 0xFF) << 8); } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_DSLITE) { - data[0] = 0x0060; data[1] = 0x0000; - data[2] = 0x0000; data[3] = 0xff04; + GSW_ROUTE_TUNL_DSLITE) { + data[0] = 0x0060; + data[1] = 0x0000; + data[2] = 0x0000; + data[3] = 0xff04; + for (i = 0; i < 8; i++) { - data[i+4] = - ((rpar->tunnelEntry.t.tunDSlite.nSrcIP6Addr.nIPv6[i] >> 8) - & 0xFF); - data[i+4] |= - ((rpar->tunnelEntry.t.tunDSlite.nSrcIP6Addr.nIPv6[i] - & 0xFF) << 8); + data[i + 4] = + ((rpar->tunnelEntry.t.tunDSlite.nSrcIP6Addr.nIPv6[i] >> 8) + & 0xFF); + data[i + 4] |= + ((rpar->tunnelEntry.t.tunDSlite.nSrcIP6Addr.nIPv6[i] + & 0xFF) << 8); } + for (i = 0; i < 8; i++) { - data[i+12] = - ((rpar->tunnelEntry.t.tunDSlite.nDstIP6Addr.nIPv6[i] >> 8) - & 0xFF); - data[i+12] |= - ((rpar->tunnelEntry.t.tunDSlite.nDstIP6Addr.nIPv6[i] - & 0xFF) << 8); + data[i + 12] = + ((rpar->tunnelEntry.t.tunDSlite.nDstIP6Addr.nIPv6[i] >> 8) + & 0xFF); + data[i + 12] |= + ((rpar->tunnelEntry.t.tunDSlite.nDstIP6Addr.nIPv6[i] + & 0xFF) << 8); } } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_L2TP) { + GSW_ROUTE_TUNL_L2TP) { data[1] = - (rpar->tunnelEntry.t.nTunL2TP & 0xFFFF); + (rpar->tunnelEntry.t.nTunL2TP & 0xFFFF); data[0] = - ((rpar->tunnelEntry.t.nTunL2TP >> 16) & 0xFFFF); + ((rpar->tunnelEntry.t.nTunL2TP >> 16) & 0xFFFF); } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_IPSEC) { + GSW_ROUTE_TUNL_IPSEC) { data[1] = (rpar->tunnelEntry.t.nTunIPsec & 0xFFFF); data[0] = - ((rpar->tunnelEntry.t.nTunIPsec >> 16) & 0xFFFF); + ((rpar->tunnelEntry.t.nTunIPsec >> 16) & 0xFFFF); } + for (j = 0; j < 5; j++) { memset(&ptable, 0, sizeof(pctbl_prog_t)); + for (i = 0; i < 4; i++) - ptable.val[i] = data[(j*4)+i]; + ptable.val[i] = data[(j * 4) + i]; + ptable.table = PCE_R_TUNNEL_INDEX; ptable.pcindex = ((rpar->nTunIndex * 5) + j); ptable.valid = 1; @@ -1964,19 +1798,22 @@ int GSW_ROUTE_TunnelEntryAdd(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_TunnelEntryRead(void *cdev, - GSW_ROUTE_Tunnel_Entry_t *rpar) + GSW_ROUTE_Tunnel_Entry_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; int i, j; u16 data[20] = { 0 }; @@ -1987,50 +1824,57 @@ int GSW_ROUTE_TunnelEntryRead(void *cdev, ptable.pcindex = ((rpar->nTunIndex * 5) + j); ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); + for (i = 0; i < 4; i++) data[(j * 4) + i] = ptable.val[i]; } + if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_6RD) { + GSW_ROUTE_TUNL_6RD) { rpar->tunnelEntry.t.tun6RD.nSrcIP4Addr.nIPv4 = ((data[6] << 16) | (data[7])); rpar->tunnelEntry.t.tun6RD.nDstIP4Addr.nIPv4 = ((data[8] << 16) | (data[9])); } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_DSLITE) { + GSW_ROUTE_TUNL_DSLITE) { for (i = 0; i < 8; i++) rpar->tunnelEntry.t.tunDSlite.nSrcIP6Addr.nIPv6[i] = - data[i+4]; + data[i + 4]; + for (i = 0; i < 8; i++) rpar->tunnelEntry.t.tunDSlite.nDstIP6Addr.nIPv6[i] = - data[i+12]; + data[i + 12]; } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_L2TP) { + GSW_ROUTE_TUNL_L2TP) { rpar->tunnelEntry.t.nTunIPsec = - ((data[0] << 16) | data[1]); + ((data[0] << 16) | data[1]); } else if (rpar->tunnelEntry.eTunnelType == - GSW_ROUTE_TUNL_IPSEC) { + GSW_ROUTE_TUNL_IPSEC) { rpar->tunnelEntry.t.nTunIPsec = ((data[0] << 16) | data[1]); } } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_TunnelEntryDel(void *cdev, - GSW_ROUTE_Tunnel_Entry_t *rpar) + GSW_ROUTE_Tunnel_Entry_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; int j; + for (j = 0; j < 5; j++) { memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_TUNNEL_INDEX; @@ -2041,22 +1885,27 @@ int GSW_ROUTE_TunnelEntryDel(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_L2NATCfgWrite(void *cdev, - GSW_ROUTE_EgPort_L2NAT_Cfg_t *rpar) + GSW_ROUTE_EgPort_L2NAT_Cfg_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { u16 data; + if (rpar->nEgPortId >= ethdev->tpnum) return GSW_statusErr; + gsw_w32(cdev, (PCE_PCTRL_2_L2NAT_OFFSET + (rpar->nEgPortId * 0xA)), PCE_PCTRL_2_L2NAT_SHIFT, @@ -2082,20 +1931,24 @@ int GSW_ROUTE_L2NATCfgWrite(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_L2NATCfgRead(void *cdev, - GSW_ROUTE_EgPort_L2NAT_Cfg_t *rpar) + GSW_ROUTE_EgPort_L2NAT_Cfg_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { u32 data; + if (rpar->nEgPortId >= ethdev->tpnum) return GSW_statusErr; @@ -2127,25 +1980,29 @@ int GSW_ROUTE_L2NATCfgRead(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_SessHitOp(void *cdev, - GSW_ROUTE_Session_Hit_t *rpar) + GSW_ROUTE_Session_Hit_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_SESSION_INDEX; ptable.pcindex = rpar->nRtIndex; ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); + if (((ptable.key[4] >> 15) & 1) == 1) { switch (rpar->eHitOper) { case GSW_ROUTE_HIT_READ: @@ -2153,7 +2010,9 @@ int GSW_ROUTE_SessHitOp(void *cdev, rpar->bHitStatus = 1; else rpar->bHitStatus = 0; + break; + case GSW_ROUTE_HIT_CLEAR: ptable.val[12] &= ~(1 << 15); ptable.table = PCE_R_SESSION_INDEX; @@ -2161,19 +2020,23 @@ int GSW_ROUTE_SessHitOp(void *cdev, ptable.op_mode = OPMOD_RT_SESSION_HIT_STATUS; route_table_write(cdev, &ptable); break; + case GSW_ROUTE_HIT_N_CNTR_READ: if ((ptable.val[12] >> 15) & 0x1) rpar->bHitStatus = 1; else rpar->bHitStatus = 0; + rpar->nSessCntr = (ptable.val[10]); rpar->nSessCntr |= ((ptable.val[11] << 16)); break; + case GSW_ROUTE_HIT_N_CNTR_CLEAR: if ((ptable.val[12] >> 15) & 0x1) rpar->bHitStatus = 1; else rpar->bHitStatus = 0; + ptable.val[12] &= ~(1 << 15); rpar->nSessCntr = (ptable.val[10]); rpar->nSessCntr |= ((ptable.val[11] << 16)); @@ -2189,25 +2052,29 @@ int GSW_ROUTE_SessHitOp(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } int GSW_ROUTE_SessDestModify(void *cdev, - GSW_ROUTE_Session_Dest_t *rpar) + GSW_ROUTE_Session_Dest_t *rpar) { ethsw_api_dev_t *ethdev = GSW_PDATA_GET(cdev); + if (ethdev == NULL) { - pr_err("%s:%s:%d \n",__FILE__, __func__, __LINE__); + pr_err("%s:%s:%d \n", __FILE__, __func__, __LINE__); return GSW_statusErr; } + if ((ethdev->gipver == LTQ_GSWIP_3_0) - && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { + && ((ethdev->gsw_dev == LTQ_FLOW_DEV_INT_R))) { pctbl_prog_t ptable; memset(&ptable, 0, sizeof(pctbl_prog_t)); ptable.table = PCE_R_SESSION_INDEX; ptable.pcindex = rpar->nRtIdx; ptable.op_mode = OPMOD_ADDRESS_READ; route_table_read(cdev, &ptable); + if (((ptable.key[4] >> 15) & 1) == 1) { /* Destination Port Map */ ptable.val[0] = (rpar->nDstPortMap & 0xFFFF); @@ -2221,6 +2088,7 @@ int GSW_ROUTE_SessDestModify(void *cdev, } else { return GSW_statusErr; } + return GSW_statusOk; } @@ -2235,10 +2103,11 @@ int rt_table_init() rthandler->rstbl.nuentries = 0; rthandler->rstbl.ffptr = 0; rthandler->rstbl.lfptr = 4095; + for (index = 0; index < rthandler->rstbl.nfentries; index++) { rthandler->rstbl.node[index].vflag = 0; - rthandler->rstbl.node[index].pprt = (index == 0) ? (-1) : (index-1); - rthandler->rstbl.node[index].nptr = (index == 4095)? (-1) : (index + 1); + rthandler->rstbl.node[index].pprt = (index == 0) ? (-1) : (index - 1); + rthandler->rstbl.node[index].nptr = (index == 4095) ? (-1) : (index + 1); rthandler->rstbl.node[index].nventries = 0; rthandler->rstbl.node[index].fflag = 1; rthandler->rstbl.node[index].prio = 0; @@ -2247,16 +2116,19 @@ int rt_table_init() rthandler->rstbl.hw_table[index].hwvalid = 0; rthandler->rstbl.hw_table[index].hwnextptr = index; } + return GSW_statusOk; } int gsw_r_init() { int index; -/* rthandler = (ltq_rt_table_t *) kmalloc(sizeof(ltq_rt_table_t),*/ -/* GFP_KERNEL);*/ + + /* rthandler = (ltq_rt_table_t *) kmalloc(sizeof(ltq_rt_table_t),*/ + /* GFP_KERNEL);*/ if (rthandler) kfree(rthandler); + rthandler = kmalloc(sizeof(ltq_rt_table_t), GFP_KERNEL); PCE_ASSERT(rthandler == NULL); memset(&rthandler->rt_sub_tbl, 0, sizeof(rt_table_handle_t)); @@ -2265,10 +2137,11 @@ int gsw_r_init() rthandler->rstbl.nuentries = 0; rthandler->rstbl.ffptr = 0; rthandler->rstbl.lfptr = 4095; + for (index = 0; index < rthandler->rstbl.nfentries; index++) { rthandler->rstbl.node[index].vflag = 0; - rthandler->rstbl.node[index].pprt = (index == 0) ? (-1) : (index-1); - rthandler->rstbl.node[index].nptr = (index == 4095)? (-1) : (index + 1); + rthandler->rstbl.node[index].pprt = (index == 0) ? (-1) : (index - 1); + rthandler->rstbl.node[index].nptr = (index == 4095) ? (-1) : (index + 1); rthandler->rstbl.node[index].nventries = 0; rthandler->rstbl.node[index].fflag = 1; rthandler->rstbl.node[index].prio = 0; @@ -2276,5 +2149,6 @@ int gsw_r_init() rthandler->rstbl.hw_table[index].hwvalid = 0; rthandler->rstbl.hw_table[index].hwnextptr = index; } + return GSW_statusOk; } diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_pae.h b/drivers/net/ethernet/lantiq/switch-api/gsw_pae.h index bf74a3d93be320939c7bddc966e5b539adbcb507..00c7184492aa08081a3becc4bb8c81e27654ef4c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_pae.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_pae.h @@ -61,8 +61,8 @@ typedef struct { u8 i4addr[4]; u16 i6addr[8]; } iaddr; - u8 itype:2; - u8 valid:1; + u8 itype: 2; + u8 valid: 1; } riptbl_t; typedef struct { @@ -130,9 +130,9 @@ typedef struct { /* Routing MAC Table */ rt_mtu_tbl_t rt_mtu_tbl[RT_MTU_TBL_SIZE]; /* table reference counter */ -/* u16 rt_rtp_tbl_cnt[RT_RTP_TBL_SIZE]; */ + /* u16 rt_rtp_tbl_cnt[RT_RTP_TBL_SIZE]; */ /* Routing MAC Table */ -/* rt_rtp_tbl_t rt_rtp_tbl[RT_RTP_TBL_SIZE]; */ + /* rt_rtp_tbl_t rt_rtp_tbl[RT_RTP_TBL_SIZE]; */ } rt_table_handle_t; diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_reg.h b/drivers/net/ethernet/lantiq/switch-api/gsw_reg.h index 844e19c21ab438576f2ed67c82f7effbc49ff6fa..a3096ece8a32cff2d4232a6ac2db80c71e054cb3 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_reg.h +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_reg.h @@ -2999,7 +2999,7 @@ #define GSW_PCE_TCM_CTRL_TCMEN_SIZE 1 /* Bit: 'BLIND' */ -/* Description: To Configure Meter Color Blind Mode' +/* Description: To Configure Meter Color Blind Mode' applicable for GSWIP 3.1 only*/ #define GSW_PCE_TCM_CTRL_BLIND_OFFSET 0xE10 #define GSW_PCE_TCM_CTRL_BLIND_SHIFT 3 @@ -4279,22 +4279,22 @@ #define PMAC_CTRL_4_FLAGEN_OFFSET 0xD07 #define PMAC_CTRL_4_FLAGEN_SHIFT 0 #define PMAC_CTRL_4_FLAGEN_SIZE 1 -/*GSWIP3.1 PMAC_CTRL_4_FLAGEN_SIZE +/*GSWIP3.1 PMAC_CTRL_4_FLAGEN_SIZE has changed to 2 */ #define PMAC_CTRL_4_GSWIP3_1_FLAGEN_SIZE 2 /* --------------------------------------------------- */ /*Applicable for GSWIP3.1*/ -#define PMAC_BSL_LEN0_OFFSET 0xD10 -#define PMAC_BSL_LEN0_SHIFT 0 -#define PMAC_BSL_LEN0_SIZE 16 +#define PMAC_BSL_LEN0_OFFSET 0xD10 +#define PMAC_BSL_LEN0_SHIFT 0 +#define PMAC_BSL_LEN0_SIZE 16 -#define PMAC_BSL_LEN1_OFFSET 0xD11 -#define PMAC_BSL_LEN1_SHIFT 0 -#define PMAC_BSL_LEN1_SIZE 16 +#define PMAC_BSL_LEN1_OFFSET 0xD11 +#define PMAC_BSL_LEN1_SHIFT 0 +#define PMAC_BSL_LEN1_SIZE 16 -#define PMAC_BSL_LEN2_OFFSET 0xD12 -#define PMAC_BSL_LEN2_SHIFT 0 -#define PMAC_BSL_LEN2_SIZE 16 +#define PMAC_BSL_LEN2_OFFSET 0xD12 +#define PMAC_BSL_LEN2_SHIFT 0 +#define PMAC_BSL_LEN2_SIZE 16 /* --------------------------------------------------- */ /* --------------------------------------------------- */ @@ -4378,11 +4378,33 @@ #define PCE_DA_FILTER_OFFSET_GET(PortMemberId) (PCE_DA_FILTER_0_OFFSET+PortMemberId) #define PCE_DA_FILTER_SHIFT 0 #define PCE_DA_FILTER_SIZE 16 - + #define PCE_SA_FILTER_0_OFFSET 0x3F0 #define PCE_SA_FILTER_OFFSET_GET(PortMemberId) (PCE_SA_FILTER_0_OFFSET+PortMemberId) #define PCE_SA_FILTER_SHIFT 0 #define PCE_SA_FILTER_SIZE 16 +/*Description: Ethernet Switch IRQ register - Applicable for 3.1*/ + +#define PCE_IER_0_OFFSET 0x465 +#define PCE_IER_0_SHIFT 0 +#define PCE_IER_0_SIZE 16 + +#define PCE_IER_0_PORT_MASK_GET(LogicalPortID) (1 << LogicalPortID) + +#define PCE_IER_1_OFFSET 0x466 +#define PCE_IER_1_SHIFT 0 +#define PCE_IER_1_SIZE 16 + +#define PCE_ISR_0_OFFSET 0x467 +#define PCE_ISR_0_SHIFT 0 +#define PCE_ISR_0_SIZE 16 +#define PCE_ISR_0_PORT_MASK_GET(LogicalPortID) (1 << LogicalPortID) + + +#define PCE_ISR_1_OFFSET 0x468 +#define PCE_ISR_1_SHIFT 0 +#define PCE_ISR_1_SIZE 16 + /* --------------------------------------------------- */ #endif /* _LTQ_GSWITCH_REG_H_ */ diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_swmcast.c b/drivers/net/ethernet/lantiq/switch-api/gsw_swmcast.c index 9cb12dbc37c1cecb347808da73890c004620cd3c..54b13927718bcc90dadd46acb4fc1c0e54676546 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gsw_swmcast.c +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_swmcast.c @@ -7,22 +7,15 @@ * ******************************************************************************/ -#include "gsw_init.h" -#include "gsw_swmcast.h" +#include <gsw_init.h> +#include <gsw_swmcast.h> #define DEBUG_TEST 0 - -static MCAST_HASHTBL phtable[MCAST_TABLE_SIZE]; - -#if defined(KERNEL_MODE) && KERNEL_MODE -#else -#define printk pr_err -#endif - #define FOR_LOOP_TEST 0 - #define DEBUG_PRINT 0 +static MCAST_HASHTBL phtable[MCAST_TABLE_SIZE]; + //static MCAST_HASHTBL *gsw_create_hash_table(u32 table_size); static int get_hashtable_empty_slot(void *cdev, MCAST_HASHTBL *phtable); static u16 cal_hash(u32 src_ip_mode, MCAST_HASHTBL_PTN *pattern, u32 type); @@ -57,64 +50,72 @@ static u16 cal_hash(u32 src_ip_mode, MCAST_HASHTBL_PTN *pattern, u32 type) { u8 b[9]; u16 crc; - u32 len=0; - int i=0,j=0; + u32 len = 0; + int i = 0, j = 0; u32 ip6data[4]; u32 xdata; memset(b, 0, sizeof(b)); /* Order is important here, fid, dip, sip */ - b[i] = pattern->fid; - - if (src_ip_mode == GSW_IGMP_MEMBER_INCLUDE) { - if (type == GSW_IP_SELECT_IPV4) { - for (i = 0; i < 4; i++) - b[i + 1] = ((pattern->dstip.nIPv4 >> ((3 - i) * 8)) & 0xFF); - for (i = 0; i < 4; i++) - b[i + 5] = ((pattern->srcip.nIPv4 >> ((3-i) * 8)) & 0xFF); - } else if (type == GSW_IP_SELECT_IPV6) { - - for (i = 0, j = 0; i < 4; i++, j += 2) { - ip6data[i] = - ((pattern->dstip.nIPv6[j] << 16) | ((pattern->dstip.nIPv6[j+1]))); - } - xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); - for (i = 0; i < 4; i++) - b[i + 1] = ((xdata >> ((3 - i) * 8)) & 0xFF); - - for (i = 0, j = 0; i < 4; i++, j += 2) { - ip6data[i] = - ((pattern->srcip.nIPv6[j] << 16) | ((pattern->srcip.nIPv6[j+1]))); - } - xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); - for (i = 0; i < 4; i++) - b[i + 5] = ((xdata >> ((3 - i) * 8)) & 0xFF); - - } - len = 9; - } - else { - if (type == GSW_IP_SELECT_IPV4) { - for (i = 0; i < 4; i++) - b[i + 1] = ((pattern->dstip.nIPv4 >> ((3 - i) * 8)) & 0xFF); - } else if (type == GSW_IP_SELECT_IPV6) { - for (i = 0, j = 0; i < 4; i++, j += 2) { - ip6data[i] = - ((pattern->dstip.nIPv6[j] << 16) | ((pattern->dstip.nIPv6[j+1]))); - } - xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); - for (i = 0; i < 4; i++) - b[i + 1] = ((xdata >> ((3 - i) * 8)) & 0xFF); - } + b[i] = pattern->fid; + + if (src_ip_mode == GSW_IGMP_MEMBER_INCLUDE) { + if (type == GSW_IP_SELECT_IPV4) { + for (i = 0; i < 4; i++) + b[i + 1] = ((pattern->dstip.nIPv4 >> ((3 - i) * 8)) & 0xFF); + + for (i = 0; i < 4; i++) + b[i + 5] = ((pattern->srcip.nIPv4 >> ((3 - i) * 8)) & 0xFF); + } else if (type == GSW_IP_SELECT_IPV6) { + + for (i = 0, j = 0; i < 4; i++, j += 2) { + ip6data[i] = + ((pattern->dstip.nIPv6[j] << 16) | ((pattern->dstip.nIPv6[j + 1]))); + } + + xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); + + for (i = 0; i < 4; i++) + b[i + 1] = ((xdata >> ((3 - i) * 8)) & 0xFF); + + for (i = 0, j = 0; i < 4; i++, j += 2) { + ip6data[i] = + ((pattern->srcip.nIPv6[j] << 16) | ((pattern->srcip.nIPv6[j + 1]))); + } + + xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); + + for (i = 0; i < 4; i++) + b[i + 5] = ((xdata >> ((3 - i) * 8)) & 0xFF); + + } + + len = 9; + } else { + if (type == GSW_IP_SELECT_IPV4) { + for (i = 0; i < 4; i++) + b[i + 1] = ((pattern->dstip.nIPv4 >> ((3 - i) * 8)) & 0xFF); + } else if (type == GSW_IP_SELECT_IPV6) { + for (i = 0, j = 0; i < 4; i++, j += 2) { + ip6data[i] = + ((pattern->dstip.nIPv6[j] << 16) | ((pattern->dstip.nIPv6[j + 1]))); + } + + xdata = (ip6data[0] ^ ip6data[1] ^ ip6data[2] ^ ip6data[3]); + + for (i = 0; i < 4; i++) + b[i + 1] = ((xdata >> ((3 - i) * 8)) & 0xFF); + } + for (i = 0; i < 4; i++) b[i + 5] = 0; - - len = 9; - } + + len = 9; + } crc = crcmsb(b, len); - + crc &= 0x01FF; // To make sure it is withing 512 return (crc); @@ -205,7 +206,7 @@ int gsw_init_hash_table(void *cdev) //printk("Enter %s:%s:%d\n", __FILE__, __func__, __LINE__); memset(phtable, 0, (MCAST_HASHTBL_SIZE * gswdev->mctblsize)); - if (gswdev->gipver == LTQ_GSWIP_3_1) { + if (IS_VRSN_31(gswdev->gipver)) { for (pcindex = 0; pcindex < gswdev->mctblsize; pcindex++) { @@ -218,7 +219,7 @@ int gsw_init_hash_table(void *cdev) pcetable.table = PCE_MULTICAST_SW_INDEX; // TODO: Write the initial entries to HW Table - //gsw_pce_table_write(cdev, &pcetable); + //gsw_pce_table_write(cdev, &pcetable); } //printk("Exit %s:%s:%d\n", __FILE__, __func__, __LINE__); @@ -237,25 +238,26 @@ int gsw_get_swmcast_entry(void *cdev, GSW_multicastTableRead_t *parm, u32 loc) printk("Enter %s:%s:%d\n", __FILE__, __func__, __LINE__); - printk("Getting Index %d\n",loc); + printk("Getting Index %d\n", loc); - if(gswdev == NULL) + if (gswdev == NULL) return 0; - + #if DEBUG_TEST - if(loc == 0) { -#if FOR_LOOP_TEST - for (j=0;j<512;j++) { + if (loc == 0) { +#if FOR_LOOP_TEST + + for (j = 0; j < 512; j++) { loc = j; -#endif -#endif +#endif +#endif memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = loc; pcetable.table = PCE_MULTICAST_SW_INDEX; gsw_pce_table_read(cdev, &pcetable); - printk("Getting Index %d\n",loc); + printk("Getting Index %d\n", loc); #if DEBUG_PRINT printk("pcetable.valid = %d\n", pcetable.valid); @@ -273,36 +275,39 @@ int gsw_get_swmcast_entry(void *cdev, GSW_multicastTableRead_t *parm, u32 loc) int issue = 0; - if(pcetable.valid != 1) { + if (pcetable.valid != 1) { issue = 1; } - - if((pcetable.key[0] != 0x3FF) && (pcetable.key[1] != 0x1FF) && (pcetable.key[2] != 0xC03F)) - issue = 1; - - for(i=3;i<18;i++) { - if(pcetable.key[i] != 0xFFFF) + + if ((pcetable.key[0] != 0x3FF) && (pcetable.key[1] != 0x1FF) && (pcetable.key[2] != 0xC03F)) + issue = 1; + + for (i = 3; i < 18; i++) { + if (pcetable.key[i] != 0xFFFF) issue = 1; } - if(pcetable.val[1] != 0xFFF8) + if (pcetable.val[1] != 0xFFF8) issue = 1; - - for(i=2;i<10;i++) { - if(pcetable.val[i] != 0xFFFF) + + for (i = 2; i < 10; i++) { + if (pcetable.val[i] != 0xFFFF) issue = 1; } - for(i=10;i<18;i++) { - if(pcetable.val[i] != 0) + + for (i = 10; i < 18; i++) { + if (pcetable.val[i] != 0) issue = 1; } - if(issue) { - printk("Error in READING INDEX %d\n",loc); + if (issue) { + printk("Error in READING INDEX %d\n", loc); return 1; } -#endif + #endif +#endif + if (pcetable.valid == 1) { parm->bExclSrcIP = ((pcetable.key[2] >> 14) & 0x3); @@ -332,33 +337,37 @@ int gsw_get_swmcast_entry(void *cdev, GSW_multicastTableRead_t *parm, u32 loc) } -#if 1 - printk("Got Loc %d\n",loc); - printk("Valid %d\n",pcetable.valid); - printk("ExclSrcIP %d\n",parm->bExclSrcIP); - printk("nFID %d\n",parm->nFID); - printk("First Idx %d\n",pcetable.key[0]); - printk("Next Idx %d\n",pcetable.key[1]); + printk("Got Loc %d\n", loc); + printk("Valid %d\n", pcetable.valid); + printk("ExclSrcIP %d\n", parm->bExclSrcIP); + printk("nFID %d\n", parm->nFID); + printk("First Idx %d\n", pcetable.key[0]); + printk("Next Idx %d\n", pcetable.key[1]); + for (i = 0; i < 8; i++) - printk("uIP_Gda.nIPv6[%d] %04x\n",i,parm->uIP_Gda.nIPv6[i]); + printk("uIP_Gda.nIPv6[%d] %04x\n", i, parm->uIP_Gda.nIPv6[i]); + for (i = 0; i < 8; i++) - printk("uIP_Gsa.nIPv6[%d] %04x\n",i,parm->uIP_Gsa.nIPv6[i]); + printk("uIP_Gsa.nIPv6[%d] %04x\n", i, parm->uIP_Gsa.nIPv6[i]); + + printk("nSubIfId %d\n", parm->nSubIfId); - printk("nSubIfId %d\n",parm->nSubIfId); for (i = 0; i < 16; i++) - printk("nPortMap[%d] %04x\n",i,parm->nPortMap[i]); + printk("nPortMap[%d] %04x\n", i, parm->nPortMap[i]); - printk("nPortId %d\n",parm->nPortId); + printk("nPortId %d\n", parm->nPortId); printk("Exit %s:%s:%d\n", __FILE__, __func__, __LINE__); -#endif + #if DEBUG_TEST -#if FOR_LOOP_TEST +#if FOR_LOOP_TEST } -#endif + +#endif } -#endif + +#endif #if DEBUG_TEST return 1; @@ -373,11 +382,12 @@ static int set_pce_hash_table(void *cdev, MCAST_HASHTBL *phtable, u32 loc) pctbl_prog_t pcetable; int i = 0; - if(gswdev == NULL) + if (gswdev == NULL) return 0; + printk("Enter %s:%s:%d\n", __FILE__, __func__, __LINE__); - printk("Setting Index %d\n",loc); + printk("Setting Index %d\n", loc); memset(&pcetable, 0, sizeof(pctbl_prog_t)); pcetable.pcindex = loc; pcetable.table = PCE_MULTICAST_SW_INDEX; @@ -411,12 +421,13 @@ static int set_pce_hash_table(void *cdev, MCAST_HASHTBL *phtable, u32 loc) #if DEBUG_TEST - if(loc == 0) { -#if FOR_LOOP_TEST - for(j=0;j<512;j++) { + if (loc == 0) { +#if FOR_LOOP_TEST + + for (j = 0; j < 512; j++) { loc = j; #endif - printk("Setting Index %d\n",loc); + printk("Setting Index %d\n", loc); pcetable.pcindex = loc; pcetable.table = PCE_MULTICAST_SW_INDEX; pcetable.valid = 1; @@ -440,24 +451,29 @@ static int set_pce_hash_table(void *cdev, MCAST_HASHTBL *phtable, u32 loc) printk("valid = %d\n", phtable->valid); - printk("eModeMember %d\n",phtable->src_ip_mode); - printk("nFID %d\n",phtable->key.fid); + printk("eModeMember %d\n", phtable->src_ip_mode); + printk("nFID %d\n", phtable->key.fid); + for (i = 0; i < 8; i++) - printk("uIP_Gda.nIPv6[%d] %04x\n",i,phtable->key.dstip.nIPv6[i]); + printk("uIP_Gda.nIPv6[%d] %04x\n", i, phtable->key.dstip.nIPv6[i]); + for (i = 0; i < 8; i++) - printk("uIP_Gsa.nIPv6[%d] %04x\n",i,phtable->key.srcip.nIPv6[i]); + printk("uIP_Gsa.nIPv6[%d] %04x\n", i, phtable->key.srcip.nIPv6[i]); + + printk("nSubIfId %d\n", phtable->action.subifid); - printk("nSubIfId %d\n",phtable->action.subifid); for (i = 0; i < 16; i++) - printk("nPortMap[%d] %04x\n",i,phtable->action.br_portmap[i]); + printk("nPortMap[%d] %04x\n", i, phtable->action.br_portmap[i]); printk("Exit %s:%s:%d\n", __FILE__, __func__, __LINE__); #endif gsw_pce_table_write(cdev, &pcetable); -#if FOR_LOOP_TEST +#if FOR_LOOP_TEST } -#endif + +#endif } + #else gsw_pce_table_write(cdev, &pcetable); @@ -482,26 +498,26 @@ int gsw_insert_hashtable_entry(void *cdev, GSW_multicastTable_t *parm) printk("Enter %s:%s:%d\n", __FILE__, __func__, __LINE__); - if(parm->nPortId > gswdev->num_of_bridge_port) { - pr_err("PortId only upto %d is supported\n",gswdev->num_of_bridge_port); + if (parm->nPortId > gswdev->num_of_bridge_port) { + pr_err("PortId only upto %d is supported\n", gswdev->num_of_bridge_port); return FAIL; } - + portId = parm->nPortId; if (parm->eIPVersion == GSW_IP_SELECT_IPV4) { pattern.srcip.nIPv4 = parm->uIP_Gsa.nIPv4; pattern.dstip.nIPv4 = parm->uIP_Gda.nIPv4; - printk("portId = %d\n parm->eIPVersion = %d\n nSubIfId = %d\n uIP_Gsa.nIPv4 = %08x\n uIP_Gda.nIPv4 = %08x\n fid = %d\n bExclSrcIP = %d\n eModeMember = %d\n",parm->nPortId, parm->eIPVersion, parm->nSubIfId, parm->uIP_Gsa.nIPv4, parm->uIP_Gda.nIPv4, - parm->nFID, parm->bExclSrcIP, parm->eModeMember); + printk("portId = %d\n parm->eIPVersion = %d\n nSubIfId = %d\n uIP_Gsa.nIPv4 = %08x\n uIP_Gda.nIPv4 = %08x\n fid = %d\n bExclSrcIP = %d\n eModeMember = %d\n", parm->nPortId, parm->eIPVersion, parm->nSubIfId, parm->uIP_Gsa.nIPv4, parm->uIP_Gda.nIPv4, + parm->nFID, parm->bExclSrcIP, parm->eModeMember); } else if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { - + printk("portId = %d\n parm->eIPVersion = %d\n nSubIfId = %d\n fid = %d\n bExclSrcIP = %d\n eModeMember = %d\n", - parm->nPortId, parm->eIPVersion, parm->nSubIfId, parm->nFID, parm->bExclSrcIP, parm->eModeMember); - + parm->nPortId, parm->eIPVersion, parm->nSubIfId, parm->nFID, parm->bExclSrcIP, parm->eModeMember); + for (i = 0; i < 8; i++) { - pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7-i]; - pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7-i]; + pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7 - i]; + pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7 - i]; } } @@ -610,8 +626,8 @@ int gsw_search_hashtable_entry(void *cdev, GSW_multicastTable_t *parm, GSW_multi MCAST_HASHTBL_PTN pattern; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if(parm->nPortId > gswdev->num_of_bridge_port) { - pr_err("PortId only upto %d is supported\n",gswdev->num_of_bridge_port); + if (parm->nPortId > gswdev->num_of_bridge_port) { + pr_err("PortId only upto %d is supported\n", gswdev->num_of_bridge_port); return FAIL; } @@ -624,8 +640,8 @@ int gsw_search_hashtable_entry(void *cdev, GSW_multicastTable_t *parm, GSW_multi pattern.dstip.nIPv4 = parm->uIP_Gda.nIPv4; } else if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { for (i = 0; i < 8; i++) { - pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7-i]; - pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7-i]; + pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7 - i]; + pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7 - i]; } } @@ -781,8 +797,8 @@ int gsw_remove_hashtable_entry(void *cdev, GSW_multicastTable_t *parm) MCAST_HASHTBL_PTN pattern; ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); - if(parm->nPortId > gswdev->num_of_bridge_port) { - pr_err("PortId only upto %d is supported\n",gswdev->num_of_bridge_port); + if (parm->nPortId > gswdev->num_of_bridge_port) { + pr_err("PortId only upto %d is supported\n", gswdev->num_of_bridge_port); return FAIL; } @@ -793,8 +809,8 @@ int gsw_remove_hashtable_entry(void *cdev, GSW_multicastTable_t *parm) pattern.dstip.nIPv4 = parm->uIP_Gda.nIPv4; } else if (parm->eIPVersion == GSW_IP_SELECT_IPV6) { for (i = 0; i < 8; i++) { - pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7-i]; - pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7-i]; + pattern.srcip.nIPv6[i] = parm->uIP_Gsa.nIPv6[7 - i]; + pattern.dstip.nIPv6[i] = parm->uIP_Gda.nIPv6[7 - i]; } } @@ -823,56 +839,3 @@ int gsw_remove_hashtable_entry(void *cdev, GSW_multicastTable_t *parm) } -#if 0 -void print_table() -{ - int i = 0, j = 0; - u8 ip[4]; - u16 *src_ipv6, *dst_ipv6; - u8 *src_ip, *dst_ip; - MCAST_HASHTBL *tbl_ptr; - - pr_err("Idx\tValid\tFirst Ptr\tNext Ptr\tSrc_IP_Mode\tSrc_IP\t\t\tDst_IP\t\t\tFID\n"); - - for (i = 0; i < MCAST_TABLE_SIZE; i++) { - if (phtable[i].valid || ((phtable[i].first_idx != 0xFFFF) || (phtable[i].nxt_idx != 0xFFFF))) { - if(phtable[i].ip_type == GSW_IP_SELECT_IPV4) { - src_ip = (u8 *)&phtable[i].key.srcip.nIPv4; - dst_ip = (u8 *)&phtable[i].key.dstip.nIPv4; - pr_err("%d\t%d\t%d\t\t%d\t\t%d\t\t%d.%d.%d.%d\t\t%d.%d.%d.%d\t\t%d\n", - phtable[i].idx, phtable[i].valid, phtable[i].first_idx, phtable[i].nxt_idx, phtable[i].src_ip_mode, src_ip[3], src_ip[2], src_ip[1], src_ip[0], - dst_ip[3], dst_ip[2], dst_ip[1], dst_ip[0], phtable[i].key.fid); - } - else { - src_ipv6 = (u16 *)&phtable[i].key.srcip.nIPv6; - dst_ipv6 = (u16 *)&phtable[i].key.dstip.nIPv6; - pr_err("%d\t%d\t%d\t\t%d\t\t%d\t\t%d:%d:%d:%d:%d:%d:%d:%d\t%d:%d:%d:%d:%d:%d:%d:%d\t%d\n", - phtable[i].idx, phtable[i].valid, phtable[i].first_idx, phtable[i].nxt_idx, phtable[i].src_ip_mode, src_ipv6[0], src_ipv6[1], src_ipv6[2], src_ipv6[3], src_ipv6[4], src_ipv6[5], src_ipv6[6], src_ipv6[7],dst_ipv6[0], dst_ipv6[1], dst_ipv6[2], dst_ipv6[3], dst_ipv6[4], dst_ipv6[5], dst_ipv6[6], dst_ipv6[7], phtable[i].key.fid); - } - //for(j=0;j<16;j++) { - //pr_err("\tbr_portmap[%d] %04x\n",j,phtable[i].action.br_portmap[j]); - //} - //pr_err("subifid %d\n",phtable[i].action.subifid); - } - - } - - for (i = 0; i < MCAST_TABLE_SIZE; i++) { - - if(phtable[i].first_idx != 0xFFFF) - { - tbl_ptr = &phtable[i]; - tbl_ptr = &phtable[tbl_ptr->first_idx]; - - pr_err("HASH %d: %d", i, phtable[i].first_idx); - while(tbl_ptr->idx != tbl_ptr->nxt_idx) { - pr_err(" -> %d", tbl_ptr->nxt_idx); - tbl_ptr = &phtable[tbl_ptr->nxt_idx]; - } - pr_err("\n"); - } - } - return; -} -#endif - diff --git a/drivers/net/ethernet/lantiq/switch-api/gsw_tbl_rw.c b/drivers/net/ethernet/lantiq/switch-api/gsw_tbl_rw.c new file mode 100644 index 0000000000000000000000000000000000000000..6c3c53e49125ee799ef7e31f890f10390e9a27c4 --- /dev/null +++ b/drivers/net/ethernet/lantiq/switch-api/gsw_tbl_rw.c @@ -0,0 +1,810 @@ +/****************************************************************************** + * Copyright (c) 2016, 2017 Intel Corporation + * + * + * For licensing information, see the file 'LICENSE' in the root folder of + * this software module. + * + ******************************************************************************/ + +#include <gsw_init.h> + +GSW_return_t gsw_bm_table_read(void *cdev, bmtbl_prog_t *ptdata) +{ + GSW_return_t err = GSW_statusOk; + int i, noOfValues; + + if (ptdata->b64bitMode) + ptdata->tableID |= 0x40; + + noOfValues = ptdata->numValues; + gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, (u32) ptdata->adr.raw); + gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x8000); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + + for (i = 0; (i < noOfValues) /*&& (GSW_statusOk == err)*/; i++) + gsw_r32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET - i, &(ptdata->value[i])); + + return err; +} + +GSW_return_t gsw_bm_table_write(void *cdev, bmtbl_prog_t *ptdata) +{ + GSW_return_t err = GSW_statusOk; + int i, noOfValues; + + if (ptdata->b64bitMode) + ptdata->tableID |= 0x40; + + noOfValues = ptdata->numValues; + gsw_w32_raw(cdev, BM_RAM_ADDR_REG_OFFSET, (u32) ptdata->adr.raw); + gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x0020); + + for (i = 0; (i < noOfValues) /*&& (GSW_statusOk == err)*/; i++) + gsw_w32_raw(cdev, BM_RAM_VAL_0_VAL0_OFFSET - i, ptdata->value[i]); + + gsw_w32_raw(cdev, BM_RAM_CTRL_REG_OFFSET, ((u32)ptdata->tableID) | 0x8020); + CHECK_BUSY(BM_RAM_CTRL_BAS_OFFSET, BM_RAM_CTRL_BAS_SHIFT, + BM_RAM_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + return err; +} + +u32 pmac_addr_off(u32 off, u32 id) +{ + + if (id == 1) + off = off + 0x80; + else if (id == 2) + off = off + 0x200; + + return off; +} + +int xwayflow_pmac_table_read(void *cdev, pmtbl_prog_t *ptdata) +{ + u32 value; + + CHECK_BUSY(pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, PMAC_TBL_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_ADDR_ADDR_OFFSET, ptdata->pmacId), + PMAC_TBL_ADDR_ADDR_SHIFT, + PMAC_TBL_ADDR_ADDR_SIZE, ptdata->ptaddr); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_ADDR_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_ADDR_SHIFT, + PMAC_TBL_CTRL_ADDR_SIZE, ptdata->ptcaddr); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_OPMOD_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_OPMOD_SHIFT, + PMAC_TBL_CTRL_OPMOD_SIZE, 0 /* ptdata->op_mode */); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, + PMAC_TBL_CTRL_BAS_SIZE, 1); + CHECK_BUSY(pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, PMAC_TBL_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + gsw_r32(cdev, pmac_addr_off(PMAC_TBL_VAL_4_VAL4_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_4_VAL4_SHIFT, + PMAC_TBL_VAL_4_VAL4_SIZE, &value); + ptdata->val[4] = value; + gsw_r32(cdev, pmac_addr_off(PMAC_TBL_VAL_3_VAL3_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_3_VAL3_SHIFT, + PMAC_TBL_VAL_3_VAL3_SIZE, &value); + ptdata->val[3] = value; + gsw_r32(cdev, pmac_addr_off(PMAC_TBL_VAL_2_VAL2_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_2_VAL2_SHIFT, + PMAC_TBL_VAL_2_VAL2_SIZE, &value); + ptdata->val[2] = value; + gsw_r32(cdev, pmac_addr_off(PMAC_TBL_VAL_1_VAL1_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_1_VAL1_SHIFT, + PMAC_TBL_VAL_1_VAL1_SIZE, &value); + ptdata->val[1] = value; + gsw_r32(cdev, pmac_addr_off(PMAC_TBL_VAL_0_VAL0_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_0_VAL0_SHIFT, + PMAC_TBL_VAL_0_VAL0_SIZE, &value); + ptdata->val[0] = value; + return 0; +} + +int xwayflow_pmac_table_write(void *cdev, pmtbl_prog_t *ptdata) +{ + CHECK_BUSY(pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, PMAC_TBL_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_ADDR_ADDR_OFFSET, ptdata->pmacId), + PMAC_TBL_ADDR_ADDR_SHIFT, + PMAC_TBL_ADDR_ADDR_SIZE, ptdata->ptaddr); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_ADDR_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_ADDR_SHIFT, + PMAC_TBL_CTRL_ADDR_SIZE, ptdata->ptcaddr); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_OPMOD_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_OPMOD_SHIFT, + PMAC_TBL_CTRL_OPMOD_SIZE, 1 /* ptdata->op_mode */); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_VAL_4_VAL4_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_4_VAL4_SHIFT, + PMAC_TBL_VAL_4_VAL4_SIZE, ptdata->val[4]); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_VAL_3_VAL3_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_3_VAL3_SHIFT, + PMAC_TBL_VAL_3_VAL3_SIZE, ptdata->val[3]); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_VAL_2_VAL2_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_2_VAL2_SHIFT, + PMAC_TBL_VAL_2_VAL2_SIZE, ptdata->val[2]); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_VAL_1_VAL1_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_1_VAL1_SHIFT, + PMAC_TBL_VAL_1_VAL1_SIZE, ptdata->val[1]); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_VAL_0_VAL0_OFFSET, ptdata->pmacId), + PMAC_TBL_VAL_0_VAL0_SHIFT, + PMAC_TBL_VAL_0_VAL0_SIZE, ptdata->val[0]); + gsw_w32(cdev, pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, + PMAC_TBL_CTRL_BAS_SIZE, 1); + CHECK_BUSY(pmac_addr_off(PMAC_TBL_CTRL_BAS_OFFSET, ptdata->pmacId), + PMAC_TBL_CTRL_BAS_SHIFT, PMAC_TBL_CTRL_BAS_SIZE, RETURN_FROM_FUNCTION); + + return 0; +} + +int route_table_read(void *cdev, pctbl_prog_t *rdata) +{ + u32 value; + + do { + gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, &value); + } while (value != 0); + + gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, + PCE_TBL_ADDR_ADDR_SHIFT, + PCE_TBL_ADDR_ADDR_SIZE, rdata->pcindex); + gsw_w32(cdev, PCE_RTBL_CTRL_ADDR_OFFSET, + PCE_RTBL_CTRL_ADDR_SHIFT, + PCE_RTBL_CTRL_ADDR_SIZE, rdata->table); + gsw_w32(cdev, PCE_RTBL_CTRL_OPMOD_OFFSET, + PCE_RTBL_CTRL_OPMOD_SHIFT, + PCE_RTBL_CTRL_OPMOD_SIZE, rdata->op_mode); + gsw_w32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, 1); + + do { + gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, &value); + } while (value != 0); + + gsw_r32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, + PCE_TBL_KEY_15_KEY15_SHIFT, + PCE_TBL_KEY_15_KEY15_SIZE, &value); + rdata->key[15] = value; + gsw_r32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, + PCE_TBL_KEY_14_KEY14_SHIFT, + PCE_TBL_KEY_14_KEY14_SIZE, &value); + rdata->key[14] = value; + gsw_r32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, + PCE_TBL_KEY_13_KEY13_SHIFT, + PCE_TBL_KEY_13_KEY13_SIZE, &value); + rdata->key[13] = value; + gsw_r32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, + PCE_TBL_KEY_12_KEY12_SHIFT, + PCE_TBL_KEY_12_KEY12_SIZE, &value); + rdata->key[12] = value; + gsw_r32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, + PCE_TBL_KEY_11_KEY11_SHIFT, + PCE_TBL_KEY_11_KEY11_SIZE, &value); + rdata->key[11] = value; + gsw_r32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, + PCE_TBL_KEY_10_KEY10_SHIFT, + PCE_TBL_KEY_10_KEY10_SIZE, &value); + rdata->key[10] = value; + gsw_r32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, + PCE_TBL_KEY_9_KEY9_SHIFT, + PCE_TBL_KEY_9_KEY9_SIZE, &value); + rdata->key[9] = value; + gsw_r32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, + PCE_TBL_KEY_8_KEY8_SHIFT, + PCE_TBL_KEY_8_KEY8_SIZE, &value); + rdata->key[8] = value; + gsw_r32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, + PCE_TBL_KEY_7_KEY7_SHIFT, + PCE_TBL_KEY_7_KEY7_SIZE, &value); + rdata->key[7] = value; + gsw_r32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, + PCE_TBL_KEY_6_KEY6_SHIFT, + PCE_TBL_KEY_6_KEY6_SIZE, &value); + rdata->key[6] = value; + gsw_r32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, + PCE_TBL_KEY_5_KEY5_SHIFT, + PCE_TBL_KEY_5_KEY5_SIZE, &value); + rdata->key[5] = value; + gsw_r32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, + PCE_TBL_KEY_4_KEY4_SHIFT, + PCE_TBL_KEY_4_KEY4_SIZE, &value); + rdata->key[4] = value; + gsw_r32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, + PCE_TBL_KEY_3_KEY3_SHIFT, + PCE_TBL_KEY_3_KEY3_SIZE, &value); + rdata->key[3] = value; + gsw_r32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, + PCE_TBL_KEY_2_KEY2_SHIFT, + PCE_TBL_KEY_2_KEY2_SIZE, &value); + rdata->key[2] = value; + gsw_r32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, + PCE_TBL_KEY_1_KEY1_SHIFT, + PCE_TBL_KEY_1_KEY1_SIZE, &value); + rdata->key[1] = value; + gsw_r32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, + PCE_TBL_KEY_0_KEY0_SHIFT, + PCE_TBL_KEY_0_KEY0_SIZE, &value); + rdata->key[0] = value; + + gsw_r32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, + PCE_TBL_VAL_15_VAL15_SHIFT, + PCE_TBL_VAL_15_VAL15_SIZE, &value); + rdata->val[15] = value; + gsw_r32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, + PCE_TBL_VAL_14_VAL14_SHIFT, + PCE_TBL_VAL_14_VAL14_SIZE, &value); + rdata->val[14] = value; + gsw_r32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, + PCE_TBL_VAL_13_VAL13_SHIFT, + PCE_TBL_VAL_13_VAL13_SIZE, &value); + rdata->val[13] = value; + gsw_r32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, + PCE_TBL_VAL_12_VAL12_SHIFT, + PCE_TBL_VAL_12_VAL12_SIZE, &value); + rdata->val[12] = value; + gsw_r32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, + PCE_TBL_VAL_11_VAL11_SHIFT, + PCE_TBL_VAL_11_VAL11_SIZE, &value); + rdata->val[11] = value; + gsw_r32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, + PCE_TBL_VAL_10_VAL10_SHIFT, + PCE_TBL_VAL_10_VAL10_SIZE, &value); + rdata->val[10] = value; + gsw_r32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, + PCE_TBL_VAL_9_VAL9_SHIFT, + PCE_TBL_VAL_9_VAL9_SIZE, &value); + rdata->val[9] = value; + gsw_r32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, + PCE_TBL_VAL_8_VAL8_SHIFT, + PCE_TBL_VAL_8_VAL8_SIZE, &value); + rdata->val[8] = value; + gsw_r32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, + PCE_TBL_VAL_7_VAL7_SHIFT, + PCE_TBL_VAL_7_VAL7_SIZE, &value); + rdata->val[7] = value; + gsw_r32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, + PCE_TBL_VAL_6_VAL6_SHIFT, + PCE_TBL_VAL_6_VAL6_SIZE, &value); + rdata->val[6] = value; + gsw_r32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, + PCE_TBL_VAL_5_VAL5_SHIFT, + PCE_TBL_VAL_5_VAL5_SIZE, &value); + rdata->val[5] = value; + gsw_r32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, + PCE_TBL_VAL_4_VAL4_SHIFT, + PCE_TBL_VAL_4_VAL4_SIZE, &value); + rdata->val[4] = value; + gsw_r32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, + PCE_TBL_VAL_3_VAL3_SHIFT, + PCE_TBL_VAL_3_VAL3_SIZE, &value); + rdata->val[3] = value; + gsw_r32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, + PCE_TBL_VAL_2_VAL2_SHIFT, + PCE_TBL_VAL_2_VAL2_SIZE, &value); + rdata->val[2] = value; + gsw_r32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, + PCE_TBL_VAL_1_VAL1_SHIFT, + PCE_TBL_VAL_1_VAL1_SIZE, &value); + rdata->val[1] = value; + gsw_r32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, + PCE_TBL_VAL_0_VAL0_SHIFT, + PCE_TBL_VAL_0_VAL0_SIZE, &value); + rdata->val[0] = value; + gsw_r32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, + PCE_TBL_MASK_0_MASK0_SHIFT, + PCE_TBL_MASK_0_MASK0_SIZE, &value); + rdata->mask[0] = value; + gsw_r32(cdev, PCE_RTBL_CTRL_VLD_OFFSET, + PCE_RTBL_CTRL_VLD_SHIFT, + PCE_RTBL_CTRL_VLD_SIZE, &value); + rdata->valid = value; + gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); + return GSW_statusOk; +} + +int route_table_write(void *cdev, pctbl_prog_t *rdata) +{ + u32 value; + u16 udata; + + do { + gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, &value); + } while (value); + + gsw_w32(cdev, PCE_TBL_ADDR_ADDR_OFFSET, + PCE_TBL_ADDR_ADDR_SHIFT, PCE_TBL_ADDR_ADDR_SIZE, + rdata->pcindex); + + udata = rdata->table; + gsw_w32(cdev, PCE_RTBL_CTRL_ADDR_OFFSET, + PCE_RTBL_CTRL_ADDR_SHIFT, + PCE_RTBL_CTRL_ADDR_SIZE, udata); + + gsw_w32(cdev, PCE_RTBL_CTRL_OPMOD_OFFSET, + PCE_RTBL_CTRL_OPMOD_SHIFT, + PCE_RTBL_CTRL_OPMOD_SIZE, rdata->op_mode); + + gsw_w32(cdev, PCE_TBL_KEY_15_KEY15_OFFSET, + PCE_TBL_KEY_15_KEY15_SHIFT, + PCE_TBL_KEY_15_KEY15_SIZE, rdata->key[15]); + gsw_w32(cdev, PCE_TBL_KEY_14_KEY14_OFFSET, + PCE_TBL_KEY_14_KEY14_SHIFT, + PCE_TBL_KEY_14_KEY14_SIZE, rdata->key[14]); + gsw_w32(cdev, PCE_TBL_KEY_13_KEY13_OFFSET, + PCE_TBL_KEY_13_KEY13_SHIFT, + PCE_TBL_KEY_13_KEY13_SIZE, rdata->key[13]); + gsw_w32(cdev, PCE_TBL_KEY_12_KEY12_OFFSET, + PCE_TBL_KEY_12_KEY12_SHIFT, + PCE_TBL_KEY_12_KEY12_SIZE, rdata->key[12]); + gsw_w32(cdev, PCE_TBL_KEY_11_KEY11_OFFSET, + PCE_TBL_KEY_11_KEY11_SHIFT, + PCE_TBL_KEY_11_KEY11_SIZE, rdata->key[11]); + gsw_w32(cdev, PCE_TBL_KEY_10_KEY10_OFFSET, + PCE_TBL_KEY_10_KEY10_SHIFT, + PCE_TBL_KEY_10_KEY10_SIZE, rdata->key[10]); + gsw_w32(cdev, PCE_TBL_KEY_9_KEY9_OFFSET, + PCE_TBL_KEY_9_KEY9_SHIFT, + PCE_TBL_KEY_9_KEY9_SIZE, rdata->key[9]); + gsw_w32(cdev, PCE_TBL_KEY_8_KEY8_OFFSET, + PCE_TBL_KEY_8_KEY8_SHIFT, + PCE_TBL_KEY_8_KEY8_SIZE, rdata->key[8]); + gsw_w32(cdev, PCE_TBL_KEY_7_KEY7_OFFSET, + PCE_TBL_KEY_7_KEY7_SHIFT, + PCE_TBL_KEY_7_KEY7_SIZE, rdata->key[7]); + gsw_w32(cdev, PCE_TBL_KEY_6_KEY6_OFFSET, + PCE_TBL_KEY_6_KEY6_SHIFT, + PCE_TBL_KEY_6_KEY6_SIZE, rdata->key[6]); + gsw_w32(cdev, PCE_TBL_KEY_5_KEY5_OFFSET, + PCE_TBL_KEY_5_KEY5_SHIFT, + PCE_TBL_KEY_5_KEY5_SIZE, rdata->key[5]); + gsw_w32(cdev, PCE_TBL_KEY_4_KEY4_OFFSET, + PCE_TBL_KEY_4_KEY4_SHIFT, + PCE_TBL_KEY_4_KEY4_SIZE, rdata->key[4]); + gsw_w32(cdev, PCE_TBL_KEY_3_KEY3_OFFSET, + PCE_TBL_KEY_3_KEY3_SHIFT, + PCE_TBL_KEY_3_KEY3_SIZE, rdata->key[3]); + gsw_w32(cdev, PCE_TBL_KEY_2_KEY2_OFFSET, + PCE_TBL_KEY_2_KEY2_SHIFT, + PCE_TBL_KEY_2_KEY2_SIZE, rdata->key[2]); + gsw_w32(cdev, PCE_TBL_KEY_1_KEY1_OFFSET, + PCE_TBL_KEY_1_KEY1_SHIFT, + PCE_TBL_KEY_1_KEY1_SIZE, rdata->key[1]); + gsw_w32(cdev, PCE_TBL_KEY_0_KEY0_OFFSET, + PCE_TBL_KEY_0_KEY0_SHIFT, + PCE_TBL_KEY_0_KEY0_SIZE, rdata->key[0]); + + gsw_w32(cdev, PCE_TBL_MASK_0_MASK0_OFFSET, + PCE_TBL_MASK_0_MASK0_SHIFT, + PCE_TBL_MASK_0_MASK0_SIZE, rdata->mask[0]); + + gsw_w32(cdev, PCE_TBL_VAL_15_VAL15_OFFSET, + PCE_TBL_VAL_15_VAL15_SHIFT, + PCE_TBL_VAL_15_VAL15_SIZE, rdata->val[15]); + gsw_w32(cdev, PCE_TBL_VAL_14_VAL14_OFFSET, + PCE_TBL_VAL_14_VAL14_SHIFT, + PCE_TBL_VAL_14_VAL14_SIZE, rdata->val[14]); + gsw_w32(cdev, PCE_TBL_VAL_13_VAL13_OFFSET, + PCE_TBL_VAL_13_VAL13_SHIFT, + PCE_TBL_VAL_13_VAL13_SIZE, rdata->val[13]); + gsw_w32(cdev, PCE_TBL_VAL_12_VAL12_OFFSET, + PCE_TBL_VAL_12_VAL12_SHIFT, + PCE_TBL_VAL_12_VAL12_SIZE, rdata->val[12]); + gsw_w32(cdev, PCE_TBL_VAL_11_VAL11_OFFSET, + PCE_TBL_VAL_11_VAL11_SHIFT, + PCE_TBL_VAL_11_VAL11_SIZE, rdata->val[11]); + gsw_w32(cdev, PCE_TBL_VAL_10_VAL10_OFFSET, + PCE_TBL_VAL_10_VAL10_SHIFT, + PCE_TBL_VAL_10_VAL10_SIZE, rdata->val[10]); + gsw_w32(cdev, PCE_TBL_VAL_9_VAL9_OFFSET, + PCE_TBL_VAL_9_VAL9_SHIFT, + PCE_TBL_VAL_9_VAL9_SIZE, rdata->val[9]); + gsw_w32(cdev, PCE_TBL_VAL_8_VAL8_OFFSET, + PCE_TBL_VAL_8_VAL8_SHIFT, + PCE_TBL_VAL_8_VAL8_SIZE, rdata->val[8]); + gsw_w32(cdev, PCE_TBL_VAL_7_VAL7_OFFSET, + PCE_TBL_VAL_7_VAL7_SHIFT, + PCE_TBL_VAL_7_VAL7_SIZE, rdata->val[7]); + gsw_w32(cdev, PCE_TBL_VAL_6_VAL6_OFFSET, + PCE_TBL_VAL_6_VAL6_SHIFT, + PCE_TBL_VAL_6_VAL6_SIZE, rdata->val[6]); + gsw_w32(cdev, PCE_TBL_VAL_5_VAL5_OFFSET, + PCE_TBL_VAL_5_VAL5_SHIFT, + PCE_TBL_VAL_5_VAL5_SIZE, rdata->val[5]); + gsw_w32(cdev, PCE_TBL_VAL_4_VAL4_OFFSET, + PCE_TBL_VAL_4_VAL4_SHIFT, + PCE_TBL_VAL_4_VAL4_SIZE, rdata->val[4]); + gsw_w32(cdev, PCE_TBL_VAL_3_VAL3_OFFSET, + PCE_TBL_VAL_3_VAL3_SHIFT, + PCE_TBL_VAL_3_VAL3_SIZE, rdata->val[3]); + gsw_w32(cdev, PCE_TBL_VAL_2_VAL2_OFFSET, + PCE_TBL_VAL_2_VAL2_SHIFT, + PCE_TBL_VAL_2_VAL2_SIZE, rdata->val[2]); + gsw_w32(cdev, PCE_TBL_VAL_1_VAL1_OFFSET, + PCE_TBL_VAL_1_VAL1_SHIFT, + PCE_TBL_VAL_1_VAL1_SIZE, rdata->val[1]); + gsw_w32(cdev, PCE_TBL_VAL_0_VAL0_OFFSET, + PCE_TBL_VAL_0_VAL0_SHIFT, + PCE_TBL_VAL_0_VAL0_SIZE, rdata->val[0]); + gsw_w32(cdev, PCE_RTBL_CTRL_VLD_OFFSET, + PCE_RTBL_CTRL_VLD_SHIFT, + PCE_RTBL_CTRL_VLD_SIZE, rdata->valid); + gsw_w32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, 1); + + do { + gsw_r32(cdev, PCE_RTBL_CTRL_BAS_OFFSET, + PCE_RTBL_CTRL_BAS_SHIFT, + PCE_RTBL_CTRL_BAS_SIZE, &value); + } while (value != 0); + + gsw_w32(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0, 16, 0); + return GSW_statusOk; +} + +int gsw_pce_table_write(void *cdev, pctbl_prog_t *ptdata) +{ + u32 ctrlval; + u16 i, j; + //pr_err("Enter table write\n"); + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("\n%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + gsw_w32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, ptdata->pcindex); + /*TABLE ADDRESS*/ + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, + PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, + PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_ADWR); + /*KEY REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_key; + + if (ptdata->kformat) + j *= 4; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); + } + + /*MASK REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_mask; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.mask[i], ptdata->mask[i]); + } + + /*VAL REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_val; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.value[i], ptdata->val[i]); +// printk("gswdev->pce_tbl_reg.value[%d] =%x\n", i, gswdev->pce_tbl_reg.value[i]); +// printk("ptdata->val[%d] =%x\n", i, ptdata->val[i]); + } + + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, + PCE_TBL_CTRL_KEYFORM_SIZE, ptdata->kformat); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, + PCE_TBL_CTRL_TYPE_SIZE, ptdata->type); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, + PCE_TBL_CTRL_VLD_SIZE, ptdata->valid); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, + PCE_TBL_CTRL_GMAP_SIZE, ptdata->group); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE, 1); + gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); + //pr_err("Exit table write\n"); + + return GSW_statusOk; +} + +int gsw_pce_table_read(void *cdev, pctbl_prog_t *ptdata) +{ + u32 ctrlval, value; + u16 i, j; + //pr_err("Enter table read\n"); + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("\n%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + gsw_w32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, ptdata->pcindex); + /*TABLE ADDRESS*/ + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, + PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, + PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_ADRD); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, + PCE_TBL_CTRL_KEYFORM_SIZE, ptdata->kformat); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE, 1); + gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + /*KEY REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_key; + + if (ptdata->kformat) + j *= 4; + + for (i = 0; i < j; i++) { + gsw_r32_raw(cdev, gswdev->pce_tbl_reg.key[i], &value); + ptdata->key[i] = value; + } + + /*MASK REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_mask; + + for (i = 0; i < j; i++) { + gsw_r32_raw(cdev, gswdev->pce_tbl_reg.mask[i], &value); + ptdata->mask[i] = value; + } + + /*VAL REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_val; + + for (i = 0; i < j; i++) { + gsw_r32_raw(cdev, gswdev->pce_tbl_reg.value[i], &value); + ptdata->val[i] = value; + } + + ptdata->type = gsw_field_r32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, + PCE_TBL_CTRL_TYPE_SIZE); + ptdata->valid = gsw_field_r32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, + PCE_TBL_CTRL_VLD_SIZE); + ptdata->group = gsw_field_r32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, + PCE_TBL_CTRL_GMAP_SIZE); + gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); + //pr_err("Exit table read\n"); + + return GSW_statusOk; +} + +int gsw_pce_table_key_read(void *cdev, pctbl_prog_t *ptdata) +{ + u32 ctrlval, value; + u16 i, j; + //pr_err("Enter table key read\n"); + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("\n%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, + PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); + + /*KEY REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_key; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); + } + + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, + PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSRD); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, + PCE_TBL_CTRL_KEYFORM_SIZE, 0); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE, 1); + gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + /*VAL REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_val; + + for (i = 0; i < j; i++) { + gsw_r32_raw(cdev, gswdev->pce_tbl_reg.value[i], &value); + ptdata->val[i] = value; + } + + ptdata->type = gsw_field_r32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, + PCE_TBL_CTRL_TYPE_SIZE); + ptdata->valid = gsw_field_r32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, + PCE_TBL_CTRL_VLD_SIZE); + ptdata->group = gsw_field_r32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, + PCE_TBL_CTRL_GMAP_SIZE); + gsw_r32_raw(cdev, PCE_TBL_ADDR_ADDR_OFFSET, &value); + ptdata->pcindex = value; + gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); + //pr_err("Exit table key read\n"); + + return GSW_statusOk; +} + +int gsw_pce_table_key_write(void *cdev, pctbl_prog_t *ptdata) +{ + u32 ctrlval; + u16 i, j; + //pr_err("Enter table key write\n"); + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + + if (gswdev == NULL) { + pr_err("\n%s:%s:%d", __FILE__, __func__, __LINE__); + return GSW_statusErr; + } + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + /*TABLE ADDRESS*/ + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_ADDR_SHIFT, + PCE_TBL_CTRL_ADDR_SIZE, ptdata->table); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_OPMOD_SHIFT, + PCE_TBL_CTRL_OPMOD_SIZE, PCE_OP_MODE_KSWR); + + /*KEY REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_key; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.key[i], ptdata->key[i]); + } + + /*MASK REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_mask; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.mask[i], ptdata->mask[i]); + } + + /*VAL REG*/ + j = gswdev->pce_tbl_info[ptdata->table].num_val; + + for (i = 0; i < j; i++) { + gsw_w32_raw(cdev, gswdev->pce_tbl_reg.value[i], ptdata->val[i]); + } + + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_KEYFORM_SHIFT, + PCE_TBL_CTRL_KEYFORM_SIZE, 0); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_TYPE_SHIFT, + PCE_TBL_CTRL_TYPE_SIZE, ptdata->type); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_VLD_SHIFT, + PCE_TBL_CTRL_VLD_SIZE, ptdata->valid); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_GMAP_SHIFT, + PCE_TBL_CTRL_GMAP_SIZE, ptdata->group); + ctrlval = gsw_field_w32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE, 1); + gsw_w32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, ctrlval); + + do { + gsw_r32_raw(cdev, PCE_TBL_CTRL_BAS_OFFSET, &ctrlval); + } while (gsw_field_r32(ctrlval, PCE_TBL_CTRL_BAS_SHIFT, + PCE_TBL_CTRL_BAS_SIZE)); + + gsw_w32_raw(cdev, PCE_TBL_CTRL_ADDR_OFFSET, 0); + //pr_err("Exit table key write\n"); + + return GSW_statusOk; +} + + +GSW_return_t GSW_DumpTable(void *cdev, GSW_table_t *parm) +{ + ethsw_api_dev_t *gswdev = GSW_PDATA_GET(cdev); + struct core_ops *gsw_ops; + + + gsw_ops = cdev; + + if (parm->tbl_id == 1) { + memset(&parm->ptdata, 0, sizeof(parm->ptdata)); + + parm->ptdata.pcindex = parm->tbl_entry; + parm->ptdata.table = parm->tbl_addr; +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + gsw_pce_table_read(gsw_ops, &parm->ptdata); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + + } + + if (parm->tbl_id == 2) { + memset(&parm->ptdata, 0, sizeof(parm->ptdata)); + + parm->ptdata.pcindex = parm->tbl_entry; + parm->ptdata.table = parm->tbl_addr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pce); +#endif + route_table_read(gsw_ops, &parm->ptdata); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pce); +#endif + + } + + if (parm->tbl_id == 3) { + memset(&parm->bmtable, 0, sizeof(parm->bmtable)); + + parm->bmtable.adr.raw = parm->tbl_entry; + parm->bmtable.tableID = parm->tbl_addr; + parm->bmtable.numValues = parm->bm_numValues; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_bm); +#endif + gsw_bm_table_read(gsw_ops, &parm->bmtable); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_bm); +#endif + + } + + if (parm->tbl_id == 4) { + memset(&parm->pmactable, 0, sizeof(parm->pmactable)); + + parm->pmactable.pmacId = parm->tbl_entry; + parm->pmactable.ptcaddr = parm->tbl_addr; + +#ifdef __KERNEL__ + spin_lock_bh(&gswdev->lock_pmac); +#endif + xwayflow_pmac_table_read(gsw_ops, &parm->pmactable); + +#ifdef __KERNEL__ + spin_unlock_bh(&gswdev->lock_pmac); +#endif + } + + return GSW_statusOk; +} + + + diff --git a/drivers/net/ethernet/lantiq/switch-api/gswip_dev/Makefile b/drivers/net/ethernet/lantiq/switch-api/gswip_dev/Makefile index 06802f02bc1f37a7f1494d3edb4928cac538990a..0067851d798d92714e870e5abd03f8d417705100 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gswip_dev/Makefile +++ b/drivers/net/ethernet/lantiq/switch-api/gswip_dev/Makefile @@ -1 +1,6 @@ -obj-y += gsw_dev.o +# +# Makefile for GSWIP Framework +# + +EXTRA_CFLAGS += -I$(src)/ -I$(src)/../ -I$(src)/../mac/ +obj-$(CONFIG_LTQ_ETHSW_API) += gsw_dev.o diff --git a/drivers/net/ethernet/lantiq/switch-api/gswip_dev/gsw_dev.c b/drivers/net/ethernet/lantiq/switch-api/gswip_dev/gsw_dev.c index 2be42c6d595a7d2bc7fa6b23acc439a65a74873f..9cf3f874e5944f111ac7742bb0a37a28fb7d9f9c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/gswip_dev/gsw_dev.c +++ b/drivers/net/ethernet/lantiq/switch-api/gswip_dev/gsw_dev.c @@ -14,10 +14,10 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include "../mac/xgmac_common.h" -#include "../mac/gswss_api.h" -#include "../gsw_flow_core.h" #include <linux/reset.h> +#include <xgmac_common.h> +#include <gswss_api.h> +#include <gsw_flow_core.h> #define GRX500_MACH_NAME "lantiq,xrx500" #define FALC_MACH_NAME "intel,falconmx" @@ -55,6 +55,21 @@ static struct gsw_cell *gsw_dev_cells; #else /* Static declaration of Resources when device tree is not present */ +static struct resource falc_macsec_res[] = { + /* Macsec Ingress Instance 0 */ + { + .start = 0x18400000, + .end = 0x18420000, + .flags = IORESOURCE_MEM, + }, + /* Macsec Egress Instance 1 */ + { + .start = 0x18420000, + .end = 0x18420000, + .flags = IORESOURCE_MEM, + }, +}; + static struct resource falc_mac_res[] = { /* Adaption Resources */ { @@ -103,38 +118,47 @@ static struct resource grx500_core_res_r[] = { static struct gsw_cell gsw_dev_cells[] = { /* MAC 0 */ { + .name = MAC_DEV_NAME, .cell_id = 0, .device_id = 0, .prod_id = FALCONMX, - .name = MAC_DEV_NAME, .of_compatible = "intel,gsw_mac", - .num_resources = ARRAY_SIZE(mac_res), - .resources = &mac_res; + .num_resources = ARRAY_SIZE(falc_mac_res), + .resources = &falc_mac_res; }, /* MAC 1 */ { + .name = MAC_DEV_NAME, .cell_id = 1, .device_id = 0, .prod_id = FALCONMX, - .name = MAC_DEV_NAME, .of_compatible = "intel,gsw_mac", + .num_resources = ARRAY_SIZE(falc_mac_res), + .resources = &falc_mac_res; }, /* MAC 2 */ { + .name = MAC_DEV_NAME, .cell_id = 2, .device_id = 0, .prod_id = FALCONMX, - .name = MAC_DEV_NAME, .of_compatible = "intel,gsw_mac", + .num_resources = ARRAY_SIZE(falc_mac_res), + .resources = &falc_mac_res; + }, /* GSW CORE L or Falcon Mx */ { + .name = CORE_DEV_NAME, .cell_id = 3, .device_id = 0, .prod_id = FALCONMX, - .name = CORE_DEV_NAME, .of_compatible = "intel,gsw_core", + .num_resources = ARRAY_SIZE(falc_core_res), + .resources = &falc_core_res; + }, + }; #endif @@ -200,6 +224,7 @@ static int gsw_add_macdev(struct gsw_cell *gsw_dev_cell, u32 devid) { struct mac_prv_data *mac_pdata; int ret = 0; + struct resource irqres; /* Allocate the private data for MAC */ mac_pdata = kzalloc(sizeof(struct mac_prv_data), GFP_KERNEL); @@ -215,6 +240,10 @@ static int gsw_add_macdev(struct gsw_cell *gsw_dev_cell, u32 devid) ret = of_property_read_string(gsw_dev_cell->of_node, "phy-mode", &mac_pdata->phy_mode); + of_irq_to_resource_table(gsw_dev_cell->of_node, &irqres, 1); + + mac_pdata->irq_num = irqres.start; + /* Retrieve the speedset */ ret = of_property_read_u32(gsw_dev_cell->of_node, "speed", &mac_pdata->phy_speed); @@ -237,6 +266,7 @@ static int gsw_add_switchdev(struct gsw_cell *gsw_dev_cell, u32 devid) { ethsw_api_dev_t *switch_pdata = NULL; int ret = 0; + struct resource irqres; /* Allocate the private data for Switch */ switch_pdata = kzalloc(sizeof(ethsw_api_dev_t), GFP_KERNEL); @@ -247,6 +277,9 @@ static int gsw_add_switchdev(struct gsw_cell *gsw_dev_cell, u32 devid) gsw_dev_cell->drv_data = (void *)(&switch_pdata->ops); gsw_dev_cell->drv_data_size = sizeof(switch_pdata->ops); + of_irq_to_resource_table(gsw_dev_cell->of_node, &irqres, 1); + switch_pdata->irq_num = irqres.start; + #ifndef CONFIG_OF if (gsw_dev[devid].prod_id == GRX500) { @@ -271,11 +304,80 @@ static int gsw_add_switchdev(struct gsw_cell *gsw_dev_cell, u32 devid) return ret; } +static int update_gsw_dev_cell(struct device_node *np, + int idx, + u32 devid, + int prod_id) +{ + + int ret = 0, r = 0; + + ret = of_property_read_string(np, + "compatible", + &gsw_dev_cells[idx].of_compatible); + ret = of_property_read_u32(np, + "num_resources", + &gsw_dev_cells[idx].num_resources); + + if (ret) + goto failed; + + strcpy(gsw_dev_cells[idx].name, np->name); + + gsw_dev_cells[idx].of_node = np; + + gsw_dev_cells[idx].cell_id = idx; + + /* All node in this GSWSS will have same device id and prod id + */ + gsw_dev_cells[idx].device_id = devid; + gsw_dev_cells[idx].prod_id = prod_id; + + /* Store the product id in gsw_dev structure + Individual drivers can get this info from parent driver data + */ + gsw_dev[devid].prod_id = gsw_dev_cells[idx].prod_id; + + if (gsw_dev_cells[idx].num_resources) { + gsw_dev_cells[idx].resources = + kzalloc((sizeof(struct resource) * + (gsw_dev_cells[idx].num_resources)), + GFP_KERNEL); + + if (!gsw_dev_cells[idx].resources) + return -ENOMEM; + + for (r = 0; r < gsw_dev_cells[idx].num_resources; r++) { + if (of_address_to_resource(np, r, + &gsw_dev_cells[idx].resources[r])) + goto failed; + } + } + + if (of_node_cmp(np->name, MAC_DEV_NAME) == 0) { + ret = gsw_add_macdev(&gsw_dev_cells[idx], devid); + + if (ret) + goto failed; + + gsw_dev[devid].mac_subdevs_cnt++; + } else if (of_node_cmp(np->name, CORE_DEV_NAME) == 0) { + ret = gsw_add_switchdev(&gsw_dev_cells[idx], devid); + + if (ret) + goto failed; + } + + return 0; +failed: + return ret; +} + #ifdef CONFIG_OF static int gsw_parse_dt(struct device_node *base_node) { struct device_node *np = NULL; - int r = 0, idx = 0, ret = 0, prod_id = 0; + int idx = 0, ret = 0, prod_id = 0; u32 devid = 0; /* Get the Product ID */ @@ -299,8 +401,9 @@ static int gsw_parse_dt(struct device_node *base_node) memset(&gsw_dev[devid], 0, sizeof(gsw_dev)); - for_each_child_of_node(base_node, np) - gsw_dev[devid].num_devs++; + for_each_child_of_node(base_node, np) { + gsw_dev[devid].num_devs++; + } gsw_dev_cells = kzalloc((sizeof(struct gsw_cell) * (gsw_dev[devid].num_devs)), @@ -312,65 +415,11 @@ static int gsw_parse_dt(struct device_node *base_node) idx = 0; for_each_child_of_node(base_node, np) { + ret = update_gsw_dev_cell(np, idx, devid, prod_id); - ret = of_property_read_string(np, - "compatible", - &gsw_dev_cells[idx].of_compatible); - ret = of_property_read_u32(np, - "num_resources", - &gsw_dev_cells[idx].num_resources); - - if (ret) + if (ret != 0) goto failed; - strcpy(gsw_dev_cells[idx].name, np->name); - - gsw_dev_cells[idx].of_node = np; - - gsw_dev_cells[idx].cell_id = idx; - - /* All node in this GSWSS will have same device id and prod id - */ - gsw_dev_cells[idx].device_id = devid; - gsw_dev_cells[idx].prod_id = prod_id; - - /* Store the product id in gsw_dev structure - Individual drivers can get this info from parent driver data - */ - gsw_dev[devid].prod_id = gsw_dev_cells[idx].prod_id; - - if (gsw_dev_cells[idx].num_resources) { - gsw_dev_cells[idx].resources = - kzalloc((sizeof(struct resource) * - (gsw_dev_cells[idx].num_resources)), - GFP_KERNEL); - - if (!gsw_dev_cells[idx].resources) - return -ENOMEM; - - for (r = 0; r < gsw_dev_cells[idx].num_resources; r++) { - if (of_address_to_resource(np, r, - &gsw_dev_cells[idx].resources[r])) - goto failed; - } - } - - if (of_node_cmp(np->name, MAC_DEV_NAME) == 0) { - ret = gsw_add_macdev(&gsw_dev_cells[idx], devid); - - if (ret) - goto failed; - - gsw_dev[devid].mac_subdevs_cnt++; - } - - if (of_node_cmp(np->name, CORE_DEV_NAME) == 0) { - ret = gsw_add_switchdev(&gsw_dev_cells[idx], devid); - - if (ret) - goto failed; - } - idx++; } @@ -400,10 +449,9 @@ static int gsw_parse_dt(struct device_node *base_node) if (strcmp(gsw_dev_cells[idx].name, MAC_DEV_NAME) == 0) { gsw_add_macdev(&gsw_dev_cells[idx], devid); gsw_dev[devid].mac_subdevs_cnt++; - } - - if (strcmp(gsw_dev_cells[idx].name, CORE_DEV_NAME) == 0) + } else if (strcmp(gsw_dev_cells[idx].name, CORE_DEV_NAME) == 0) gsw_add_switchdev(&gsw_dev_cells[idx], devid); + } return 0; @@ -463,7 +511,6 @@ static int gsw_add_device(struct device *parent, int id, { struct resource *res; struct platform_device *pdev; - struct device_node *np = NULL; int ret = -ENOMEM; int platform_id; int r; @@ -485,14 +532,7 @@ static int gsw_add_device(struct device *parent, int id, pdev->dev.parent = parent; - if (parent->of_node && cell->of_compatible) { - for_each_child_of_node(parent->of_node, np) { - if (of_device_is_compatible(np, cell->of_compatible)) { - pdev->dev.of_node = np; - break; - } - } - } + pdev->dev.of_node = cell->of_node; if (cell->pdata_size) { ret = platform_device_add_data(pdev, @@ -503,8 +543,9 @@ static int gsw_add_device(struct device *parent, int id, goto fail_res; } - if (cell->drv_data_size) + if (cell->drv_data_size) { platform_set_drvdata(pdev, cell->drv_data); + } for (r = 0; r < cell->num_resources; r++) { res[r].name = cell->resources[r].name; @@ -586,7 +627,6 @@ static int gsw_dev_probe(struct platform_device *pdev) u32 prod_id = 0; struct reset_control *gswss_rst; - if (pdev->dev.of_node) printk("Node name %s\n", base_node->full_name); diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/Makefile b/drivers/net/ethernet/lantiq/switch-api/mac/Makefile index 262eb5c64b3721412d76a0a1eba8a637d0b73c52..8a6a5f728e7d6c271296ae3e35d8be4b5d64252e 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/Makefile +++ b/drivers/net/ethernet/lantiq/switch-api/mac/Makefile @@ -1,4 +1,20 @@ -obj-y += mac_driver.o +# +# Makefile for MAC +# -mac_driver-objs := mac_drv.o xgmac_main.o xgmac_debug.o xgmac_mtl_api.o xgmac_ptp.o xgmac_mac_api.o xgmac_cli.o xgmac_mdio.o mac_cfg.o gswss_api.o gswss_mac_api.o lmac_api.o +EXTRA_CFLAGS += -I$(src) +obj-$(CONFIG_LTQ_ETHSW_API) += mac_driver.o + +mac_driver-objs += mac_drv.o +mac_driver-objs += xgmac_main.o +mac_driver-objs += xgmac_debug.o +mac_driver-objs += xgmac_mtl_api.o +mac_driver-objs += xgmac_ptp.o +mac_driver-objs += xgmac_mac_api.o +mac_driver-objs += xgmac_cli.o +mac_driver-objs += xgmac_mdio.o +mac_driver-objs += mac_cfg.o +mac_driver-objs += gswss_api.o +mac_driver-objs += gswss_mac_api.o +mac_driver-objs += lmac_api.o diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.c b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.c index 3c31ac173536d10291ba4dd183ed57f6548bc4bf..a81cef0c650702114d6dcbe31669dc1ba0b5f65d 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.c @@ -7,7 +7,7 @@ * ******************************************************************************/ -#include "gswss_api.h" +#include <gswss_api.h> int gswss_cfg0_1588(void *pdev, u32 ref_time, u32 dig_time, u32 bin_time, u32 pps_sel) @@ -15,96 +15,94 @@ int gswss_cfg0_1588(void *pdev, u32 ref_time, u32 dig_time, u32 bin_time, struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 cfg0; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif cfg0 = GSWSS_RGRD(pdata, CFG0_1588); if (ref_time == 0) - xgmac_printf("\tREF_TIME: PON_PCS is the master\n"); + mac_printf("\tREF_TIME: PON_PCS is the master\n"); else if (ref_time == 1) - xgmac_printf("\tREF_TIME: PCIE0 is the master\n"); + mac_printf("\tREF_TIME: PCIE0 is the master\n"); else if (ref_time == 2) - xgmac_printf("\tREF_TIME: PCIE1 is the master\n"); + mac_printf("\tREF_TIME: PCIE1 is the master\n"); else if (ref_time == 3) - xgmac_printf("\tREF_TIME: XGMAC2 is the master\n"); + mac_printf("\tREF_TIME: XGMAC2 is the master\n"); else if (ref_time == 4) - xgmac_printf("\tREF_TIME: XGMAC3 is the master\n"); + mac_printf("\tREF_TIME: XGMAC3 is the master\n"); else if (ref_time == 5) - xgmac_printf("\tREF_TIME: XGMAC4 is the master\n"); + mac_printf("\tREF_TIME: XGMAC4 is the master\n"); else { - xgmac_printf("\tREF_TIME: Wrong Value"); + mac_printf("\tREF_TIME: Wrong Value"); goto end; } if (dig_time == 0) - xgmac_printf("\tDIG_TIME: PON_PCS is the master\n"); + mac_printf("\tDIG_TIME: PON_PCS is the master\n"); else if (dig_time == 1) - xgmac_printf("\tDIG_TIME: PCIE0 is the master\n"); + mac_printf("\tDIG_TIME: PCIE0 is the master\n"); else if (dig_time == 2) - xgmac_printf("\tDIG_TIME: PCIE1 is the master\n"); + mac_printf("\tDIG_TIME: PCIE1 is the master\n"); else if (dig_time == 3) - xgmac_printf("\tDIG_TIME: XGMAC2 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC2 is the master\n"); else if (dig_time == 4) - xgmac_printf("\tDIG_TIME: XGMAC3 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC3 is the master\n"); else if (dig_time == 5) - xgmac_printf("\tDIG_TIME: XGMAC4 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC4 is the master\n"); else { - xgmac_printf("\tDIG_TIME: Wrong Value"); + mac_printf("\tDIG_TIME: Wrong Value"); goto end; } if (bin_time == 0) - xgmac_printf("\tBIN_TIME: PON_PCS is the master\n"); + mac_printf("\tBIN_TIME: PON_PCS is the master\n"); else if (bin_time == 1) - xgmac_printf("\tBIN_TIME: PCIE0 is the master\n"); + mac_printf("\tBIN_TIME: PCIE0 is the master\n"); else if (bin_time == 2) - xgmac_printf("\tBIN_TIME: PCIE1 is the master\n"); + mac_printf("\tBIN_TIME: PCIE1 is the master\n"); else if (bin_time == 3) - xgmac_printf("\tBIN_TIME: XGMAC2 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC2 is the master\n"); else if (bin_time == 4) - xgmac_printf("\tBIN_TIME: XGMAC3 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC3 is the master\n"); else if (bin_time == 5) - xgmac_printf("\tBIN_TIME: XGMAC4 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC4 is the master\n"); else { - xgmac_printf("\tBIN_TIME: Wrong Value"); + mac_printf("\tBIN_TIME: Wrong Value"); goto end; } if (pps_sel == 0) - xgmac_printf("\tPPS_SEL: PON_PCS is the master\n"); + mac_printf("\tPPS_SEL: PON_PCS is the master\n"); else if (pps_sel == 1) - xgmac_printf("\tPPS_SEL: PCIE0 is the master\n"); + mac_printf("\tPPS_SEL: PCIE0 is the master\n"); else if (pps_sel == 2) - xgmac_printf("\tPPS_SEL: PCIE1 is the master\n"); + mac_printf("\tPPS_SEL: PCIE1 is the master\n"); else if (pps_sel == 3) - xgmac_printf("\tPPS_SEL: XGMAC2 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC2 is the master\n"); else if (pps_sel == 4) - xgmac_printf("\tPPS_SEL: XGMAC3 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC3 is the master\n"); else if (pps_sel == 5) - xgmac_printf("\tPPS_SEL: XGMAC4 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC4 is the master\n"); else if (pps_sel == 6) - xgmac_printf("\tPPS_SEL: PON PPS100US is the master\n"); + mac_printf("\tPPS_SEL: PON PPS100US is the master\n"); else if (pps_sel == 7) - xgmac_printf("\tPPS_SEL: Software trigger\n"); + mac_printf("\tPPS_SEL: Software trigger\n"); else { - xgmac_printf("\tPPS_SEL: Wrong Value"); + mac_printf("\tPPS_SEL: Wrong Value"); goto end; } - GSWSS_SET_BITS(cfg0, CFG0_1588, REFTIME, ref_time); - GSWSS_SET_BITS(cfg0, CFG0_1588, DIGTIME, dig_time); - GSWSS_SET_BITS(cfg0, CFG0_1588, BINTIME, bin_time); - GSWSS_SET_BITS(cfg0, CFG0_1588, PPSSEL, pps_sel); + MAC_SET_VAL(cfg0, CFG0_1588, REFTIME, ref_time); + MAC_SET_VAL(cfg0, CFG0_1588, DIGTIME, dig_time); + MAC_SET_VAL(cfg0, CFG0_1588, BINTIME, bin_time); + MAC_SET_VAL(cfg0, CFG0_1588, PPSSEL, pps_sel); GSWSS_RGWR(pdata, CFG0_1588, cfg0); end: -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -116,77 +114,77 @@ int gswss_get_cfg0_1588(void *pdev, u32 *ref_time, u32 *dig_time, struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 cfg0; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; +#ifdef __KERNEL__ + - spin_lock_irqsave(&pdata->adap_lock, flags); + spin_lock_bh(&pdata->adap_lock); #endif cfg0 = GSWSS_RGRD(pdata, CFG0_1588); - *ref_time = GSWSS_GET_BITS(cfg0, CFG0_1588, REFTIME); - *dig_time = GSWSS_GET_BITS(cfg0, CFG0_1588, DIGTIME); - *bin_time = GSWSS_GET_BITS(cfg0, CFG0_1588, BINTIME); - *pps_sel = GSWSS_GET_BITS(cfg0, CFG0_1588, PPSSEL); + *ref_time = MAC_GET_VAL(cfg0, CFG0_1588, REFTIME); + *dig_time = MAC_GET_VAL(cfg0, CFG0_1588, DIGTIME); + *bin_time = MAC_GET_VAL(cfg0, CFG0_1588, BINTIME); + *pps_sel = MAC_GET_VAL(cfg0, CFG0_1588, PPSSEL); if (*ref_time == 0) - xgmac_printf("\tREF_TIME: PON_PCS is the master\n"); + mac_printf("\tREF_TIME: PON_PCS is the master\n"); else if (*ref_time == 1) - xgmac_printf("\tREF_TIME: PCIE0 is the master\n"); + mac_printf("\tREF_TIME: PCIE0 is the master\n"); else if (*ref_time == 2) - xgmac_printf("\tREF_TIME: PCIE1 is the master\n"); + mac_printf("\tREF_TIME: PCIE1 is the master\n"); else if (*ref_time == 3) - xgmac_printf("\tREF_TIME: XGMAC2 is the master\n"); + mac_printf("\tREF_TIME: XGMAC2 is the master\n"); else if (*ref_time == 4) - xgmac_printf("\tREF_TIME: XGMAC3 is the master\n"); + mac_printf("\tREF_TIME: XGMAC3 is the master\n"); else if (*ref_time == 5) - xgmac_printf("\tREF_TIME: XGMAC4 is the master\n"); + mac_printf("\tREF_TIME: XGMAC4 is the master\n"); if (*dig_time == 0) - xgmac_printf("\tDIG_TIME: PON_PCS is the master\n"); + mac_printf("\tDIG_TIME: PON_PCS is the master\n"); else if (*dig_time == 1) - xgmac_printf("\tDIG_TIME: PCIE0 is the master\n"); + mac_printf("\tDIG_TIME: PCIE0 is the master\n"); else if (*dig_time == 2) - xgmac_printf("\tDIG_TIME: PCIE1 is the master\n"); + mac_printf("\tDIG_TIME: PCIE1 is the master\n"); else if (*dig_time == 3) - xgmac_printf("\tDIG_TIME: XGMAC2 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC2 is the master\n"); else if (*dig_time == 4) - xgmac_printf("\tDIG_TIME: XGMAC3 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC3 is the master\n"); else if (*dig_time == 5) - xgmac_printf("\tDIG_TIME: XGMAC4 is the master\n"); + mac_printf("\tDIG_TIME: XGMAC4 is the master\n"); if (*bin_time == 0) - xgmac_printf("\tBIN_TIME: PON_PCS is the master\n"); + mac_printf("\tBIN_TIME: PON_PCS is the master\n"); else if (*bin_time == 1) - xgmac_printf("\tBIN_TIME: PCIE0 is the master\n"); + mac_printf("\tBIN_TIME: PCIE0 is the master\n"); else if (*bin_time == 2) - xgmac_printf("\tBIN_TIME: PCIE1 is the master\n"); + mac_printf("\tBIN_TIME: PCIE1 is the master\n"); else if (*bin_time == 3) - xgmac_printf("\tBIN_TIME: XGMAC2 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC2 is the master\n"); else if (*bin_time == 4) - xgmac_printf("\tBIN_TIME: XGMAC3 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC3 is the master\n"); else if (*bin_time == 5) - xgmac_printf("\tBIN_TIME: XGMAC4 is the master\n"); + mac_printf("\tBIN_TIME: XGMAC4 is the master\n"); if (*pps_sel == 0) - xgmac_printf("\tPPS_SEL: PON_PCS is the master\n"); + mac_printf("\tPPS_SEL: PON_PCS is the master\n"); else if (*pps_sel == 1) - xgmac_printf("\tPPS_SEL: PCIE0 is the master\n"); + mac_printf("\tPPS_SEL: PCIE0 is the master\n"); else if (*pps_sel == 2) - xgmac_printf("\tPPS_SEL: PCIE1 is the master\n"); + mac_printf("\tPPS_SEL: PCIE1 is the master\n"); else if (*pps_sel == 3) - xgmac_printf("\tPPS_SEL: XGMAC2 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC2 is the master\n"); else if (*pps_sel == 4) - xgmac_printf("\tPPS_SEL: XGMAC3 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC3 is the master\n"); else if (*pps_sel == 5) - xgmac_printf("\tPPS_SEL: XGMAC4 is the master\n"); + mac_printf("\tPPS_SEL: XGMAC4 is the master\n"); else if (*pps_sel == 6) - xgmac_printf("\tPPS_SEL: PON PPS100US is the master\n"); + mac_printf("\tPPS_SEL: PON PPS100US is the master\n"); else if (*pps_sel == 7) - xgmac_printf("\tPPS_SEL: Software trigger\n"); + mac_printf("\tPPS_SEL: Software trigger\n"); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -197,23 +195,21 @@ int gswss_macsec_reset(void *pdev, u32 reset) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 macsec_en; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif macsec_en = GSWSS_RGRD(pdata, MACSEC_EN); - GSWSS_SET_BITS(macsec_en, MACSEC_EN, RES, reset); + MAC_SET_VAL(macsec_en, MACSEC_EN, RES, reset); - xgmac_printf("GSWSS: MACSEC reset : %s\n", - reset ? "ENABLED" : "DISABLED"); + mac_printf("GSWSS: MACSEC reset : %s\n", + reset ? "ENABLED" : "DISABLED"); GSWSS_RGWR(pdata, MACSEC_EN, macsec_en); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -224,20 +220,18 @@ int gswss_get_macsec_reset(void *pdev) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 macsec_en, reset; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif macsec_en = GSWSS_RGRD(pdata, MACSEC_EN); - reset = GSWSS_GET_BITS(macsec_en, MACSEC_EN, RES); + reset = MAC_GET_VAL(macsec_en, MACSEC_EN, RES); - xgmac_printf("GSWSS: MACSEC reset : %s\n", - reset ? "ENABLED" : "DISABLED"); + mac_printf("GSWSS: MACSEC reset : %s\n", + reset ? "ENABLED" : "DISABLED"); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -248,22 +242,20 @@ int gswss_switch_ss_reset(void *pdev) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 core_reset; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif core_reset = GSWSS_RGRD(pdata, GSWIP_CFG); - xgmac_printf("Switch Subsys Resetting\n"); + mac_printf("Switch Subsys Resetting\n"); - GSWSS_SET_BITS(core_reset, GSWIP_CFG, SS_HWRES, 1); + MAC_SET_VAL(core_reset, GSWIP_CFG, SS_HWRES, 1); GSWSS_RGWR(pdata, GSWIP_CFG, core_reset); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -274,19 +266,19 @@ int gswss_get_switch_ss_reset(void *pdev) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 core_reset, reset; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; +#ifdef __KERNEL__ + - spin_lock_irqsave(&pdata->adap_lock, flags); + spin_lock_bh(&pdata->adap_lock); #endif core_reset = GSWSS_RGRD(pdata, GSWIP_CFG); - reset = GSWSS_GET_BITS(core_reset, GSWIP_CFG, SS_HWRES); + reset = MAC_GET_VAL(core_reset, GSWIP_CFG, SS_HWRES); - xgmac_printf("Switch Subsys Reset %s\n", - reset ? "ENABLED" : "DISABLED"); + mac_printf("Switch Subsys Reset %s\n", + reset ? "ENABLED" : "DISABLED"); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -297,36 +289,34 @@ int gswss_set_clkmode(void *pdev, u32 clk_mode) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 clk_mode_cfg; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif clk_mode_cfg = GSWSS_RGRD(pdata, GSWIP_CFG); - xgmac_printf("GSWSS: Clock Mode Changing to :"); + mac_printf("GSWSS: Clock Mode Changing to :"); if (clk_mode == 0) - xgmac_printf("%s\n", "NCO1 - 666 Mhz"); + mac_printf("%s\n", "NCO1 - 666 Mhz"); else if (clk_mode == 1) - xgmac_printf("%s\n", "NCO2 - 450 Mhz"); + mac_printf("%s\n", "NCO2 - 450 Mhz"); else if (clk_mode == 2) - xgmac_printf("%s\n", "Auto Mode (666/450) Mhz"); + mac_printf("%s\n", "Auto Mode (666/450) Mhz"); else if (clk_mode == 3) - xgmac_printf("%s\n", "Auto Mode (666/450) Mhz"); + mac_printf("%s\n", "Auto Mode (666/450) Mhz"); else { - xgmac_printf("%s\n", "Wrong Value"); + mac_printf("%s\n", "Wrong Value"); goto end; } - GSWSS_SET_BITS(clk_mode_cfg, GSWIP_CFG, CLK_MD, clk_mode); + MAC_SET_VAL(clk_mode_cfg, GSWIP_CFG, CLK_MD, clk_mode); GSWSS_RGWR(pdata, GSWIP_CFG, clk_mode_cfg); end: -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -338,28 +328,26 @@ u32 gswss_get_clkmode(void *pdev) u32 clk_mode_cfg; u32 clk_mode; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif clk_mode_cfg = GSWSS_RGRD(pdata, GSWIP_CFG); - clk_mode = GSWSS_GET_BITS(clk_mode_cfg, GSWIP_CFG, CLK_MD); + clk_mode = MAC_GET_VAL(clk_mode_cfg, GSWIP_CFG, CLK_MD); - xgmac_printf("GSWSS: Clock Mode Got :"); + mac_printf("GSWSS: Clock Mode Got :"); if (clk_mode == 0) - xgmac_printf("%s\n", "NCO1 - 666 Mhz"); + mac_printf("%s\n", "NCO1 - 666 Mhz"); else if (clk_mode == 1) - xgmac_printf("%s\n", "NCO2 - 450 Mhz"); + mac_printf("%s\n", "NCO2 - 450 Mhz"); else if (clk_mode == 2) - xgmac_printf("%s\n", "Auto Mode (666/450) Mhz"); + mac_printf("%s\n", "Auto Mode (666/450) Mhz"); else if (clk_mode == 3) - xgmac_printf("%s\n", "Auto Mode (666/450) Mhz"); + mac_printf("%s\n", "Auto Mode (666/450) Mhz"); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return clk_mode; @@ -370,21 +358,19 @@ int gswss_switch_core_enable(void *pdev, u32 enable) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 core_en; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif core_en = GSWSS_RGRD(pdata, GSWIP_CFG); - xgmac_printf("Switch Core: %s\n", enable ? "ENABLED" : "DISABLED"); + mac_printf("Switch Core: %s\n", enable ? "ENABLED" : "DISABLED"); - GSWSS_SET_BITS(core_en, GSWIP_CFG, CORE_SE, enable); + MAC_SET_VAL(core_en, GSWIP_CFG, CORE_SE, enable); GSWSS_RGWR(pdata, GSWIP_CFG, core_en); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; } @@ -394,19 +380,17 @@ int gswss_get_switch_core_enable(void *pdev) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 core_en, enable; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif core_en = GSWSS_RGRD(pdata, GSWIP_CFG); - enable = GSWSS_GET_BITS(core_en, GSWIP_CFG, CORE_SE); + enable = MAC_GET_VAL(core_en, GSWIP_CFG, CORE_SE); - xgmac_printf("Switch Core: %s\n", enable ? "ENABLED" : "DISABLED"); + mac_printf("Switch Core: %s\n", enable ? "ENABLED" : "DISABLED"); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; } @@ -415,32 +399,27 @@ int gswss_set_macsec_to_mac(void *pdev, u32 mac_idx, u32 enable) { struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 macsec_en; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; -#endif - if (!enable) { - xgmac_printf("GSWSS: MACSEC to MAC mapping : DISABLED\n"); - GSWSS_SET_BITS(macsec_en, MACSEC_EN, SEL, 0); - return 0; - } - -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif - - mac_idx += 2; - macsec_en = GSWSS_RGRD(pdata, MACSEC_EN); - GSWSS_SET_BITS(macsec_en, MACSEC_EN, SEL, mac_idx); + mac_idx += 2; - xgmac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", mac_idx); + if (enable) { + mac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", + mac_idx); + MAC_SET_VAL(macsec_en, MACSEC_EN, SEL, mac_idx); + } else { + mac_printf("GSWSS: MACSEC to MAC mapping : DISABLED\n"); + MAC_SET_VAL(macsec_en, MACSEC_EN, SEL, 0); + } GSWSS_RGWR(pdata, MACSEC_EN, macsec_en); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return 0; @@ -451,61 +430,78 @@ int gswss_get_macsec_to_mac(void *pdev) struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); u32 macsec_en, mac_idx; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); +#endif + macsec_en = GSWSS_RGRD(pdata, MACSEC_EN); + + mac_idx = MAC_GET_VAL(macsec_en, MACSEC_EN, SEL); - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); +#endif + return mac_idx; +} + + +int gswss_dbg_macsec_to_mac(void *pdev) +{ + struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); + u32 macsec_en, mac_idx; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif macsec_en = GSWSS_RGRD(pdata, MACSEC_EN); - mac_idx = GSWSS_GET_BITS(macsec_en, MACSEC_EN, SEL); + mac_idx = MAC_GET_VAL(macsec_en, MACSEC_EN, SEL); if (mac_idx == 0) - xgmac_printf("GSWSS: MACSEC Disabled\n"); + mac_printf("GSWSS: MACSEC Disabled\n"); else if (mac_idx == 2) - xgmac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", - mac_idx); + mac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", + mac_idx); else if (mac_idx == 3) - xgmac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", - mac_idx); + mac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", + mac_idx); else if (mac_idx == 4) - xgmac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", - mac_idx); + mac_printf("GSWSS: MACSEC enabled to MAC %d data traffic\n", + mac_idx); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return mac_idx; } +/* Calling from Interrupt Context, so no lock required. */ int gswss_set_interrupt(void *pdev, u32 mod, u32 idx, u32 enable) { struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); - u32 mac_int_en0, mac_int_en1, val; + u32 mac_int_en0, mac_int_en1; int ret = 0; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); -#endif - - mac_int_en0 = GSWSS_RGRD(pdata, GSWIPSS_IER0); - mac_int_en1 = GSWSS_RGRD(pdata, GSWIPSS_IER1); - - val = enable ? 1 : 0; - switch (mod) { case XGMAC: + //mac_printf("XGMAC %d: Interrupt %s\n", idx, + // enable ? "ENABLED" : "DISABLED"); + + mac_int_en0 = GSWSS_RGRD(pdata, GSWIPSS_IER0); idx += GSWIPSS_IER0_XGMAC2_POS; - SET_N_BITS(mac_int_en0, idx, GSWIPSS_IER0_XGMAC2_WIDTH, val); + SET_N_BITS(mac_int_en0, idx, GSWIPSS_IER0_XGMAC2_WIDTH, enable); + GSWSS_RGWR(pdata, GSWIPSS_IER0, mac_int_en0); break; case LINK: + mac_printf("LINK %d: Interrupt %s\n", idx, + enable ? "ENABLED" : "DISABLED"); + + mac_int_en1 = GSWSS_RGRD(pdata, GSWIPSS_IER1); idx += GSWIPSS_IER1_LINK2_POS; - SET_N_BITS(mac_int_en1, idx, GSWIPSS_IER1_LINK2_WIDTH, val); + SET_N_BITS(mac_int_en1, idx, GSWIPSS_IER1_LINK2_WIDTH, enable); + GSWSS_RGWR(pdata, GSWIPSS_IER1, mac_int_en1); break; default: @@ -513,13 +509,6 @@ int gswss_set_interrupt(void *pdev, u32 mod, u32 idx, u32 enable) break; } - GSWSS_RGWR(pdata, GSWIPSS_IER0, mac_int_en0); - GSWSS_RGWR(pdata, GSWIPSS_IER1, mac_int_en1); - -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); -#endif - return ret; } @@ -529,11 +518,10 @@ int gswss_get_int_en_sts(void *pdev) u32 reg_val, reg_val1; int ret = 0, i = 0; u32 mac_int_isr0, mac_int_isr1; + u32 max_mac = gsw_get_mac_subifcnt(0); -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif mac_int_isr0 = GSWSS_RGRD(pdata, GSWIPSS_ISR0); @@ -541,68 +529,53 @@ int gswss_get_int_en_sts(void *pdev) reg_val = GSWSS_RGRD(pdata, GSWIPSS_IER0); reg_val1 = GSWSS_RGRD(pdata, GSWIPSS_IER1); - xgmac_printf("GSWIPSS_IER0 %08x\n", reg_val); - xgmac_printf("GSWIPSS_IER1 %08x\n", reg_val1); - xgmac_printf("GSWIPSS_ISR0 %08x\n", mac_int_isr0); - xgmac_printf("GSWIPSS_ISR1 %08x\n", mac_int_isr1); - - for (i = 10; i < 13; i++) { - xgmac_printf("\tXGMAC %d INT EN: %s\n", - (i - 8), - GET_N_BITS(reg_val, i, 1) ? - "ENABLED" : - "DISABLED"); - xgmac_printf("\tXGMAC %d INT STS: %s\n", - (i - 8), - GET_N_BITS(mac_int_isr0, i, 1) ? - "ENABLED" : - "DISABLED"); + mac_printf("GSWIPSS_IER0 %08x\n", reg_val); + mac_printf("GSWIPSS_IER1 %08x\n", reg_val1); + mac_printf("GSWIPSS_ISR0 %08x\n", mac_int_isr0); + mac_printf("GSWIPSS_ISR1 %08x\n", mac_int_isr1); + + for (i = 0; i < max_mac; i++) { + mac_printf("\tXGMAC %d INT EN: %s\n", + i, + GET_N_BITS(reg_val, GSWIPSS_IER0_XGMAC2_POS + i, 1) ? + "ENABLED" : + "DISABLED"); + mac_printf("\tXGMAC %d INT STS: %s\n", + i, + GET_N_BITS(mac_int_isr0, GSWIPSS_ISR0_XGMAC2_POS + i, 1) ? + "ENABLED" : + "DISABLED"); + + mac_printf("\tLINK %d INT EN: %s\n", + i, GET_N_BITS(reg_val1, GSWIPSS_IER1_LINK2_POS + i, 1) ? + "ENABLED" : + "DISABLED"); + mac_printf("\tLINK %d INT STS: %s\n", + i, GET_N_BITS(mac_int_isr1, GSWIPSS_ISR1_LINK2_POS + i, 1) ? + "ENABLED" : + "DISABLED"); } - for (i = 2; i < 5; i++) { - xgmac_printf("\tLINK %d INT EN: %s\n", - i, GET_N_BITS(reg_val1, i, 1) ? - "ENABLED" : - "DISABLED"); - xgmac_printf("\tLINK %d INT STS: %s\n", - i, GET_N_BITS(mac_int_isr1, i, 1) ? - "ENABLED" : - "DISABLED"); - } - -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return ret; } -int gswss_get_int_stat(void *pdev, u32 mod, u32 idx) +/* Calling from Interrupt Context, so no lock required. */ +int gswss_get_int_stat(void *pdev, u32 mod) { struct adap_prv_data *pdata = GET_ADAP_PDATA(pdev); - u32 mac_int_isr0, mac_int_isr1; int ret = 0; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); -#endif - - mac_int_isr0 = GSWSS_RGRD(pdata, GSWIPSS_ISR0); - mac_int_isr1 = GSWSS_RGRD(pdata, GSWIPSS_ISR1); - switch (mod) { case XGMAC: - idx += GSWIPSS_ISR0_XGMAC2_POS; - ret = (GET_N_BITS(mac_int_isr0, idx, - GSWIPSS_IER0_XGMAC2_WIDTH)); + ret = GSWSS_RGRD(pdata, GSWIPSS_ISR0); break; case LINK: - idx += GSWIPSS_ISR1_LINK2_POS; - ret = (GET_N_BITS(mac_int_isr1, idx, - GSWIPSS_IER1_LINK2_WIDTH)); + ret = GSWSS_RGRD(pdata, GSWIPSS_ISR1); break; default: @@ -610,10 +583,6 @@ int gswss_get_int_stat(void *pdev, u32 mod, u32 idx) break; } -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); -#endif - return ret; } @@ -624,10 +593,8 @@ int gswss_set_nco(void *pdev, u32 val, u32 nco_idx) u32 lsb_off, msb_off; int ret = 0; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif if (nco_idx) { @@ -644,14 +611,14 @@ int gswss_set_nco(void *pdev, u32 val, u32 nco_idx) nco_lsb = (val & 0xFFFF); nco_msb = ((val & 0xFFFF0000) >> 16); - xgmac_printf("GSWSS: NCO_LSB Configured to %x\n", nco_lsb); - xgmac_printf("GSWSS: NCO_MSB Configured to %x\n", nco_msb); + mac_printf("GSWSS: NCO_LSB Configured to %x\n", nco_lsb); + mac_printf("GSWSS: NCO_MSB Configured to %x\n", nco_msb); GSWSS_RGWR(pdata, lsb_off, nco_lsb); GSWSS_RGWR(pdata, msb_off, nco_msb); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return ret; @@ -663,10 +630,8 @@ u32 gswss_get_nco(void *pdev, u32 nco_idx) u32 nco_lsb, nco_msb, nco; u32 lsb_off, msb_off; -#if defined(KERNEL_MODE) && KERNEL_MODE - unsigned long flags; - - spin_lock_irqsave(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->adap_lock); #endif if (nco_idx) { @@ -680,13 +645,13 @@ u32 gswss_get_nco(void *pdev, u32 nco_idx) nco_lsb = GSWSS_RGRD(pdata, lsb_off); nco_msb = GSWSS_RGRD(pdata, msb_off); - xgmac_printf("GSWSS: NCO_LSB Got is %x\n", nco_lsb); - xgmac_printf("GSWSS: NCO_MSB Got is %x\n", nco_msb); + mac_printf("GSWSS: NCO_LSB Got is %x\n", nco_lsb); + mac_printf("GSWSS: NCO_MSB Got is %x\n", nco_msb); nco = ((nco_msb << 16) | nco_lsb); -#if defined(KERNEL_MODE) && KERNEL_MODE - spin_unlock_irqrestore(&pdata->adap_lock, flags); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->adap_lock); #endif return nco; diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.h b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.h index 3ac9bb2ccafa4b013bcb7c158f50769dadbd13cf..a41cf194f82ef8709338c6a434379caf3986411c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_api.h @@ -10,8 +10,8 @@ #ifndef _GSWSS_API_H #define _GSWSS_API_H -#include "xgmac_common.h" -#if defined(KERNEL_MODE) && KERNEL_MODE +#include <xgmac_common.h> +#ifdef __KERNEL__ #include <net/switch_api/adap_ops.h> #else #include <adap_ops.h> @@ -59,6 +59,21 @@ #define GSWIPSS_IER0_XGMAC3_WIDTH 1 #define GSWIPSS_IER0_XGMAC4_POS 4 #define GSWIPSS_IER0_XGMAC4_WIDTH 1 +#define GSWIPSS_IER0_XGMAC5_POS 5 +#define GSWIPSS_IER0_XGMAC5_WIDTH 1 +#define GSWIPSS_IER0_XGMAC6_POS 6 +#define GSWIPSS_IER0_XGMAC6_WIDTH 1 +#define GSWIPSS_IER0_XGMAC7_POS 7 +#define GSWIPSS_IER0_XGMAC7_WIDTH 1 +#define GSWIPSS_IER0_XGMAC8_POS 8 +#define GSWIPSS_IER0_XGMAC8_WIDTH 1 +#define GSWIPSS_IER0_XGMAC9_POS 9 +#define GSWIPSS_IER0_XGMAC9_WIDTH 1 +#define GSWIPSS_IER0_XGMAC10_POS 10 +#define GSWIPSS_IER0_XGMAC10_WIDTH 1 +#define GSWIPSS_IER0_XGMAC11_POS 11 +#define GSWIPSS_IER0_XGMAC11_WIDTH 1 + #define GSWIPSS_ISR0_XGMAC2_POS 2 #define GSWIPSS_ISR0_XGMAC2_WIDTH 1 @@ -66,6 +81,22 @@ #define GSWIPSS_ISR0_XGMAC3_WIDTH 1 #define GSWIPSS_ISR0_XGMAC4_POS 4 #define GSWIPSS_ISR0_XGMAC4_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC5_POS 5 +#define GSWIPSS_ISR0_XGMAC5_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC6_POS 6 +#define GSWIPSS_ISR0_XGMAC6_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC7_POS 7 +#define GSWIPSS_ISR0_XGMAC7_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC8_POS 8 +#define GSWIPSS_ISR0_XGMAC8_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC9_POS 9 +#define GSWIPSS_ISR0_XGMAC9_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC10_POS 10 +#define GSWIPSS_ISR0_XGMAC10_WIDTH 1 +#define GSWIPSS_ISR0_XGMAC11_POS 11 +#define GSWIPSS_ISR0_XGMAC11_WIDTH 1 + + #define GSWIPSS_IER1_LINK2_POS 2 #define GSWIPSS_IER1_LINK2_WIDTH 1 @@ -73,6 +104,21 @@ #define GSWIPSS_IER1_LINK3_WIDTH 1 #define GSWIPSS_IER1_LINK4_POS 4 #define GSWIPSS_IER1_LINK4_WIDTH 1 +#define GSWIPSS_IER1_LINK5_POS 5 +#define GSWIPSS_IER1_LINK5_WIDTH 1 +#define GSWIPSS_IER1_LINK6_POS 6 +#define GSWIPSS_IER1_LINK6_WIDTH 1 +#define GSWIPSS_IER1_LINK7_POS 7 +#define GSWIPSS_IER1_LINK7_WIDTH 1 +#define GSWIPSS_IER1_LINK8_POS 8 +#define GSWIPSS_IER1_LINK8_WIDTH 1 +#define GSWIPSS_IER1_LINK9_POS 9 +#define GSWIPSS_IER1_LINK9_WIDTH 1 +#define GSWIPSS_IER1_LINK10_POS 10 +#define GSWIPSS_IER1_LINK10_WIDTH 1 +#define GSWIPSS_IER1_LINK11_POS 11 +#define GSWIPSS_IER1_LINK11_WIDTH 1 + #define GSWIPSS_ISR1_LINK2_POS 2 #define GSWIPSS_ISR1_LINK2_WIDTH 1 @@ -80,6 +126,21 @@ #define GSWIPSS_ISR1_LINK3_WIDTH 1 #define GSWIPSS_ISR1_LINK4_POS 4 #define GSWIPSS_ISR1_LINK4_WIDTH 1 +#define GSWIPSS_ISR1_LINK5_POS 5 +#define GSWIPSS_ISR1_LINK5_WIDTH 1 +#define GSWIPSS_ISR1_LINK6_POS 6 +#define GSWIPSS_ISR1_LINK6_WIDTH 1 +#define GSWIPSS_ISR1_LINK7_POS 7 +#define GSWIPSS_ISR1_LINK7_WIDTH 1 +#define GSWIPSS_ISR1_LINK8_POS 8 +#define GSWIPSS_ISR1_LINK8_WIDTH 1 +#define GSWIPSS_ISR1_LINK9_POS 9 +#define GSWIPSS_ISR1_LINK9_WIDTH 1 +#define GSWIPSS_ISR1_LINK10_POS 10 +#define GSWIPSS_ISR1_LINK10_WIDTH 1 +#define GSWIPSS_ISR1_LINK11_POS 11 +#define GSWIPSS_ISR1_LINK11_WIDTH 1 + #define CFG0_1588_REFTIME_POS 0 #define CFG0_1588_REFTIME_WIDTH 3 @@ -117,22 +178,12 @@ struct adap_prv_data; struct adap_prv_data { u32 flags; u32 ss_addr_base; -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ spinlock_t adap_lock; #endif struct adap_ops ops; }; -#define GSWSS_GET_BITS(var, prefix, field) \ - GET_N_BITS((var), \ - prefix##_##field##_POS, \ - prefix##_##field##_WIDTH) - -#define GSWSS_SET_BITS(var, prefix, field, _val) \ - SET_N_BITS((var), \ - prefix##_##field##_POS, \ - prefix##_##field##_WIDTH, (_val)) - static inline struct adap_prv_data *GET_ADAP_PDATA(void *pdev) { struct adap_prv_data *pdata; @@ -158,7 +209,7 @@ static inline u32 GSWSS_RGRD(struct adap_prv_data *pdata, u32 reg) #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_rd(reg_addr, ®_val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ reg_val = ltq_r32(reg_addr); #endif return reg_val; @@ -178,7 +229,7 @@ static inline void GSWSS_RGWR(struct adap_prv_data *pdata, u32 reg, u32 val) #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_wr(reg_addr, val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ ltq_w32(val, reg_addr); #endif } @@ -196,7 +247,8 @@ int gswss_cfg0_1588(void *pdev, u32 ref_time, u32 dig_time, u32 bin_time, u32 pps_sel); int gswss_set_macsec_to_mac(void *pdev, u32 mac_idx, u32 enable); -int gswss_get_int_stat(void *pdev, u32 mod, u32 idx); +int gswss_get_int_stat(void *pdev, u32 mod); + int gswss_get_int_en_sts(void *pdev); void gswss_test_all_reg(void *pdev); void gswss_check_reg(void *pdev, u32 reg, char *name, int idx, @@ -206,6 +258,7 @@ int gswss_get_cfg0_1588(void *pdev, u32 *ref_time, u32 *dig_time, u32 *bin_time, u32 *pps_sel); u32 gswss_get_clkmode(void *pdev); int gswss_get_macsec_to_mac(void *pdev); +int gswss_dbg_macsec_to_mac(void *pdev); int gswss_get_switch_core_enable(void *pdev); int gswss_get_switch_ss_reset(void *pdev); int gswss_get_macsec_reset(void *pdev); diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.c b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.c index 58009e6bbe9bd902e5e4613d4dc1612f57a4aeb8..a3ccb502b047e3e6bdbf97407301b905f9b901d6 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.c @@ -7,7 +7,7 @@ * ******************************************************************************/ -#include "gswss_mac_api.h" +#include <gswss_mac_api.h> struct adap_prv_data adap_priv_data = { .flags = 0, @@ -52,22 +52,10 @@ struct _gswss_cfg gswss_mac_cfg[] = { "<mtu size>" }, { - "txtstamp", - 4, - "<0/1/2: MacIdx> " - "<sec nsec rec_id>" - }, - { - "cic", - 5, - "<0/1/2: MacIdx> " - "<ttse ostc ost_avail cic>" - }, - { - "tstamp_acc", - 5, + "txtstamp_fifo", + 8, "<0/1/2: MacIdx> " - "<ttse ostc ost_avail cic>" + "<ttse ostc ost_avail cic sec nsec rec_id>" }, { "w", @@ -132,56 +120,36 @@ void gswss_help(void) int i = 0; int num_of_elem = (sizeof(gswss_mac_cfg) / sizeof(struct _gswss_cfg)); - xgmac_printf("\n----GSWSS MAC Commands----\n\n"); + mac_printf("\n----GSWSS MAC Commands----\n\n"); for (i = 0; i < num_of_elem; i++) { if (gswss_mac_cfg[i].help) { -#if defined(KERNEL_MODE) && KERNEL_MODE - xgmac_printf("switch_cli gswss %15s \t %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); -#endif + #if defined(CHIPTEST) && CHIPTEST - xgmac_printf("gsw gswss %15s \t %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); -#endif -#if defined(PC_UTILITY) && PC_UTILITY - xgmac_printf("%15s \t %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); + mac_printf("gsw gswss %15s \t %s\n", + gswss_mac_cfg[i].cmdname, + gswss_mac_cfg[i].help); +#else + mac_printf("switch_cli gswss %15s \t %s\n", + gswss_mac_cfg[i].cmdname, + gswss_mac_cfg[i].help); #endif + } } - xgmac_printf("\n"); + mac_printf("\n"); for (i = 0; i < num_of_elem; i++) { if (gswss_mac_cfg[i].cmdname) { -#if defined(KERNEL_MODE) && KERNEL_MODE - if (!strcmp(gswss_mac_cfg[i].cmdname, "txtstamp")) { - xgmac_printf("switch_cli gswss get %11s \t " - "<0/1/2: MacIdx> <rec_id>\n", - gswss_mac_cfg[i].cmdname); - continue; - } - - if (!strcmp(gswss_mac_cfg[i].cmdname, "w") || - (!strcmp(gswss_mac_cfg[i].cmdname, "r"))) - continue; - - xgmac_printf("switch_cli gswss get %11s \t " - "<0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); -#endif #if defined(CHIPTEST) && CHIPTEST - if (!strcmp(gswss_mac_cfg[i].cmdname, "txtstamp")) { - xgmac_printf("gsw gswss get %11s \t " - "<0/1/2: MacIdx> <rec_id>\n", - gswss_mac_cfg[i].cmdname); + if (!strcmp(gswss_mac_cfg[i].cmdname, "txtstamp_fifo")) { + mac_printf("gsw gswss get %11s \t " + "<0/1/2: MacIdx> <rec_id>\n", + gswss_mac_cfg[i].cmdname); continue; } @@ -189,15 +157,14 @@ void gswss_help(void) (!strcmp(gswss_mac_cfg[i].cmdname, "r"))) continue; - xgmac_printf("gsw gswss get %11s \t <0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); -#endif -#if defined(PC_UTILITY) && PC_UTILITY + mac_printf("gsw gswss get %11s \t <0/1/2: MacIdx> \n", + gswss_mac_cfg[i].cmdname); +#else - if (!strcmp(gswss_mac_cfg[i].cmdname, "txtstamp")) { - xgmac_printf("gswss get %11s \t " - "<0/1/2: MacIdx> <rec_id>\n", - gswss_mac_cfg[i].cmdname); + if (!strcmp(gswss_mac_cfg[i].cmdname, "txtstamp_fifo")) { + mac_printf("switch_cli gswss get %11s \t " + "<0/1/2: MacIdx> <rec_id>\n", + gswss_mac_cfg[i].cmdname); continue; } @@ -205,51 +172,44 @@ void gswss_help(void) (!strcmp(gswss_mac_cfg[i].cmdname, "r"))) continue; - xgmac_printf("gswss get %11s \t <0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); + mac_printf("switch_cli gswss get %11s \t " + "<0/1/2: MacIdx> \n", + gswss_mac_cfg[i].cmdname); #endif + } } num_of_elem = (sizeof(gswss_adap_cfg) / sizeof(struct _gswss_cfg)); - xgmac_printf("\n----GSWSS Adaption Commands----\n\n"); + mac_printf("\n----GSWSS Adaption Commands----\n\n"); for (i = 0; i < num_of_elem; i++) { if (gswss_adap_cfg[i].help) { -#if defined(KERNEL_MODE) && KERNEL_MODE - xgmac_printf("switch_cli gswss %15s \t %s\n", - gswss_adap_cfg[i].cmdname, - gswss_adap_cfg[i].help); -#endif + #if defined(CHIPTEST) && CHIPTEST - xgmac_printf("gsw gswss %15s \t %s\n", , - gswss_adap_cfg[i].cmdname, - gswss_adap_cfg[i].help); -#endif -#if defined(PC_UTILITY) && PC_UTILITY - xgmac_printf("gswss %15s \t %s\n", , - gswss_adap_cfg[i].cmdname, - gswss_adap_cfg[i].help); + mac_printf("gsw gswss %15s \t %s\n", + gswss_adap_cfg[i].cmdname, + gswss_adap_cfg[i].help); +#else + mac_printf("switch_cli gswss %15s \t %s\n", + gswss_adap_cfg[i].cmdname, + gswss_adap_cfg[i].help); #endif } } - xgmac_printf("\n"); + mac_printf("\n"); for (i = 0; i < num_of_elem; i++) { if (gswss_adap_cfg[i].cmdname) { -#if defined(KERNEL_MODE) && KERNEL_MODE - xgmac_printf("switch_cli gswss get %11s \t \n", - gswss_adap_cfg[i].cmdname); -#endif + #if defined(CHIPTEST) && CHIPTEST - xgmac_printf("gsw gswss get %11s \t \n", - gswss_adap_cfg[i].cmdname); -#endif -#if defined(PC_UTILITY) && PC_UTILITY - xgmac_printf("gswss get %11s \t \n", - gswss_adap_cfg[i].cmdname); + mac_printf("gsw gswss get %11s \t \n", + gswss_adap_cfg[i].cmdname); +#else + mac_printf("switch_cli gswss get %11s \t \n", + gswss_adap_cfg[i].cmdname); #endif } } @@ -264,47 +224,17 @@ int gswss_mac_check_args(int argc, char *argv) for (i = 0; i < num_of_elem; i++) { if (!strcmp(argv, gswss_mac_cfg[i].cmdname)) { -#if defined(KERNEL_MODE) && KERNEL_MODE if (argc != (gswss_mac_cfg[i].args + 3)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("switch_cli gswss %s %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); - xgmac_printf("switch_cli gswss get %s " - "<0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); - return -1; - } - -#endif -#if defined(CHIPTEST) && CHIPTEST - - if (argc != (gswss_mac_cfg[i].args + 3)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("gsw gswss %s %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); - xgmac_printf("gsw gswss get %s " - "<0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); - return -1; - } - -#endif -#if defined(PC_UTILITY) && PC_UTILITY - - if (argc != (gswss_mac_cfg[i].args + 2)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("gswss %s %s\n", - gswss_mac_cfg[i].cmdname, - gswss_mac_cfg[i].help); - xgmac_printf("gswss get %s <0/1/2: MacIdx> \n", - gswss_mac_cfg[i].cmdname); + mac_printf("\n--WRONG Command--\n"); + mac_printf("switch_cli gswss %s %s\n", + gswss_mac_cfg[i].cmdname, + gswss_mac_cfg[i].help); + mac_printf("switch_cli gswss get %s " + "<0/1/2: MacIdx> \n", + gswss_mac_cfg[i].cmdname); return -1; } - -#endif } } @@ -316,6 +246,7 @@ struct mac_ops *gswss_get_mac_ops(char *cmd, char *argv, u32 *start_arg) u32 idx, i = 0; int num_of_elem = (sizeof(gswss_mac_cfg) / sizeof(struct _gswss_cfg)); struct mac_ops *ops = NULL; + u32 max_mac = 0; for (i = 0; i < num_of_elem; i++) { if (!strcmp(cmd, gswss_mac_cfg[i].cmdname)) { @@ -323,11 +254,13 @@ struct mac_ops *gswss_get_mac_ops(char *cmd, char *argv, u32 *start_arg) } } + max_mac = gsw_get_mac_subifcnt(0); + idx = mac_nstrtoul(argv, mac_nstrlen(argv), start_arg); - if ((idx < 0) || (idx > 2)) { + if ((idx < 0) || (idx > max_mac)) { gswss_help(); return NULL; } @@ -343,42 +276,17 @@ int gswss_adap_check_args(int argc, char *argv) for (i = 0; i < num_of_elem; i++) { if (!strcmp(argv, gswss_adap_cfg[i].cmdname)) { -#if defined(KERNEL_MODE) && KERNEL_MODE if (argc != (gswss_adap_cfg[i].args + 3)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("switch_cli %s\n", - gswss_adap_cfg[i].help); - xgmac_printf("switch_cli gswss get %s\n", - gswss_adap_cfg[i].cmdname); + mac_printf("\n--WRONG Command--\n"); + mac_printf("switch_cli %s\n", + gswss_adap_cfg[i].help); + mac_printf("switch_cli gswss get %s\n", + gswss_adap_cfg[i].cmdname); return -1; } -#endif -#if defined(CHIPTEST) && CHIPTEST - - if (argc != (gswss_adap_cfg[i].args + 3)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("gsw %s\n", - gswss_adap_cfg[i].help); - xgmac_printf("gsw gswss get %s\n", - gswss_adap_cfg[i].cmdname); - return -1; - } -#endif -#if defined(PC_UTILITY) && PC_UTILITY - - if (argc != (gswss_adap_cfg[i].args + 2)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("%s\n", - gswss_adap_cfg[i].help); - xgmac_printf("gswss get %s\n", - gswss_adap_cfg[i].cmdname); - return -1; - } - -#endif } } @@ -389,8 +297,8 @@ void gswss_wr_reg(void *pdev, u32 reg_off, u32 reg_val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + reg_val); GSWSS_MAC_RGWR(pdata, reg_off, reg_val); } @@ -401,8 +309,8 @@ u32 gswss_rd_reg(void *pdev, u32 reg_off) pdata->reg_val = GSWSS_MAC_RGRD(pdata, reg_off); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - pdata->reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + pdata->reg_val); return pdata->reg_val; } @@ -418,23 +326,17 @@ int gswss_main(u32 argc, u8 *argv[]) u32 mtu; u32 sec, nsec, rec_id; u32 ttse, ostc, ost_avail, cic; - u32 op_mode, addr; + u32 enable; u32 ref_time, dig_time, bin_time, pps_sel; struct mac_ops *ops = NULL; struct adap_ops *adap_ops = gsw_get_adap_ops(0); u32 reg_off, reg_val; -#if defined(PC_UTILITY) && PC_UTILITY - start_arg++; -#endif -#if defined(CHIPTEST) && CHIPTEST - start_arg++; -#endif -#if defined(KERNEL_MODE) && KERNEL_MODE + start_arg++; start_arg++; -#endif + if (argc <= 2) { gswss_help(); @@ -533,14 +435,14 @@ int gswss_main(u32 argc, u8 *argv[]) return -1; gswss_get_mtu(ops); - } else if (!strcmp(argv[start_arg], "txtstamp")) { + } else if (!strcmp(argv[start_arg], "txtstamp_fifo")) { start_arg++; -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ if (argc != 6) { - xgmac_printf("switch_cli gswss get txtstamp" - "<0/1/2: MacIdx> rec_id\n"); + mac_printf("switch_cli gswss get txtstamp_fifo" + "<0/1/2: MacIdx> rec_id\n"); return -1; } @@ -556,20 +458,7 @@ int gswss_main(u32 argc, u8 *argv[]) mac_nstrlen(argv[start_arg]), &start_arg); - gswss_get_txtstamp(ops, rec_id); - } else if (!strcmp(argv[start_arg], "cic")) { - start_arg++; - ops = gswss_get_mac_ops(argv[start_arg - 1], - argv[start_arg], - &start_arg); - - if (!ops) - return -1; - - gswss_get_txtstamp_cic(ops); - } else if (!strcmp(argv[start_arg], "tstamp_acc")) { - start_arg++; - gswss_get_txtstamp_access(ops); + gswss_get_txtstamp_fifo(ops, rec_id); } else if (!strcmp(argv[start_arg], "phymode")) { start_arg++; ops = gswss_get_mac_ops(argv[start_arg - 1], @@ -581,7 +470,7 @@ int gswss_main(u32 argc, u8 *argv[]) gswss_get_phy2mode(ops); } else if (!strcmp(argv[start_arg], "macsec")) { - gswss_get_macsec_to_mac(adap_ops); + gswss_dbg_macsec_to_mac(adap_ops); } else if (!strcmp(argv[start_arg], "cfg_1588")) { gswss_get_cfg0_1588(adap_ops, &ref_time, @@ -737,26 +626,7 @@ int gswss_main(u32 argc, u8 *argv[]) mac_nstrlen(argv[start_arg]), &start_arg); gswss_set_mtu(ops, mtu); - } else if (!strcmp(argv[start_arg], "txtstamp")) { - start_arg++; - ops = gswss_get_mac_ops(argv[start_arg - 1], - argv[start_arg], - &start_arg); - - if (!ops) - return -1; - - sec = mac_nstrtoul(argv[start_arg], - mac_nstrlen(argv[start_arg]), - &start_arg); - nsec = mac_nstrtoul(argv[start_arg], - mac_nstrlen(argv[start_arg]), - &start_arg); - rec_id = mac_nstrtoul(argv[start_arg], - mac_nstrlen(argv[start_arg]), - &start_arg); - gswss_set_txtstamp(ops, sec, nsec, rec_id); - } else if (!strcmp(argv[start_arg], "cic")) { + } else if (!strcmp(argv[start_arg], "txtstamp_fifo")) { start_arg++; ops = gswss_get_mac_ops(argv[start_arg - 1], argv[start_arg], @@ -777,26 +647,17 @@ int gswss_main(u32 argc, u8 *argv[]) cic = mac_nstrtoul(argv[start_arg], mac_nstrlen(argv[start_arg]), &start_arg); - gswss_set_txtstamp_cic(ops, - ttse, ostc, ost_avail, cic); - } else if (!strcmp(argv[start_arg], "tstamp_acc")) { - start_arg++; - ops = gswss_get_mac_ops(argv[start_arg - 1], - argv[start_arg], - &start_arg); - - if (!ops) - return -1; - - op_mode = mac_nstrtoul(argv[start_arg], - mac_nstrlen(argv[start_arg]), - &start_arg); - addr = mac_nstrtoul(argv[start_arg], + sec = mac_nstrtoul(argv[start_arg], + mac_nstrlen(argv[start_arg]), + &start_arg); + nsec = mac_nstrtoul(argv[start_arg], mac_nstrlen(argv[start_arg]), &start_arg); - - gswss_set_txtstamp_access(ops, - op_mode, addr); + rec_id = mac_nstrtoul(argv[start_arg], + mac_nstrlen(argv[start_arg]), + &start_arg); + gswss_set_txtstamp_fifo(ops, ttse, ostc, ost_avail, cic, + sec, nsec, rec_id); } else if (!strcmp(argv[start_arg], "nco")) { start_arg++; @@ -870,9 +731,9 @@ int gswss_xgmac_reset(void *pdev, u32 reset) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, XGMAC_RES, reset); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, XGMAC_RES, reset); - xgmac_printf("GSWSS: Resetting XGMAC %d Module\n", pdata->mac_idx); + mac_printf("GSWSS: Resetting XGMAC %d Module\n", pdata->mac_idx); GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -886,9 +747,9 @@ int gswss_lmac_reset(void *pdev, u32 reset) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, LMAC_RES, reset); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, LMAC_RES, reset); - xgmac_printf("GSWSS: Resetting LMAC %d Module\n", pdata->mac_idx); + mac_printf("GSWSS: Resetting LMAC %d Module\n", pdata->mac_idx); GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -902,9 +763,9 @@ int gswss_adap_reset(void *pdev, u32 reset) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, ADAP_RES, reset); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, ADAP_RES, reset); - xgmac_printf("GSWSS: Resetting ADAP %d Module\n", pdata->mac_idx); + mac_printf("GSWSS: Resetting ADAP %d Module\n", pdata->mac_idx); GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -918,10 +779,10 @@ int gswss_mac_enable(void *pdev, u32 enable) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, MAC_EN, enable); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, MAC_EN, enable); - xgmac_printf("GSWSS: MAC %d: %s\n", pdata->mac_idx, - enable ? "ENABLED" : "DISABLED"); + mac_printf("GSWSS: MAC %d: %s\n", pdata->mac_idx, + enable ? "ENABLED" : "DISABLED"); GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -935,15 +796,15 @@ int gswss_get_mac_reset(void *pdev) int ret = 0, i = 0; mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - reset = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, XGMAC_RES); - xgmac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), - reset ? "ENABLED" : "DISABLED"); - reset = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, LMAC_RES); - xgmac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), - reset ? "ENABLED" : "DISABLED"); - reset = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, ADAP_RES); - xgmac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), - reset ? "ENABLED" : "DISABLED"); + reset = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, XGMAC_RES); + mac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), + reset ? "ENABLED" : "DISABLED"); + reset = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, LMAC_RES); + mac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), + reset ? "ENABLED" : "DISABLED"); + reset = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, ADAP_RES); + mac_printf("\tXGMAC %d Reset Bit: %s\n", (i + 2), + reset ? "ENABLED" : "DISABLED"); return ret; } @@ -955,8 +816,8 @@ int gswss_get_mac_en(void *pdev) int ret = 0, i = 0; mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - enable = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, MAC_EN); - xgmac_printf("GSWSS: MAC %d: %s\n", i, enable ? "ENABLED" : "DISABLED"); + enable = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, MAC_EN); + mac_printf("GSWSS: MAC %d: %s\n", i, enable ? "ENABLED" : "DISABLED"); return ret; } @@ -970,13 +831,13 @@ int gswss_set_1g_intf(void *pdev, u32 macif) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); if (macif == LMAC_GMII) { - xgmac_printf("GSWSS: MACIF Set to CFG1G with LMAC_GMII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFG1G, 0); + mac_printf("GSWSS: MACIF Set to CFG1G with LMAC_GMII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFG1G, 0); } else if (macif == XGMAC_GMII) { - xgmac_printf("GSWSS: MACIF Set to CFG1G with XGMAC_GMII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFG1G, 1); + mac_printf("GSWSS: MACIF Set to CFG1G with XGMAC_GMII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFG1G, 1); } else { - xgmac_printf("GSWSS: MACIF Set to 1G Wrong Value\n"); + mac_printf("GSWSS: MACIF Set to 1G Wrong Value\n"); } GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -991,16 +852,16 @@ u32 gswss_get_1g_intf(void *pdev) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - macif = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFG1G); + macif = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFG1G); if (macif == 0) { - xgmac_printf("GSWSS: MACIF got for CFG1G is LMAC_GMII\n"); + mac_printf("GSWSS: MACIF got for CFG1G is LMAC_GMII\n"); macif = LMAC_GMII; } else if (macif == 1) { - xgmac_printf("GSWSS: MACIF got for CFG1G is XGMAC_GMII\n"); + mac_printf("GSWSS: MACIF got for CFG1G is XGMAC_GMII\n"); macif = XGMAC_GMII; } else { - xgmac_printf("GSWSS: MACIF got for CFG1G is Wrong Value\n"); + mac_printf("GSWSS: MACIF got for CFG1G is Wrong Value\n"); } return macif; @@ -1015,13 +876,13 @@ int gswss_set_fe_intf(void *pdev, u32 macif) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); if (macif == LMAC_MII) { - xgmac_printf("GSWSS: MACIF Set to CFGFE with LMAC_MII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFGFE, 0); + mac_printf("GSWSS: MACIF Set to CFGFE with LMAC_MII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFGFE, 0); } else if (macif == XGMAC_GMII) { - xgmac_printf("GSWSS: MACIF Set to CFGFE with XGMAC_GMII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFGFE, 1); + mac_printf("GSWSS: MACIF Set to CFGFE with XGMAC_GMII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFGFE, 1); } else { - xgmac_printf("GSWSS: MACIF Set to CFGFE Wrong Value\n"); + mac_printf("GSWSS: MACIF Set to CFGFE Wrong Value\n"); } GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -1036,16 +897,16 @@ u32 gswss_get_fe_intf(void *pdev) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - macif = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFGFE); + macif = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFGFE); if (macif == 0) { - xgmac_printf("GSWSS: MACIF got for CFGFE is LMAC_MII\n"); + mac_printf("GSWSS: MACIF got for CFGFE is LMAC_MII\n"); macif = LMAC_MII; } else if (macif == 1) { - xgmac_printf("GSWSS: MACIF got for CFGFE is XGMAC_GMII\n"); + mac_printf("GSWSS: MACIF got for CFGFE is XGMAC_GMII\n"); macif = XGMAC_GMII; } else { - xgmac_printf("GSWSS: MACIF got for CFGFE is Wrong Value\n"); + mac_printf("GSWSS: MACIF got for CFGFE is Wrong Value\n"); } return macif; @@ -1060,13 +921,13 @@ int gswss_set_2G5_intf(void *pdev, u32 macif) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); if (macif == XGMAC_GMII) { - xgmac_printf("GSWSS: MACIF Set to 2.5G with XGMAC_GMII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFG2G5, 0); + mac_printf("GSWSS: MACIF Set to 2.5G with XGMAC_GMII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFG2G5, 0); } else if (macif == XGMAC_XGMII) { - xgmac_printf("GSWSS: MACIF Set to 2.5G with XGMAC_XGMII\n"); - GSWSS_SET_BITS(mac_if_cfg, MAC_IF_CFG, CFG2G5, 1); + mac_printf("GSWSS: MACIF Set to 2.5G with XGMAC_XGMII\n"); + MAC_SET_VAL(mac_if_cfg, MAC_IF_CFG, CFG2G5, 1); } else { - xgmac_printf("GSWSS: MACIF Set to 2.5G Wrong Value\n"); + mac_printf("GSWSS: MACIF Set to 2.5G Wrong Value\n"); } GSWSS_MAC_RGWR(pdata, MAC_IF_CFG(pdata->mac_idx), mac_if_cfg); @@ -1081,16 +942,16 @@ u32 gswss_get_2G5_intf(void *pdev) mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - macif = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFG2G5); + macif = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFG2G5); if (macif == 0) { - xgmac_printf("GSWSS: MACIF Got for 2.5G with XGMAC_GMII\n"); + mac_printf("GSWSS: MACIF Got for 2.5G with XGMAC_GMII\n"); macif = XGMAC_GMII; } else if (macif == 1) { - xgmac_printf("GSWSS: MACIF Got for 2.5G with XGMAC_XGMII\n"); + mac_printf("GSWSS: MACIF Got for 2.5G with XGMAC_XGMII\n"); macif = XGMAC_XGMII; } else { - xgmac_printf("GSWSS: MACIF Got for 2.5G Wrong Value\n"); + mac_printf("GSWSS: MACIF Got for 2.5G Wrong Value\n"); } return macif; @@ -1102,23 +963,23 @@ void gswss_get_macif(void *pdev) u32 mac_if_cfg, val; mac_if_cfg = GSWSS_MAC_RGRD(pdata, MAC_IF_CFG(pdata->mac_idx)); - xgmac_printf("GSWSS: MAC%d IF_CFG %d\n", (pdata->mac_idx + 2), - mac_if_cfg); - val = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFG1G); - xgmac_printf("\t1G: %s\n", - val ? - "XGMAC GMII interface mode is used" : - "Legacy GMAC GMII interface mode is used"); - val = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFGFE); - xgmac_printf("\tFast Ethernet: %s\n", - val ? - "XGMAC GMII interface mode is used" : - "Legacy GMAC MII interface mode is used"); - val = GSWSS_GET_BITS(mac_if_cfg, MAC_IF_CFG, CFG2G5); - xgmac_printf("\t2.5G: %s\n", - val ? - "XGMAC XGMII interface mode is used" : - "XGMAC GMII interface mode is used"); + mac_printf("GSWSS: MAC%d IF_CFG %d\n", (pdata->mac_idx + 2), + mac_if_cfg); + val = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFG1G); + mac_printf("\t1G: %s\n", + val ? + "XGMAC GMII interface mode is used" : + "Legacy GMAC GMII interface mode is used"); + val = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFGFE); + mac_printf("\tFast Ethernet: %s\n", + val ? + "XGMAC GMII interface mode is used" : + "Legacy GMAC MII interface mode is used"); + val = MAC_GET_VAL(mac_if_cfg, MAC_IF_CFG, CFG2G5); + mac_printf("\t2.5G: %s\n", + val ? + "XGMAC XGMII interface mode is used" : + "XGMAC GMII interface mode is used"); } int gswss_set_mac_txfcs_ins_op(void *pdev, u32 val) @@ -1128,10 +989,10 @@ int gswss_set_mac_txfcs_ins_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, TXFCS_INS) != val) { - xgmac_printf("GSWSS: TX FCS INS operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, TXFCS_INS, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, TXFCS_INS) != val) { + mac_printf("GSWSS: TX FCS INS operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, TXFCS_INS, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1145,10 +1006,10 @@ int gswss_set_mac_txfcs_rm_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, TXFCS_RM) != val) { - xgmac_printf("GSWSS: TX FCS RM operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, TXFCS_RM, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, TXFCS_RM) != val) { + mac_printf("GSWSS: TX FCS RM operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, TXFCS_RM, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1162,10 +1023,10 @@ int gswss_set_mac_rxfcs_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXFCS) != val) { - xgmac_printf("GSWSS: RX FCS operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, RXFCS, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXFCS) != val) { + mac_printf("GSWSS: RX FCS operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, RXFCS, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1179,10 +1040,10 @@ int gswss_set_mac_rxsptag_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXSPTAG) != val) { - xgmac_printf("GSWSS: RX SPTAG operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, RXSPTAG, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXSPTAG) != val) { + mac_printf("GSWSS: RX SPTAG operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, RXSPTAG, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1196,10 +1057,10 @@ int gswss_set_mac_txsptag_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, TXSPTAG) != val) { - xgmac_printf("GSWSS: TX SPTAG operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, TXSPTAG, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, TXSPTAG) != val) { + mac_printf("GSWSS: TX SPTAG operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, TXSPTAG, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1213,10 +1074,10 @@ int gswss_set_mac_rxtime_op(void *pdev, u32 val) mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - if (GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXTIME) != val) { - xgmac_printf("GSWSS: RX TIME operation changing to MODE%d\n", - val); - GSWSS_SET_BITS(mac_op_cfg, MAC_OP_CFG, RXTIME, val); + if (MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXTIME) != val) { + mac_printf("GSWSS: RX TIME operation changing to MODE%d\n", + val); + MAC_SET_VAL(mac_op_cfg, MAC_OP_CFG, RXTIME, val); GSWSS_MAC_RGWR(pdata, MAC_OP_CFG(pdata->mac_idx), mac_op_cfg); } @@ -1230,79 +1091,79 @@ void gswss_get_macop(void *pdev) u32 mac_op_cfg, val; mac_op_cfg = GSWSS_MAC_RGRD(pdata, MAC_OP_CFG(pdata->mac_idx)); - xgmac_printf("GSWSS: MAC%d OP_CFG %d\n", (i + 2), mac_op_cfg); - val = GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, TXFCS_INS); - xgmac_printf("TX direction FCS\n"); + mac_printf("GSWSS: MAC%d OP_CFG %d\n", (i + 2), mac_op_cfg); + val = MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, TXFCS_INS); + mac_printf("TX direction FCS\n"); if (val == MODE0) - xgmac_printf("\tPacket does not have FCS and FCS " - "is not inserted\n"); + mac_printf("\tPacket does not have FCS and FCS " + "is not inserted\n"); else if (val == MODE1) - xgmac_printf("\tPacket does not have FCS and FCS " - "is inserted\n"); + mac_printf("\tPacket does not have FCS and FCS " + "is inserted\n"); else if (val == MODE2) - xgmac_printf("\tPacket has FCS and FCS is not inserted\n"); + mac_printf("\tPacket has FCS and FCS is not inserted\n"); else if (val == MODE3) - xgmac_printf("\tReserved\n"); + mac_printf("\tReserved\n"); - val = GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXFCS); - xgmac_printf("RX direction FCS\n"); + val = MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXFCS); + mac_printf("RX direction FCS\n"); if (val == MODE0) - xgmac_printf("\tPacket does not have FCS and FCS " - "is not removed\n"); + mac_printf("\tPacket does not have FCS and FCS " + "is not removed\n"); else if (val == MODE1) - xgmac_printf("\tReserved\n"); + mac_printf("\tReserved\n"); else if (val == MODE2) - xgmac_printf("\tPacket has FCS and FCS is not removed\n"); + mac_printf("\tPacket has FCS and FCS is not removed\n"); else if (val == MODE3) - xgmac_printf("\tPacket has FCS and FCS is removed\n"); + mac_printf("\tPacket has FCS and FCS is removed\n"); - val = GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, TXSPTAG); - xgmac_printf("TX Special Tag\n"); + val = MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, TXSPTAG); + mac_printf("TX Special Tag\n"); if (val == MODE0) - xgmac_printf("\tPacket does not have Special Tag and " - "Special Tag is not removed\n"); + mac_printf("\tPacket does not have Special Tag and " + "Special Tag is not removed\n"); else if (val == MODE1) - xgmac_printf("\tPacket has Special Tag and " - "Special Tag is replaced\n"); + mac_printf("\tPacket has Special Tag and " + "Special Tag is replaced\n"); else if (val == MODE2) - xgmac_printf("\tPacket has Special Tag and " - "Special Tag is not removed\n"); + mac_printf("\tPacket has Special Tag and " + "Special Tag is not removed\n"); else if (val == MODE3) - xgmac_printf("\tPacket has Special Tag and " - "Special Tag is removed\n"); + mac_printf("\tPacket has Special Tag and " + "Special Tag is removed\n"); - val = GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXSPTAG); - xgmac_printf("RX Special Tag\n"); + val = MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXSPTAG); + mac_printf("RX Special Tag\n"); if (val == MODE0) - xgmac_printf("\tPacket does not have Special Tag and " - "Special Tag is not inserted\n"); + mac_printf("\tPacket does not have Special Tag and " + "Special Tag is not inserted\n"); else if (val == MODE1) - xgmac_printf("\tPacket does not have Special Tag and " - "Special Tag is inserted\n"); + mac_printf("\tPacket does not have Special Tag and " + "Special Tag is inserted\n"); else if (val == MODE2) - xgmac_printf("\tPacket has Special Tag and " - "Special Tag is not inserted\n"); + mac_printf("\tPacket has Special Tag and " + "Special Tag is not inserted\n"); else if (val == MODE3) - xgmac_printf("\tReserved\n"); + mac_printf("\tReserved\n"); - val = GSWSS_GET_BITS(mac_op_cfg, MAC_OP_CFG, RXTIME); - xgmac_printf("RX Direction Timestamp\n"); + val = MAC_GET_VAL(mac_op_cfg, MAC_OP_CFG, RXTIME); + mac_printf("RX Direction Timestamp\n"); if (val == MODE0) - xgmac_printf("\tPacket does not have time stamp and " - "time stamp is not inserted.\n"); + mac_printf("\tPacket does not have time stamp and " + "time stamp is not inserted.\n"); else if (val == MODE1) - xgmac_printf("\tPacket doe not have time stamp and " - "time stamp is inserted\n"); + mac_printf("\tPacket doe not have time stamp and " + "time stamp is inserted\n"); else if (val == MODE2) - xgmac_printf("\tPacket has time stamp and " - "time stamp is not inserted\n"); + mac_printf("\tPacket has time stamp and " + "time stamp is not inserted\n"); else if (val == MODE3) - xgmac_printf("\tReserved\n"); + mac_printf("\tReserved\n"); } int gswss_set_mtu(void *pdev, u32 mtu) @@ -1311,7 +1172,7 @@ int gswss_set_mtu(void *pdev, u32 mtu) int ret = 0; if (GSWSS_MAC_RGRD(pdata, MAC_MTU_CFG(pdata->mac_idx)) != mtu) { - xgmac_printf("GSWSS: MTU set to %d\n", mtu); + mac_printf("GSWSS: MTU set to %d\n", mtu); GSWSS_MAC_RGWR(pdata, MAC_MTU_CFG(pdata->mac_idx), mtu); } @@ -1323,17 +1184,22 @@ int gswss_get_mtu(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mtu = GSWSS_MAC_RGRD(pdata, MAC_MTU_CFG(pdata->mac_idx)); - xgmac_printf("GSWSS: MAC%d MTU %d\n", (pdata->mac_idx + 2), mtu); + mac_printf("GSWSS: MAC%d MTU %d\n", (pdata->mac_idx + 2), mtu); return mtu; } -int gswss_set_txtstamp(void *pdev, u32 nsec, u32 sec, u32 record_id) +int gswss_set_txtstamp_fifo(void *pdev, + u8 ttse, u8 ostc, u8 ost_avail, u8 cic, u32 sec, + u32 nsec, u32 record_id) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - u32 mac_txtstamp; int ret = 0; - u16 val; + u16 val = 0; + u32 mac_txtstamp; + + val = ((ttse << 4) | (ostc << 3) | (ost_avail << 2) | cic); + GSWSS_MAC_RGWR(pdata, MAC_TXTS_CIC(pdata->mac_idx), val); mac_txtstamp = MAC_TXTS_0(pdata->mac_idx); val = GET_N_BITS(nsec, 0, 16); @@ -1356,8 +1222,8 @@ int gswss_set_txtstamp(void *pdev, u32 nsec, u32 sec, u32 record_id) nsec = ((GSWSS_MAC_RGRD(pdata, MAC_TXTS_3(pdata->mac_idx)) << 16) | GSWSS_MAC_RGRD(pdata, MAC_TXTS_2(pdata->mac_idx))); - xgmac_printf("GSWSS Write Record ID %d: MAC%d sec %d nsec %d\n", - record_id, (pdata->mac_idx + 2), sec, nsec); + mac_printf("\nMAC%d: TxTstamp Fifo Record ID %d written\n", + (pdata->mac_idx + 2), record_id); /* Write the entries into the 64 array record_id */ gswss_set_txtstamp_access(pdev, 1, record_id); @@ -1365,67 +1231,53 @@ int gswss_set_txtstamp(void *pdev, u32 nsec, u32 sec, u32 record_id) return ret; } -void gswss_get_txtstamp(void *pdev, u32 record_id) +void gswss_get_txtstamp_fifo(void *pdev, u32 record_id) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 mac_txtstamp, tstamp_cic; u32 sec, nsec; gswss_set_txtstamp_access(pdev, 0, record_id); - sec = ((GSWSS_MAC_RGRD(pdata, MAC_TXTS_1(pdata->mac_idx)) << 16) | - GSWSS_MAC_RGRD(pdata, MAC_TXTS_0(pdata->mac_idx))); - nsec = ((GSWSS_MAC_RGRD(pdata, MAC_TXTS_3(pdata->mac_idx)) << 16) | - GSWSS_MAC_RGRD(pdata, MAC_TXTS_2(pdata->mac_idx))); - - xgmac_printf("GSWSS Read Record ID %d: MAC%d sec %d nsec %d\n", - record_id, (pdata->mac_idx + 2), sec, nsec); -} - -int gswss_set_txtstamp_cic(void *pdev, - u8 ttse, u8 ostc, u8 ost_avail, u8 cic) -{ - struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - int ret = 0; - u16 val = 0; - - val = ((ttse << 4) | (ostc << 3) | (ost_avail << 2) | cic); - GSWSS_MAC_RGWR(pdata, MAC_TXTS_CIC(pdata->mac_idx), val); - - return ret; -} - -void gswss_get_txtstamp_cic(void *pdev) -{ - struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - int i = 0; - u32 mac_txtstamp, tstamp_cic; + mac_printf("\nMAC%d: TxTstamp Fifo Record ID %d:\n", + (pdata->mac_idx + 2), + record_id); mac_txtstamp = GSWSS_MAC_RGRD(pdata, MAC_TXTS_CIC(pdata->mac_idx)); - xgmac_printf("GSWSS: MAC%d txtstamp_cic %d\n", (i + 2), mac_txtstamp); - xgmac_printf("\tTime Stamp Capture Enable: %s\n", - GET_N_BITS(mac_txtstamp, 4, 1) ? "ENABLED" : "DISABLED"); - xgmac_printf("\tTime stamp One Step Correction Enable: %s\n", - GET_N_BITS(mac_txtstamp, 3, 1) ? "ENABLED" : "DISABLED"); - xgmac_printf("\tTime stamp One Step Time stamp Available: %s\n", - GET_N_BITS(mac_txtstamp, 2, 1) ? "ENABLED" : "DISABLED"); + + mac_printf("\tTTSE: \t%s\n", + GET_N_BITS(mac_txtstamp, 4, 1) ? "ENABLED" : "DISABLED"); + mac_printf("\tOSTC: \t%s\n", + GET_N_BITS(mac_txtstamp, 3, 1) ? "ENABLED" : "DISABLED"); + mac_printf("\tOSTPA: \t%s\n", + GET_N_BITS(mac_txtstamp, 2, 1) ? "ENABLED" : "DISABLED"); tstamp_cic = GET_N_BITS(mac_txtstamp, 0, 2); if (tstamp_cic == 0) - xgmac_printf("\tTime stamp CIC Checksum Insertion is " - "Disabled\n"); + mac_printf("\tCIC: \t" + "DISABLED\n"); if (tstamp_cic == 1) - xgmac_printf("\tTime stamp CIC IP Checksum update\n"); + mac_printf("\tCIC: \tTime stamp IP Checksum update\n"); if (tstamp_cic == 2) - xgmac_printf("\tTime stamp CIC IP and " - "Payload Checksum update\n"); + mac_printf("\tCIC: \tTime stamp IP and " + "Payload Checksum update\n"); if (tstamp_cic == 3) - xgmac_printf("\tTime stamp CIC IP, Payload checksum and " - "Pseudo header update\n"); + mac_printf("\tCIC: \tTime stamp IP, Payload checksum and " + "Pseudo header update\n"); + + sec = ((GSWSS_MAC_RGRD(pdata, MAC_TXTS_1(pdata->mac_idx)) << 16) | + GSWSS_MAC_RGRD(pdata, MAC_TXTS_0(pdata->mac_idx))); + nsec = ((GSWSS_MAC_RGRD(pdata, MAC_TXTS_3(pdata->mac_idx)) << 16) | + GSWSS_MAC_RGRD(pdata, MAC_TXTS_2(pdata->mac_idx))); + + mac_printf("\tSEC: \t%d\n", sec); + mac_printf("\tNSEC:\t%d\n", nsec); } + int gswss_set_txtstamp_access(void *pdev, u32 op_mode, u32 addr) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); @@ -1433,16 +1285,16 @@ int gswss_set_txtstamp_access(void *pdev, u32 op_mode, u32 addr) u16 tstamp_acc = 0; u32 busy_bit; - GSWSS_SET_BITS(tstamp_acc, MAC_TXTS_ACC, BAS, 1); - GSWSS_SET_BITS(tstamp_acc, MAC_TXTS_ACC, OPMOD, op_mode); - GSWSS_SET_BITS(tstamp_acc, MAC_TXTS_ACC, ADDR, addr); + MAC_SET_VAL(tstamp_acc, MAC_TXTS_ACC, BAS, 1); + MAC_SET_VAL(tstamp_acc, MAC_TXTS_ACC, OPMOD, op_mode); + MAC_SET_VAL(tstamp_acc, MAC_TXTS_ACC, ADDR, addr); GSWSS_MAC_RGWR(pdata, MAC_TXTS_ACC(pdata->mac_idx), tstamp_acc); while (1) { tstamp_acc = GSWSS_MAC_RGRD(pdata, MAC_TXTS_ACC(pdata->mac_idx)); - busy_bit = GSWSS_GET_BITS(tstamp_acc, MAC_TXTS_ACC, BAS); + busy_bit = MAC_GET_VAL(tstamp_acc, MAC_TXTS_ACC, BAS); if (busy_bit == 0) break; @@ -1451,21 +1303,6 @@ int gswss_set_txtstamp_access(void *pdev, u32 op_mode, u32 addr) return ret; } -void gswss_get_txtstamp_access(void *pdev) -{ - struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - int i = 0; - u32 tstamp_acc; - - tstamp_acc = GSWSS_MAC_RGRD(pdata, MAC_TXTS_ACC(pdata->mac_idx)); - xgmac_printf("GSWSS: MAC%d txtstamp_access %d\n", (i + 2), tstamp_acc); - xgmac_printf("\tAccess Busy/Access Start: %s\n", - GET_N_BITS(tstamp_acc, 15, 1) ? "BUSY" : "READY"); - xgmac_printf("\tAccess Operation Mode: %s\n", - GET_N_BITS(tstamp_acc, 14, 1) ? "WRITE" : "READ"); - xgmac_printf("\tTime stamp FIFO address: %d\n", - GET_N_BITS(tstamp_acc, 0, 6)); -} int gswss_set_duplex_mode(void *pdev, u32 val) { @@ -1474,17 +1311,17 @@ int gswss_set_duplex_mode(void *pdev, u32 val) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - if (GSWSS_GET_BITS(phy_mode, PHY_MODE, FDUP) != val) { + if (MAC_GET_VAL(phy_mode, PHY_MODE, FDUP) != val) { if (val == MAC_AUTO_DPLX) - xgmac_printf("\tGSWSS: Duplex mode set: Auto Mode\n"); + mac_printf("\tGSWSS: Duplex mode set: Auto Mode\n"); else if (val == MAC_FULL_DPLX) - xgmac_printf("\tGSWSS: Duplex mode set: Full Duplex\n"); + mac_printf("\tGSWSS: Duplex mode set: Full Duplex\n"); else if (val == MAC_RES_DPLX) - xgmac_printf("\tGSWSS: Duplex mode set: Reserved\n"); + mac_printf("\tGSWSS: Duplex mode set: Reserved\n"); else if (val == MAC_HALF_DPLX) - xgmac_printf("\tGSWSS: Duplex mode set: Half Duplex\n"); + mac_printf("\tGSWSS: Duplex mode set: Half Duplex\n"); - GSWSS_SET_BITS(phy_mode, PHY_MODE, FDUP, val); + MAC_SET_VAL(phy_mode, PHY_MODE, FDUP, val); GSWSS_MAC_RGWR(pdata, PHY_MODE(pdata->mac_idx), phy_mode); } @@ -1498,16 +1335,16 @@ int gswss_get_duplex_mode(void *pdev) u32 val; phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - val = GSWSS_GET_BITS(phy_mode, PHY_MODE, FDUP); + val = MAC_GET_VAL(phy_mode, PHY_MODE, FDUP); if (val == MAC_AUTO_DPLX) - xgmac_printf("\tGSWSS: Duplex mode got: Auto Mode\n"); + mac_printf("\tGSWSS: Duplex mode got: Auto Mode\n"); else if (val == MAC_FULL_DPLX) - xgmac_printf("\tGSWSS: Duplex mode got: Full Duplex\n"); + mac_printf("\tGSWSS: Duplex mode got: Full Duplex\n"); else if (val == MAC_RES_DPLX) - xgmac_printf("\tGSWSS: Duplex mode got: Reserved\n"); + mac_printf("\tGSWSS: Duplex mode got: Reserved\n"); else if (val == MAC_HALF_DPLX) - xgmac_printf("\tGSWSS: Duplex mode got: Half Duplex\n"); + mac_printf("\tGSWSS: Duplex mode got: Half Duplex\n"); return val; } @@ -1524,24 +1361,24 @@ int gswss_set_speed(void *pdev, u8 speed) speed_lsb = GET_N_BITS(speed, 0, 2); if (speed == SPEED_10M) - xgmac_printf("\tGSWSS: SPEED 10 Mbps\n"); + mac_printf("\tGSWSS: SPEED 10 Mbps\n"); else if (speed == SPEED_100M) - xgmac_printf("\tGSWSS: SPEED 100 Mbps\n"); + mac_printf("\tGSWSS: SPEED 100 Mbps\n"); else if (speed == SPEED_1G) - xgmac_printf("\tGSWSS: SPEED 1 Gbps\n"); + mac_printf("\tGSWSS: SPEED 1 Gbps\n"); else if (speed == SPEED_10G) - xgmac_printf("\tGSWSS: SPEED 10 Gbps\n"); + mac_printf("\tGSWSS: SPEED 10 Gbps\n"); else if (speed == SPEED_2G5) - xgmac_printf("\tGSWSS: SPEED 2.5 Gbps\n"); + mac_printf("\tGSWSS: SPEED 2.5 Gbps\n"); else if (speed == SPEED_5G) - xgmac_printf("\tGSWSS: SPEED 5 Gbps\n"); + mac_printf("\tGSWSS: SPEED 5 Gbps\n"); else if (speed == SPEED_FLEX) - xgmac_printf("\tGSWSS: SPEED RESERVED\n"); + mac_printf("\tGSWSS: SPEED RESERVED\n"); else if (speed == SPEED_AUTO) - xgmac_printf("\tGSWSS: SPEED Auto Mode\n"); + mac_printf("\tGSWSS: SPEED Auto Mode\n"); - GSWSS_SET_BITS(phy_mode, PHY_MODE, SPEEDMSB, speed_msb); - GSWSS_SET_BITS(phy_mode, PHY_MODE, SPEEDLSB, speed_lsb); + MAC_SET_VAL(phy_mode, PHY_MODE, SPEEDMSB, speed_msb); + MAC_SET_VAL(phy_mode, PHY_MODE, SPEEDLSB, speed_lsb); GSWSS_MAC_RGWR(pdata, PHY_MODE(pdata->mac_idx), phy_mode); @@ -1556,27 +1393,27 @@ u8 gswss_get_speed(void *pdev) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - speed_msb = GSWSS_GET_BITS(phy_mode, PHY_MODE, SPEEDMSB); - speed_lsb = GSWSS_GET_BITS(phy_mode, PHY_MODE, SPEEDLSB); + speed_msb = MAC_GET_VAL(phy_mode, PHY_MODE, SPEEDMSB); + speed_lsb = MAC_GET_VAL(phy_mode, PHY_MODE, SPEEDLSB); speed = ((speed_msb << 2) | speed_lsb); if (speed == SPEED_10M) - xgmac_printf("\tGSWSS: SPEED Got 10 Mbps\n"); + mac_printf("\tGSWSS: SPEED Got 10 Mbps\n"); else if (speed == SPEED_100M) - xgmac_printf("\tGSWSS: SPEED Got 100 Mbps\n"); + mac_printf("\tGSWSS: SPEED Got 100 Mbps\n"); else if (speed == SPEED_1G) - xgmac_printf("\tGSWSS: SPEED Got 1 Gbps\n"); + mac_printf("\tGSWSS: SPEED Got 1 Gbps\n"); else if (speed == SPEED_10G) - xgmac_printf("\tGSWSS: SPEED Got 10 Gbps\n"); + mac_printf("\tGSWSS: SPEED Got 10 Gbps\n"); else if (speed == SPEED_2G5) - xgmac_printf("\tGSWSS: SPEED Got 2.5 Gbps\n"); + mac_printf("\tGSWSS: SPEED Got 2.5 Gbps\n"); else if (speed == SPEED_5G) - xgmac_printf("\tGSWSS: SPEED Got 5 Gbps\n"); + mac_printf("\tGSWSS: SPEED Got 5 Gbps\n"); else if (speed == SPEED_FLEX) - xgmac_printf("\tGSWSS: SPEED Got RESERVED\n"); + mac_printf("\tGSWSS: SPEED Got RESERVED\n"); else if (speed == SPEED_AUTO) - xgmac_printf("\tGSWSS: SPEED Got Auto Mode\n"); + mac_printf("\tGSWSS: SPEED Got Auto Mode\n"); return speed; } @@ -1588,17 +1425,17 @@ int gswss_set_linkstatus(void *pdev, u8 linkst) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - if (GSWSS_GET_BITS(phy_mode, PHY_MODE, LINKST) != linkst) { + if (MAC_GET_VAL(phy_mode, PHY_MODE, LINKST) != linkst) { if (linkst == 0) - xgmac_printf("\tGSWSS: LINK STS: Auto Mode\n"); + mac_printf("\tGSWSS: LINK STS: Auto Mode\n"); else if (linkst == 1) - xgmac_printf("\tGSWSS: LINK STS: Forced UP\n"); + mac_printf("\tGSWSS: LINK STS: Forced UP\n"); else if (linkst == 2) - xgmac_printf("\tGSWSS: LINK STS: Forced DOWN\n"); + mac_printf("\tGSWSS: LINK STS: Forced DOWN\n"); else if (linkst == 3) - xgmac_printf("\tGSWSS: LINK STS: Reserved\n"); + mac_printf("\tGSWSS: LINK STS: Reserved\n"); - GSWSS_SET_BITS(phy_mode, PHY_MODE, LINKST, linkst); + MAC_SET_VAL(phy_mode, PHY_MODE, LINKST, linkst); GSWSS_MAC_RGWR(pdata, PHY_MODE(pdata->mac_idx), phy_mode); } @@ -1613,16 +1450,16 @@ int gswss_get_linkstatus(void *pdev) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - linkst = GSWSS_GET_BITS(phy_mode, PHY_MODE, LINKST); + linkst = MAC_GET_VAL(phy_mode, PHY_MODE, LINKST); if (linkst == 0) - xgmac_printf("\tGSWSS: LINK STS Got: Auto Mode\n"); + mac_printf("\tGSWSS: LINK STS Got: Auto Mode\n"); else if (linkst == 1) - xgmac_printf("\tGSWSS: LINK STS Got: Forced UP\n"); + mac_printf("\tGSWSS: LINK STS Got: Forced UP\n"); else if (linkst == 2) - xgmac_printf("\tGSWSS: LINK STS Got: Forced DOWN\n"); + mac_printf("\tGSWSS: LINK STS Got: Forced DOWN\n"); else if (linkst == 3) - xgmac_printf("\tGSWSS: LINK STS Got: Reserved\n"); + mac_printf("\tGSWSS: LINK STS Got: Reserved\n"); return linkst; } @@ -1635,17 +1472,17 @@ int gswss_set_flowctrl_tx(void *pdev, u8 flow_ctrl_tx) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - if (GSWSS_GET_BITS(phy_mode, PHY_MODE, FCONTX) != flow_ctrl_tx) { + if (MAC_GET_VAL(phy_mode, PHY_MODE, FCONTX) != flow_ctrl_tx) { if (flow_ctrl_tx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); else if (flow_ctrl_tx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); else if (flow_ctrl_tx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); else if (flow_ctrl_tx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); - GSWSS_SET_BITS(phy_mode, PHY_MODE, FCONTX, flow_ctrl_tx); + MAC_SET_VAL(phy_mode, PHY_MODE, FCONTX, flow_ctrl_tx); GSWSS_MAC_RGWR(pdata, PHY_MODE(pdata->mac_idx), phy_mode); } @@ -1660,16 +1497,16 @@ u32 gswss_get_flowctrl_tx(void *pdev) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - flow_ctrl_tx = GSWSS_GET_BITS(phy_mode, PHY_MODE, FCONTX); + flow_ctrl_tx = MAC_GET_VAL(phy_mode, PHY_MODE, FCONTX); if (flow_ctrl_tx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); else if (flow_ctrl_tx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); else if (flow_ctrl_tx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); else if (flow_ctrl_tx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); return flow_ctrl_tx; } @@ -1682,17 +1519,17 @@ int gswss_set_flowctrl_rx(void *pdev, u8 flow_ctrl_rx) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - if (GSWSS_GET_BITS(phy_mode, PHY_MODE, FCONRX) != flow_ctrl_rx) { + if (MAC_GET_VAL(phy_mode, PHY_MODE, FCONRX) != flow_ctrl_rx) { if (flow_ctrl_rx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); else if (flow_ctrl_rx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); else if (flow_ctrl_rx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); else if (flow_ctrl_rx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); - GSWSS_SET_BITS(phy_mode, PHY_MODE, FCONRX, flow_ctrl_rx); + MAC_SET_VAL(phy_mode, PHY_MODE, FCONRX, flow_ctrl_rx); GSWSS_MAC_RGWR(pdata, PHY_MODE(pdata->mac_idx), phy_mode); } @@ -1707,16 +1544,16 @@ u32 gswss_get_flowctrl_rx(void *pdev) phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - flow_ctrl_rx = GSWSS_GET_BITS(phy_mode, PHY_MODE, FCONRX); + flow_ctrl_rx = MAC_GET_VAL(phy_mode, PHY_MODE, FCONRX); if (flow_ctrl_rx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); else if (flow_ctrl_rx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); else if (flow_ctrl_rx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); else if (flow_ctrl_rx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); return flow_ctrl_rx; } @@ -1730,71 +1567,71 @@ void gswss_get_phy2mode(void *pdev) u8 linkst, fdup, flow_ctrl_tx, flow_ctrl_rx; phy_mode = GSWSS_MAC_RGRD(pdata, PHY_MODE(pdata->mac_idx)); - xgmac_printf("phy_mode%d %d\n", (i + 2), phy_mode); + mac_printf("phy_mode%d %d\n", (i + 2), phy_mode); speed_msb = GET_N_BITS(phy_mode, 15, 1); speed_lsb = GET_N_BITS(phy_mode, 11, 2); speed = (speed_msb << 2) | speed_lsb; if (speed == 0) - xgmac_printf("\tGSWSS: SPEED 10 Mbps\n"); + mac_printf("\tGSWSS: SPEED 10 Mbps\n"); else if (speed == 1) - xgmac_printf("\tGSWSS: SPEED 100 Mbps\n"); + mac_printf("\tGSWSS: SPEED 100 Mbps\n"); else if (speed == 2) - xgmac_printf("\tGSWSS: SPEED 1 Gbps\n"); + mac_printf("\tGSWSS: SPEED 1 Gbps\n"); else if (speed == 3) - xgmac_printf("\tGSWSS: SPEED 10 Gbps\n"); + mac_printf("\tGSWSS: SPEED 10 Gbps\n"); else if (speed == 4) - xgmac_printf("\tGSWSS: SPEED 2.5 Gbps\n"); + mac_printf("\tGSWSS: SPEED 2.5 Gbps\n"); else if (speed == 5) - xgmac_printf("\tGSWSS: SPEED 5 Gbps\n"); + mac_printf("\tGSWSS: SPEED 5 Gbps\n"); else if (speed == 6) - xgmac_printf("\tGSWSS: SPEED RESERVED\n"); + mac_printf("\tGSWSS: SPEED RESERVED\n"); else if (speed == 7) - xgmac_printf("\tGSWSS: SPEED Auto Mode\n"); + mac_printf("\tGSWSS: SPEED Auto Mode\n"); linkst = GET_N_BITS(phy_mode, 13, 2); if (linkst == 0) - xgmac_printf("\tGSWSS: LINK STS: Auto Mode\n"); + mac_printf("\tGSWSS: LINK STS: Auto Mode\n"); else if (linkst == 1) - xgmac_printf("\tGSWSS: LINK STS: Forced up\n"); + mac_printf("\tGSWSS: LINK STS: Forced up\n"); else if (linkst == 2) - xgmac_printf("\tGSWSS: LINK STS: Forced down\n"); + mac_printf("\tGSWSS: LINK STS: Forced down\n"); else if (linkst == 3) - xgmac_printf("\tGSWSS: LINK STS: Reserved\n"); + mac_printf("\tGSWSS: LINK STS: Reserved\n"); fdup = GET_N_BITS(phy_mode, 9, 2); if (fdup == 0) - xgmac_printf("\tGSWSS: Duplex mode set: Auto Mode\n"); + mac_printf("\tGSWSS: Duplex mode set: Auto Mode\n"); else if (fdup == 1) - xgmac_printf("\tGSWSS: Duplex mode set: Full Duplex Mode\n"); + mac_printf("\tGSWSS: Duplex mode set: Full Duplex Mode\n"); else if (fdup == 2) - xgmac_printf("\tGSWSS: Duplex mode set: Reserved\n"); + mac_printf("\tGSWSS: Duplex mode set: Reserved\n"); else if (fdup == 3) - xgmac_printf("\tGSWSS: Duplex mode set: Half Duplex Mode\n"); + mac_printf("\tGSWSS: Duplex mode set: Half Duplex Mode\n"); flow_ctrl_tx = GET_N_BITS(phy_mode, 7, 2); if (flow_ctrl_tx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Auto Mode\n"); else if (flow_ctrl_tx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: ENABLED\n"); else if (flow_ctrl_tx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: Reserved\n"); else if (flow_ctrl_tx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode TX: DISABLED\n"); flow_ctrl_rx = GET_N_BITS(phy_mode, 7, 2); if (flow_ctrl_rx == 0) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Auto Mode\n"); else if (flow_ctrl_rx == 1) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: ENABLED\n"); else if (flow_ctrl_rx == 2) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: Reserved\n"); else if (flow_ctrl_rx == 3) - xgmac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); + mac_printf("\tGSWSS: Flow Ctrl Mode RX: DISABLED\n"); } int gswss_set_xgmac_tx_disable(void *pdev, u32 val) @@ -1804,10 +1641,10 @@ int gswss_set_xgmac_tx_disable(void *pdev, u32 val) xgmac_ctrl = GSWSS_MAC_RGRD(pdata, XGMAC_CTRL(pdata->mac_idx)); - if (GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, DISTX) != val) { - xgmac_printf("\tGSWSS: XGMAC %d TX %s\n", pdata->mac_idx, - val ? "DISABLED" : "NOT DISABLED"); - GSWSS_SET_BITS(xgmac_ctrl, XGMAC_CTRL, DISTX, val); + if (MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, DISTX) != val) { + mac_printf("\tGSWSS: XGMAC %d TX %s\n", pdata->mac_idx, + val ? "DISABLED" : "NOT DISABLED"); + MAC_SET_VAL(xgmac_ctrl, XGMAC_CTRL, DISTX, val); GSWSS_MAC_RGWR(pdata, XGMAC_CTRL(pdata->mac_idx), xgmac_ctrl); } @@ -1821,10 +1658,10 @@ int gswss_set_xgmac_rx_disable(void *pdev, u32 val) xgmac_ctrl = GSWSS_MAC_RGRD(pdata, XGMAC_CTRL(pdata->mac_idx)); - if (GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, DISRX) != val) { - xgmac_printf("\tGSWSS: XGMAC %d RX %s\n", pdata->mac_idx, - val ? "DISABLED" : "NOT DISABLED"); - GSWSS_SET_BITS(xgmac_ctrl, XGMAC_CTRL, DISRX, val); + if (MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, DISRX) != val) { + mac_printf("\tGSWSS: XGMAC %d RX %s\n", pdata->mac_idx, + val ? "DISABLED" : "NOT DISABLED"); + MAC_SET_VAL(xgmac_ctrl, XGMAC_CTRL, DISRX, val); GSWSS_MAC_RGWR(pdata, XGMAC_CTRL(pdata->mac_idx), xgmac_ctrl); } @@ -1838,18 +1675,18 @@ int gswss_set_xgmac_crc_ctrl(void *pdev, u32 val) xgmac_ctrl = GSWSS_MAC_RGRD(pdata, XGMAC_CTRL(pdata->mac_idx)); - if (GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, CPC) != val) { + if (MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, CPC) != val) { if (val == 0) - xgmac_printf("GSWSS: CRC and PAD insertion are " - "enabled.\n"); + mac_printf("GSWSS: CRC and PAD insertion are " + "enabled.\n"); else if (val == 1) - xgmac_printf("GSWSS: CRC insert enable,PAD insert " - "disable\n"); + mac_printf("GSWSS: CRC insert enable,PAD insert " + "disable\n"); else if (val == 2) - xgmac_printf("GSWSS: CRC,PAD not inserted not " - "replaced.\n"); + mac_printf("GSWSS: CRC,PAD not inserted not " + "replaced.\n"); - GSWSS_SET_BITS(xgmac_ctrl, XGMAC_CTRL, CPC, val); + MAC_SET_VAL(xgmac_ctrl, XGMAC_CTRL, CPC, val); GSWSS_MAC_RGWR(pdata, XGMAC_CTRL(pdata->mac_idx), xgmac_ctrl); } @@ -1863,14 +1700,14 @@ int gswss_get_xgmac_crc_ctrl(void *pdev) xgmac_ctrl = GSWSS_MAC_RGRD(pdata, XGMAC_CTRL(pdata->mac_idx)); - val = GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, CPC); + val = MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, CPC); if (val == 0) - xgmac_printf("GSWSS: CRC and PAD insertion are enabled.\n"); + mac_printf("GSWSS: CRC and PAD insertion are enabled.\n"); else if (val == 1) - xgmac_printf("GSWSS: CRC insert enable,PAD insert disable\n"); + mac_printf("GSWSS: CRC insert enable,PAD insert disable\n"); else if (val == 2) - xgmac_printf("GSWSS: CRC,PAD not inserted not replaced.\n"); + mac_printf("GSWSS: CRC,PAD not inserted not replaced.\n"); return val; } @@ -1882,27 +1719,27 @@ void gswss_get_xgmac_ctrl(void *pdev) u32 mac_idx = 0; xgmac_ctrl = GSWSS_MAC_RGRD(pdata, XGMAC_CTRL(pdata->mac_idx)); - xgmac_printf("GSWSS: XGMAC CTRL %d %x\n", mac_idx, xgmac_ctrl); - distx = GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, DISTX); - disrx = GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, DISRX); - crc_ctrl = GSWSS_GET_BITS(xgmac_ctrl, XGMAC_CTRL, CPC); + mac_printf("GSWSS: XGMAC CTRL %d %x\n", mac_idx, xgmac_ctrl); + distx = MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, DISTX); + disrx = MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, DISRX); + crc_ctrl = MAC_GET_VAL(xgmac_ctrl, XGMAC_CTRL, CPC); - xgmac_printf("\tGSWSS: XGMAC %d TX %s\n", mac_idx, - distx ? "DISABLED" : "NOT DISABLED"); - xgmac_printf("\tGSWSS: XGMAC %d RX %s\n", mac_idx, - disrx ? "DISABLED" : "NOT DISABLED"); + mac_printf("\tGSWSS: XGMAC %d TX %s\n", mac_idx, + distx ? "DISABLED" : "NOT DISABLED"); + mac_printf("\tGSWSS: XGMAC %d RX %s\n", mac_idx, + disrx ? "DISABLED" : "NOT DISABLED"); if (crc_ctrl == 0) - xgmac_printf("\tGSWSS: CRC and PAD insertion are enabled.\n"); + mac_printf("\tGSWSS: CRC and PAD insertion are enabled.\n"); else if (crc_ctrl == 1) - xgmac_printf("\tGSWSS: CRC insert enable,PAD insert disable\n"); + mac_printf("\tGSWSS: CRC insert enable,PAD insert disable\n"); else if (crc_ctrl == 2) - xgmac_printf("\tGSWSS: CRC,PAD not inserted not replaced.\n"); + mac_printf("\tGSWSS: CRC,PAD not inserted not replaced.\n"); } void gswss_test_all_reg(void *pdev) { - int i = 0; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); gswss_check_reg(pdev, GSWIPSS_IER0, "GSWIPSS_IER0", 0, 0x8C8C, 0); gswss_check_reg(pdev, GSWIPSS_ISR0, "GSWIPSS_ISR0", 0, 0x8C8C, 0); @@ -1911,48 +1748,46 @@ void gswss_test_all_reg(void *pdev) gswss_check_reg(pdev, CFG0_1588, "CFG0_1588", 0, 0x7777, 0); gswss_check_reg(pdev, CFG1_1588, "CFG1_1588", 0, 0xFF80, 0); - for (i = 0; i < 3; i++) { - gswss_check_reg(pdev, MAC_IF_CFG(i), - "MAC_IF_CFG", i, 0x7, 0); - gswss_check_reg(pdev, MAC_OP_CFG(i), - "MAC_OP_CFG", i, 0x1FF, 0); - gswss_check_reg(pdev, MAC_MTU_CFG(i), - "MAC_MTU_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_CFG(i), - "MAC_GINT_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD0_CFG(i), - "MAC_GINT_HD0_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD1_CFG(i), - "MAC_GINT_HD1_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD2_CFG(i), - "MAC_GINT_HD2_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD3_CFG(i), - "MAC_GINT_HD3_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD4_CFG(i), - "MAC_GINT_HD4_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD5_CFG(i), - "MAC_GINT_HD5_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_GINT_HD6_CFG(i), - "MAC_GINT_HD6_CFG", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_TXTS_0(i), - "MAC_TXTS_0", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_TXTS_1(i), - "MAC_TXTS_1", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_TXTS_2(i), - "MAC_TXTS_2", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_TXTS_3(i), - "MAC_TXTS_3", i, 0xFFFF, 0); - gswss_check_reg(pdev, MAC_TXTS_CIC(i), - "MAC_TXTS_CIC", i, 0x1F, 0); - gswss_check_reg(pdev, MAC_TXTS_ACC(i), - "MAC_TXTS_ACC", i, 0x403F, 0); - gswss_check_reg(pdev, PHY_MODE(i), - "PHY_MODE", i, 0xFFE0, 0); - gswss_check_reg(pdev, ANEG_EEE(i), - "ANEG_EEE", i, 0xF, 0); - gswss_check_reg(pdev, XGMAC_CTRL(i), - "XGMAC_CTRL", i, 0xF, 0); - } + gswss_check_reg(pdev, MAC_IF_CFG(pdata->mac_idx), + "MAC_IF_CFG", pdata->mac_idx, 0x7, 0); + gswss_check_reg(pdev, MAC_OP_CFG(pdata->mac_idx), + "MAC_OP_CFG", pdata->mac_idx, 0x1FF, 0); + gswss_check_reg(pdev, MAC_MTU_CFG(pdata->mac_idx), + "MAC_MTU_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_CFG(pdata->mac_idx), + "MAC_GINT_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD0_CFG(pdata->mac_idx), + "MAC_GINT_HD0_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD1_CFG(pdata->mac_idx), + "MAC_GINT_HD1_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD2_CFG(pdata->mac_idx), + "MAC_GINT_HD2_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD3_CFG(pdata->mac_idx), + "MAC_GINT_HD3_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD4_CFG(pdata->mac_idx), + "MAC_GINT_HD4_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD5_CFG(pdata->mac_idx), + "MAC_GINT_HD5_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_GINT_HD6_CFG(pdata->mac_idx), + "MAC_GINT_HD6_CFG", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_TXTS_0(pdata->mac_idx), + "MAC_TXTS_0", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_TXTS_1(pdata->mac_idx), + "MAC_TXTS_1", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_TXTS_2(pdata->mac_idx), + "MAC_TXTS_2", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_TXTS_3(pdata->mac_idx), + "MAC_TXTS_3", pdata->mac_idx, 0xFFFF, 0); + gswss_check_reg(pdev, MAC_TXTS_CIC(pdata->mac_idx), + "MAC_TXTS_CIC", pdata->mac_idx, 0x1F, 0); + gswss_check_reg(pdev, MAC_TXTS_ACC(pdata->mac_idx), + "MAC_TXTS_ACC", pdata->mac_idx, 0x403F, 0); + gswss_check_reg(pdev, PHY_MODE(pdata->mac_idx), + "PHY_MODE", pdata->mac_idx, 0xFFE0, 0); + gswss_check_reg(pdev, ANEG_EEE(pdata->mac_idx), + "ANEG_EEE", pdata->mac_idx, 0xF, 0); + gswss_check_reg(pdev, XGMAC_CTRL(pdata->mac_idx), + "XGMAC_CTRL", pdata->mac_idx, 0xF, 0); } void gswss_check_reg(void *pdev, u32 reg, char *name, int idx, @@ -1965,14 +1800,14 @@ void gswss_check_reg(void *pdev, u32 reg, char *name, int idx, val = GSWSS_MAC_RGRD(pdata, reg); if (val != set_val) - xgmac_printf("Setting reg %s: %d with %x FAILED\n", - name, idx, set_val); + mac_printf("Setting reg %s: %d with %x FAILED\n", + name, idx, set_val); GSWSS_MAC_RGWR(pdata, reg, clr_val); if (val != clr_val) - xgmac_printf("Setting reg %s: %d with %x FAILED\n", - name, idx, clr_val); + mac_printf("Setting reg %s: %d with %x FAILED\n", + name, idx, clr_val); } #if defined(PC_UTILITY) || defined(CHIPTEST) diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.h b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.h index a51c2aa2e3f4930edfe28debad69137ea06255b6..8987c90e3d36ddc2c17e9f1b2b2d6fbc752f750a 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/gswss_mac_api.h @@ -10,8 +10,8 @@ #ifndef _GSWIPSS_MAC_API #define _GSWIPSS_MAC_API -#include "xgmac_common.h" -#include "gswss_api.h" +#include <xgmac_common.h> +#include <gswss_api.h> #define MAC_IF_CFG(idx) (0x1200 + ((idx) * (0x100))) #define MAC_OP_CFG(idx) (0x1204 + ((idx) * (0x100))) @@ -46,6 +46,8 @@ #define MAC_IF_CFG_XGMAC_RES_WIDTH 1 #define MAC_IF_CFG_MAC_EN_POS 12 #define MAC_IF_CFG_MAC_EN_WIDTH 1 +#define MAC_IF_CFG_PTP_DIS_POS 11 +#define MAC_IF_CFG_PTP_DIS_WIDTH 1 #define MAC_IF_CFG_CFG1G_POS 1 #define MAC_IF_CFG_CFG1G_WIDTH 1 #define MAC_IF_CFG_CFGFE_POS 2 @@ -65,9 +67,11 @@ #define MAC_OP_CFG_TXFCS_RM_WIDTH 1 #define MAC_OP_CFG_TXFCS_INS_POS 9 #define MAC_OP_CFG_TXFCS_INS_WIDTH 1 +#define MAC_OP_CFG_NUM_STREAM_POS 10 +#define MAC_OP_CFG_NUM_STREAM_WIDTH 1 #define MAC_MTU_CFG_POS 0 -#define MAC_MTU_CFG_WIDTH 16 +#define MAC_MTU_CFG_WIDTH 14 #define MAC_TXTS_CIC_CIC_POS 0 #define MAC_TXTS_CIC_CIC_WIDTH 2 @@ -137,7 +141,7 @@ static inline u32 GSWSS_MAC_RGRD(struct mac_prv_data *pdata, u32 reg) #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_rd(reg_addr, ®_val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ reg_val = ltq_r32(reg_addr); #endif return reg_val; @@ -158,7 +162,7 @@ static inline void GSWSS_MAC_RGWR(struct mac_prv_data *pdata, u32 reg, #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_wr(reg_addr, val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ ltq_w32(val, reg_addr); #endif } @@ -229,9 +233,6 @@ int gswss_set_mac_txsptag_op(void *pdev, u32 val); int gswss_set_mac_rxsptag_op(void *pdev, u32 val); int gswss_set_mac_rxtime_op(void *pdev, u32 val); int gswss_set_mtu(void *pdev, u32 mtu); -int gswss_set_txtstamp(void *pdev, u32 nsec, u32 sec, u32 record_id); -int gswss_set_txtstamp_cic(void *pdev, u8 ttse, u8 ostc, u8 ost_avail, - u8 cic); int gswss_set_txtstamp_access(void *pdev, u32 op_mode, u32 addr); int gswss_set_duplex_mode(void *pdev, u32 val); int gswss_set_speed(void *pdev, u8 speed); @@ -246,7 +247,6 @@ int gswss_set_xgmac_rx_disable(void *pdev, u32 val); int gswss_set_xgmac_crc_ctrl(void *pdev, u32 val); int gswss_get_mtu(void *pdev); -void gswss_get_txtstamp(void *pdev, u32 record_id); u32 gswss_get_flowctrl_tx(void *pdev); u32 gswss_get_flowctrl_rx(void *pdev); u8 gswss_get_speed(void *pdev); @@ -257,11 +257,13 @@ int gswss_get_duplex_mode(void *pdev); int gswss_get_linkstatus(void *pdev); void gswss_get_xgmac_ctrl(void *pdev); void gswss_get_phy2mode(void *pdev); -void gswss_get_txtstamp_cic(void *pdev); -void gswss_get_txtstamp_access(void *pdev); void gswss_get_macop(void *pdev); void gswss_get_macif(void *pdev); int gswss_get_mac_en(void *pdev); int gswss_get_mac_reset(void *pdev); +int gswss_set_txtstamp_fifo(void *pdev, + u8 ttse, u8 ostc, u8 ost_avail, u8 cic, u32 sec, + u32 nsec, u32 record_id); +void gswss_get_txtstamp_fifo(void *pdev, u32 record_id); #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.c b/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.c index 90c0e0018ad74df4770f2677ffec11a3b3d683b0..1bca0f7262f297cfb44d6f0a8dcfcdaa7e38c619 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.c @@ -7,7 +7,7 @@ * ******************************************************************************/ -#include "lmac_api.h" +#include <lmac_api.h> static u32 read_lmac_cnt(void *pdev); static u32 write_lmac_cnt(void *pdev, u32 val); @@ -46,21 +46,17 @@ void lmac_help(void) int i = 0; int num_of_elem = (sizeof(lmac_cfg) / sizeof(struct _lmac_cfg)); - xgmac_printf("\n----Legacy MAC Commands----\n\n"); + mac_printf("\n----Legacy MAC Commands----\n\n"); for (i = 0; i < num_of_elem; i++) { if (lmac_cfg[i].help) { -#if defined(KERNEL_MODE) && KERNEL_MODE - xgmac_printf("switch_cli %s\n", - lmac_cfg[i].help); -#endif + #if defined(CHIPTEST) && CHIPTEST - xgmac_printf("gsw %s\n", - lmac_cfg[i].help); -#endif -#if defined(PC_UTILITY) && PC_UTILITY - xgmac_printf("%s\n", - lmac_cfg[i].help); + mac_printf("gsw %s\n", + lmac_cfg[i].help); +#else + mac_printf("switch_cli %s\n", + lmac_cfg[i].help); #endif } } @@ -73,36 +69,13 @@ int lmac_check_args(int argc, char *argv) for (i = 0; i < num_of_elem; i++) { if (!strcmp(argv, lmac_cfg[i].cmdname)) { -#if defined(KERNEL_MODE) && KERNEL_MODE if (argc != (lmac_cfg[i].args + 4)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("switch_cli %s\n", - lmac_cfg[i].help); - return -1; - } - -#endif -#if defined(CHIPTEST) && CHIPTEST - - if (argc != (lmac_cfg[i].args + 4)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("gsw %s\n", - lmac_cfg[i].help); - return -1; - } - -#endif -#if defined(PC_UTILITY) && PC_UTILITY - - if (argc != (lmac_cfg[i].args + 3)) { - xgmac_printf("\n--WRONG Command--\n"); - xgmac_printf("%s\n", - lmac_cfg[i].help); + mac_printf("\n--WRONG Command--\n"); + mac_printf("switch_cli %s\n", + lmac_cfg[i].help); return -1; } - -#endif } } @@ -113,8 +86,8 @@ void lmac_wr_reg(void *pdev, u32 reg_off, u32 reg_val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + reg_val); LMAC_RGWR(pdata, reg_off, reg_val); } @@ -125,8 +98,8 @@ u32 lmac_rd_reg(void *pdev, u32 reg_off) pdata->reg_val = LMAC_RGRD(pdata, reg_off); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - pdata->reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + pdata->reg_val); return pdata->reg_val; } @@ -139,18 +112,10 @@ int lmac_main(u32 argc, u8 *argv[]) struct mac_ops *ops; u32 reg_off, reg_val; -#if defined(PC_UTILITY) && PC_UTILITY - start_arg++; -#endif -#if defined(CHIPTEST) && CHIPTEST start_arg++; -#endif - -#if defined(KERNEL_MODE) && KERNEL_MODE start_arg++; - start_arg++; -#endif + if (argc <= 2) { lmac_help(); @@ -168,7 +133,7 @@ int lmac_main(u32 argc, u8 *argv[]) &start_arg); if (idx > 2 || idx < 0) { - xgmac_printf("Give valid lmac index 0/1/2/\n"); + mac_printf("Give valid lmac index 0/1/2/\n"); return -1; } @@ -180,14 +145,14 @@ int lmac_main(u32 argc, u8 *argv[]) } start_arg++; -#if defined(PC_UTILITY) || defined(KERNEL_MODE) +#if defined(PC_UTILITY) || defined(__KERNEL__) if ((strstr(argv[start_arg], "0x")) || (strstr(argv[start_arg], "0X"))) - xgmac_printf("matches with 0x\n"); + mac_printf("matches with 0x\n"); else - xgmac_printf("Please give the address with " - "0x firmat\n"); + mac_printf("Please give the address with " + "0x firmat\n"); #endif reg_off = mac_nstrtoul(argv[start_arg], @@ -205,14 +170,14 @@ int lmac_main(u32 argc, u8 *argv[]) start_arg++; -#if defined(PC_UTILITY) || defined(KERNEL_MODE) +#if defined(PC_UTILITY) || defined(__KERNEL__) if ((strstr(argv[start_arg], "0x")) || (strstr(argv[start_arg], "0X"))) - xgmac_printf("matches with 0x\n"); + mac_printf("matches with 0x\n"); else - xgmac_printf("Please give the address with " - "0x format\n"); + mac_printf("Please give the address with " + "0x format\n"); #endif reg_off = mac_nstrtoul(argv[start_arg], @@ -266,21 +231,21 @@ int lmac_set_intf_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, GMII) != val) { + if (MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, GMII) != val) { if (val == 0) - xgmac_printf("LMAC %d Intf: AUTO\n", - pdata->mac_idx); + mac_printf("LMAC %d Intf: AUTO\n", + pdata->mac_idx); else if (val == 1) - xgmac_printf("LMAC %d Intf: MII(10/100/200 Mbps)\n", - pdata->mac_idx); + mac_printf("LMAC %d Intf: MII(10/100/200 Mbps)\n", + pdata->mac_idx); else if (val == 2) - xgmac_printf("LMAC %d Intf: GMII (1000 Mbps)\n", - pdata->mac_idx); + mac_printf("LMAC %d Intf: GMII (1000 Mbps)\n", + pdata->mac_idx); else if (val == 3) - xgmac_printf("LMAC %d Intf: GMII_2G (2000 Mbps)\n", - pdata->mac_idx); + mac_printf("LMAC %d Intf: GMII_2G (2000 Mbps)\n", + pdata->mac_idx); - LMAC_SET_BITS(mac_ctrl0, MAC_CTRL0, GMII, val); + MAC_SET_VAL(mac_ctrl0, MAC_CTRL0, GMII, val); LMAC_RGWR(pdata, MAC_CTRL0(pdata->mac_idx), mac_ctrl0); } @@ -294,17 +259,17 @@ int lmac_get_intf_mode(void *pdev) u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); u32 val = 0; - xgmac_printf("LMAC %d INTF MODE %08x\n", pdata->mac_idx, mac_ctrl0); - val = LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, GMII); + mac_printf("LMAC %d INTF MODE %08x\n", pdata->mac_idx, mac_ctrl0); + val = MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, GMII); if (val == 0) - xgmac_printf("\tIntf mode set to : AUTO\n"); + mac_printf("\tIntf mode set to : AUTO\n"); else if (val == 1) - xgmac_printf("\tIntf mode set to : MII (10/100/200 Mbps)\n"); + mac_printf("\tIntf mode set to : MII (10/100/200 Mbps)\n"); else if (val == 2) - xgmac_printf("\tIntf mode set to : GMII (1000 Mbps)\n"); + mac_printf("\tIntf mode set to : GMII (1000 Mbps)\n"); else if (val == 3) - xgmac_printf("\tIntf mode set to : GMII_2G (2000 Mbps)\n"); + mac_printf("\tIntf mode set to : GMII_2G (2000 Mbps)\n"); return 0; } @@ -314,21 +279,21 @@ int lmac_set_duplex_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FDUP) != val) { + if (MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FDUP) != val) { if (val == 0) - xgmac_printf("LMAC %d FDUP set to: AUTO\n", - pdata->mac_idx); + mac_printf("LMAC %d FDUP set to: AUTO\n", + pdata->mac_idx); else if (val == 1) - xgmac_printf("LMAC %d FDUP set to: Full Duplex Mode\n", - pdata->mac_idx); + mac_printf("LMAC %d FDUP set to: Full Duplex Mode\n", + pdata->mac_idx); else if (val == 2) - xgmac_printf("LMAC %d FDUP set to: Reserved\n", - pdata->mac_idx); + mac_printf("LMAC %d FDUP set to: Reserved\n", + pdata->mac_idx); else if (val == 3) - xgmac_printf("LMAC %d FDUP set to: Half Duplex Mode\n", - pdata->mac_idx); + mac_printf("LMAC %d FDUP set to: Half Duplex Mode\n", + pdata->mac_idx); - LMAC_SET_BITS(mac_ctrl0, MAC_CTRL0, FDUP, val); + MAC_SET_VAL(mac_ctrl0, MAC_CTRL0, FDUP, val); LMAC_RGWR(pdata, MAC_CTRL0(pdata->mac_idx), mac_ctrl0); } @@ -342,18 +307,18 @@ int lmac_get_duplex_mode(void *pdev) u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d DUPLEX MODE %08x\n", pdata->mac_idx, mac_ctrl0); + mac_printf("LMAC %d DUPLEX MODE %08x\n", pdata->mac_idx, mac_ctrl0); - val = LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FDUP); + val = MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FDUP); if (val == 0) - xgmac_printf("\tFDUP mode set to : AUTO\n"); + mac_printf("\tFDUP mode set to : AUTO\n"); else if (val == 1) - xgmac_printf("\tFDUP mode set to : Full Duplex Mode\n"); + mac_printf("\tFDUP mode set to : Full Duplex Mode\n"); else if (val == 2) - xgmac_printf("\tFDUP mode set to : Reserved\n"); + mac_printf("\tFDUP mode set to : Reserved\n"); else if (val == 3) - xgmac_printf("\tFDUP mode set to : Half Duplex Mode\n"); + mac_printf("\tFDUP mode set to : Half Duplex Mode\n"); return val; } @@ -363,24 +328,24 @@ int lmac_set_flowcon_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FCON) != val) { + if (MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FCON) != val) { if (val == 0) - xgmac_printf("LMAC %d FCON mode set to : AUTO\n", - pdata->mac_idx); + mac_printf("LMAC %d FCON mode set to : AUTO\n", + pdata->mac_idx); else if (val == 1) - xgmac_printf("LMAC %d FCON mode set to : RX only\n", - pdata->mac_idx); + mac_printf("LMAC %d FCON mode set to : RX only\n", + pdata->mac_idx); else if (val == 2) - xgmac_printf("LMAC %d FCON mode set to : TX only\n", - pdata->mac_idx); + mac_printf("LMAC %d FCON mode set to : TX only\n", + pdata->mac_idx); else if (val == 3) - xgmac_printf("LMAC %d FCON mode set to : RXTX \n", - pdata->mac_idx); + mac_printf("LMAC %d FCON mode set to : RXTX \n", + pdata->mac_idx); else if (val == 4) - xgmac_printf("LMAC %d FCON mode set to : DISABLED\n", - pdata->mac_idx); + mac_printf("LMAC %d FCON mode set to : DISABLED\n", + pdata->mac_idx); - LMAC_SET_BITS(mac_ctrl0, MAC_CTRL0, FCON, val); + MAC_SET_VAL(mac_ctrl0, MAC_CTRL0, FCON, val); LMAC_RGWR(pdata, MAC_CTRL0(pdata->mac_idx), mac_ctrl0); } @@ -394,21 +359,21 @@ u32 lmac_get_flowcon_mode(void *pdev) u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d FLOWCONTROL MODE %08x\n", - pdata->mac_idx, mac_ctrl0); + mac_printf("LMAC %d FLOWCONTROL MODE %08x\n", + pdata->mac_idx, mac_ctrl0); - val = LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FCON); + val = MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FCON); if (val == 0) - xgmac_printf("\tFCON mode set to : AUTO\n"); + mac_printf("\tFCON mode set to : AUTO\n"); else if (val == 1) - xgmac_printf("\tFCON mode set to : Receive only\n"); + mac_printf("\tFCON mode set to : Receive only\n"); else if (val == 2) - xgmac_printf("\tFCON mode set to : transmit only\n"); + mac_printf("\tFCON mode set to : transmit only\n"); else if (val == 3) - xgmac_printf("\tFCON mode set to : RXTX\n"); + mac_printf("\tFCON mode set to : RXTX\n"); else if (val == 4) - xgmac_printf("\tFCON mode set to : DISABLED\n"); + mac_printf("\tFCON mode set to : DISABLED\n"); return val; } @@ -418,10 +383,10 @@ int lmac_set_txfcs(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FCS) != val) { - xgmac_printf("LMAC %d FCS generation : %s\n", pdata->mac_idx, - val ? "ENABLED" : "DISABLED"); - LMAC_SET_BITS(mac_ctrl0, MAC_CTRL0, FCS, val); + if (MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FCS) != val) { + mac_printf("LMAC %d FCS generation : %s\n", pdata->mac_idx, + val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_ctrl0, MAC_CTRL0, FCS, val); LMAC_RGWR(pdata, MAC_CTRL0(pdata->mac_idx), mac_ctrl0); } @@ -435,10 +400,10 @@ int lmac_get_txfcs(void *pdev) u32 mac_ctrl0 = LMAC_RGRD(pdata, MAC_CTRL0(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d FCS %08x\n", pdata->mac_idx, mac_ctrl0); + mac_printf("LMAC %d FCS %08x\n", pdata->mac_idx, mac_ctrl0); - val = LMAC_GET_BITS(mac_ctrl0, MAC_CTRL0, FCS); - xgmac_printf("\tFCS generation : %s\n", val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_ctrl0, MAC_CTRL0, FCS); + mac_printf("\tFCS generation : %s\n", val ? "ENABLED" : "DISABLED"); return val; } @@ -451,37 +416,209 @@ int lmac_set_int(void *pdev, u32 val) pdata->mac_idx += LMAC_IER_MAC2_POS; SET_N_BITS(lmac_ier, pdata->mac_idx, LMAC_IER_MAC2_WIDTH, val); - xgmac_printf("LMAC %d Interrupt : %s\n", pdata->mac_idx, - val ? "ENABLED" : "DISABLED"); + //mac_printf("LMAC %d Interrupt : %s\n", pdata->mac_idx, + // val ? "ENABLED" : "DISABLED"); LMAC_RGWR(pdata, LMAC_IER, lmac_ier); return 0; } -int lmac_get_int_stat(void *pdev) +int lmac_set_event_int(void *pdev, u32 evnt, u32 val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - u32 lmac_isr = LMAC_RGRD(pdata, LMAC_ISR); - u32 val = 0; + u32 lmac_pier = LMAC_RGRD(pdata, MAC_PIER(pdata->mac_idx)); + + switch (evnt) { + case LMAC_PHYERR_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, PHYERR, val); + break; + + case LMAC_ALIGN_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, ALIGN, val); + break; + + case LMAC_SPEED_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, SPEED, val); + break; + + case LMAC_FDUP_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, FDUP, val); + break; + + case LMAC_RXPAUEN_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, RXPAUEN, val); + break; + + case LMAC_TXPAUEN_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, TXPAUEN, val); + break; - pdata->mac_idx += LMAC_ISR_MAC2_POS; - val = GET_N_BITS(lmac_isr, pdata->mac_idx, LMAC_ISR_MAC2_WIDTH); + case LMAC_LPIOFF_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, LPIOFF, val); + break; - xgmac_printf("LMAC %d Interrupt Stats : %s\n", pdata->mac_idx, - val ? "ENABLED" : "DISABLED"); + case LMAC_LPION_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, LPION, val); + break; + + case LMAC_JAM_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, JAM, val); + break; + + case LMAC_FCSERR_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, FCSERR, val); + break; + + case LMAC_TXPAU_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, TXPAUSE, val); + break; + + case LMAC_RXPAU_EVNT: + MAC_SET_VAL(lmac_pier, MAC_PIER, RXPAUSE, val); + break; + + case LMAC_ALL_EVNT: + if (val) + lmac_pier = 0xFFFFFFFF; + else + lmac_pier = 0; + + break; + + default: + return -1; + } + mac_printf("LMAC %d PIER Interrupt Value: %d\n", pdata->mac_idx, + lmac_pier); + LMAC_RGWR(pdata, MAC_PIER(pdata->mac_idx), lmac_pier); + + return 0; +} + +int lmac_get_int(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 lmac_isr = LMAC_RGRD(pdata, LMAC_ISR); + u32 val = 0, mac_idx = 0; + + mac_idx = pdata->mac_idx + LMAC_ISR_MAC2_POS; + val = GET_N_BITS(lmac_isr, mac_idx, LMAC_ISR_MAC2_WIDTH); + +#if 0 + mac_printf("LMAC %d Interrupt Stats : %s\n", pdata->mac_idx, + val ? "ENABLED" : "DISABLED"); +#endif return val; } +/* Clear all the LMAC interrupts, Write 1 to Clear */ +int lmac_clear_int(void *pdev, u32 event) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 mac_isr = 0; + + /* Clear all the interrupts which are set */ + mac_isr = LMAC_RGRD(pdata, MAC_PISR(pdata->mac_idx)); + + if ((event & LMAC_PHYERR_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, PHYERR))) { + mac_printf("LMAC %d Clearing PHYERR Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, PHYERR, 1); + } + + if ((event & LMAC_ALIGN_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, ALIGN))) { + mac_printf("LMAC %d Clearing ALIGN Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, ALIGN, 1); + } + + if ((event & LMAC_SPEED_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, SPEED))) { + mac_printf("LMAC %d Clearing SPEED Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, SPEED, 1); + } + + if ((event & LMAC_FDUP_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, FDUP))) { + mac_printf("LMAC %d Clearing FDUP Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, FDUP, 1); + } + + if ((event & LMAC_RXPAUEN_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, RXPAUEN))) { + mac_printf("LMAC %d Clearing RXPAUEN Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, RXPAUEN, 1); + } + + if ((event & LMAC_TXPAUEN_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, TXPAUEN))) { + mac_printf("LMAC %d Clearing TXPAUEN Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, TXPAUEN, 1); + } + + if ((event & LMAC_LPIOFF_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, LPIOFF))) { + mac_printf("LMAC %d Clearing LPIOFF Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, LPIOFF, 1); + } + + if ((event & LMAC_LPION_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, LPION))) { + mac_printf("LMAC %d Clearing LPION Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, LPION, 1); + } + + if ((event & LMAC_JAM_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, JAM))) { + mac_printf("LMAC %d Clearing JAM Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, JAM, 1); + } + + if ((event & LMAC_FCSERR_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, FCSERR))) { + mac_printf("LMAC %d Clearing FCSERR Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, FCSERR, 1); + } + + if ((event & LMAC_TXPAU_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, TXPAUSE))) { + mac_printf("LMAC %d Clearing TXPAUSE Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, TXPAUSE, 1); + } + + if ((event & LMAC_RXPAU_EVNT) && + (MAC_GET_VAL(mac_isr, MAC_PISR, RXPAUSE))) { + mac_printf("LMAC %d Clearing RXPAUSE Interrupt Status\n", + pdata->mac_idx); + MAC_SET_VAL(mac_isr, MAC_PISR, RXPAUSE, 1); + } + + LMAC_RGWR(pdata, MAC_PISR(pdata->mac_idx), mac_isr); + + return 0; +} + int lmac_set_ipg(void *pdev, u32 val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, IPG) != val) { - xgmac_printf("LMAC %d IPG set to : %d bytes\n", - pdata->mac_idx, val); - LMAC_SET_BITS(mac_ctrl1, MAC_CTRL1, IPG, val); + if (MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, IPG) != val) { + mac_printf("LMAC %d IPG set to : %d bytes\n", + pdata->mac_idx, val); + MAC_SET_VAL(mac_ctrl1, MAC_CTRL1, IPG, val); LMAC_RGWR(pdata, MAC_CTRL1(pdata->mac_idx), mac_ctrl1); } @@ -495,10 +632,10 @@ int lmac_get_ipg(void *pdev) u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d IPG %08x\n", pdata->mac_idx, mac_ctrl1); + mac_printf("LMAC %d IPG %08x\n", pdata->mac_idx, mac_ctrl1); - val = LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, IPG); - xgmac_printf("\tIPG set to %d : bytes\n", val); + val = MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, IPG); + mac_printf("\tIPG set to %d : bytes\n", val); return val; } @@ -508,10 +645,10 @@ int lmac_set_preamble(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, SHORTPRE) != val) { - xgmac_printf("LMAC %d Preamble is : %s\n", pdata->mac_idx, - val ? "0 byte" : "7 byte"); - LMAC_SET_BITS(mac_ctrl1, MAC_CTRL1, SHORTPRE, val); + if (MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, SHORTPRE) != val) { + mac_printf("LMAC %d Preamble is : %s\n", pdata->mac_idx, + val ? "0 byte" : "7 byte"); + MAC_SET_VAL(mac_ctrl1, MAC_CTRL1, SHORTPRE, val); LMAC_RGWR(pdata, MAC_CTRL1(pdata->mac_idx), mac_ctrl1); } @@ -525,10 +662,10 @@ int lmac_get_preamble(void *pdev) u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d PREAMBLE %08x\n", pdata->mac_idx, mac_ctrl1); + mac_printf("LMAC %d PREAMBLE %08x\n", pdata->mac_idx, mac_ctrl1); - val = LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, SHORTPRE); - xgmac_printf("\tPreamble is : %s\n", val ? "0 byte" : "7 byte"); + val = MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, SHORTPRE); + mac_printf("\tPreamble is : %s\n", val ? "0 byte" : "7 byte"); return val; } @@ -538,12 +675,12 @@ int lmac_set_defermode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, DEFERMODE) != val) { - xgmac_printf("LMAC %d CRS backpressure : %s\n", pdata->mac_idx, - val ? - "Enabled in Full Duplex mode" : - "Enabled in Half Duplex mode"); - LMAC_SET_BITS(mac_ctrl1, MAC_CTRL1, DEFERMODE, val); + if (MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, DEFERMODE) != val) { + mac_printf("LMAC %d CRS backpressure : %s\n", pdata->mac_idx, + val ? + "Enabled in Full Duplex mode" : + "Enabled in Half Duplex mode"); + MAC_SET_VAL(mac_ctrl1, MAC_CTRL1, DEFERMODE, val); LMAC_RGWR(pdata, MAC_CTRL1(pdata->mac_idx), mac_ctrl1); } @@ -557,13 +694,13 @@ int lmac_get_defermode(void *pdev) u32 mac_ctrl1 = LMAC_RGRD(pdata, MAC_CTRL1(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d DEFERMODE %08x\n", pdata->mac_idx, mac_ctrl1); + mac_printf("LMAC %d DEFERMODE %08x\n", pdata->mac_idx, mac_ctrl1); - val = LMAC_GET_BITS(mac_ctrl1, MAC_CTRL1, DEFERMODE); - xgmac_printf("\tCRS backpressure : %s\n", - val ? - "Enabled in Full Duplex mode" : - "Enabled in Half Duplex mode"); + val = MAC_GET_VAL(mac_ctrl1, MAC_CTRL1, DEFERMODE); + mac_printf("\tCRS backpressure : %s\n", + val ? + "Enabled in Full Duplex mode" : + "Enabled in Half Duplex mode"); return val; } @@ -573,22 +710,22 @@ int lmac_set_lpi(void *pdev, u32 mode_en, u32 lpi_waitg, u32 lpi_waitm) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl4 = LMAC_RGRD(pdata, MAC_CTRL4(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, LPIEN) != mode_en) { - xgmac_printf("LMAC %d LPI Mode : %s\n", pdata->mac_idx, - mode_en ? "ENABLED" : "DISABLED"); - LMAC_SET_BITS(mac_ctrl4, MAC_CTRL4, LPIEN, mode_en); + if (MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, LPIEN) != mode_en) { + mac_printf("LMAC %d LPI Mode : %s\n", pdata->mac_idx, + mode_en ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_ctrl4, MAC_CTRL4, LPIEN, mode_en); } - if (LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, WAIT) != lpi_waitm) { - xgmac_printf("LMAC %d LPI Wait time for 100M : %d usec\n", - pdata->mac_idx, lpi_waitm); - LMAC_SET_BITS(mac_ctrl4, MAC_CTRL4, WAIT, lpi_waitm); + if (MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, WAIT) != lpi_waitm) { + mac_printf("LMAC %d LPI Wait time for 100M : %d usec\n", + pdata->mac_idx, lpi_waitm); + MAC_SET_VAL(mac_ctrl4, MAC_CTRL4, WAIT, lpi_waitm); } - if (LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, GWAIT) != lpi_waitg) { - xgmac_printf("LMAC %d LPI Wait time for 1G : %d usec\n", - pdata->mac_idx, lpi_waitg); - LMAC_SET_BITS(mac_ctrl4, MAC_CTRL4, GWAIT, lpi_waitg); + if (MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, GWAIT) != lpi_waitg) { + mac_printf("LMAC %d LPI Wait time for 1G : %d usec\n", + pdata->mac_idx, lpi_waitg); + MAC_SET_VAL(mac_ctrl4, MAC_CTRL4, GWAIT, lpi_waitg); } LMAC_RGWR(pdata, MAC_CTRL4(pdata->mac_idx), mac_ctrl4); @@ -601,16 +738,16 @@ int lmac_get_lpi(void *pdev, u32 *mode_en, u32 *lpi_waitg, u32 *lpi_waitm) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl4 = LMAC_RGRD(pdata, MAC_CTRL4(pdata->mac_idx)); - xgmac_printf("LMAC %d LPI %08x\n", pdata->mac_idx, mac_ctrl4); + mac_printf("LMAC %d LPI %08x\n", pdata->mac_idx, mac_ctrl4); - *mode_en = LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, LPIEN); - xgmac_printf("\tLPI Mode : %s\n", *mode_en ? "ENABLED" : "DISABLED"); + *mode_en = MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, LPIEN); + mac_printf("\tLPI Mode : %s\n", *mode_en ? "ENABLED" : "DISABLED"); - *lpi_waitm = LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, WAIT); - xgmac_printf("\tLPI Wait time for 100M : %d usec\n", *lpi_waitm); + *lpi_waitm = MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, WAIT); + mac_printf("\tLPI Wait time for 100M : %d usec\n", *lpi_waitm); - *lpi_waitg = LMAC_GET_BITS(mac_ctrl4, MAC_CTRL4, GWAIT); - xgmac_printf("\tLPI Wait time for 1G : %d usec\n", *lpi_waitg); + *lpi_waitg = MAC_GET_VAL(mac_ctrl4, MAC_CTRL4, GWAIT); + mac_printf("\tLPI Wait time for 1G : %d usec\n", *lpi_waitg); return 0; } @@ -620,22 +757,22 @@ int lmac_set_jps(void *pdev, u32 pjps_bp, u32 pjps_nobp) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_ctrl5 = LMAC_RGRD(pdata, MAC_CTRL5(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_BP) != pjps_bp) { - xgmac_printf("LMAC %d Prolong Jam Pattern Size during " - "backpressure : %s\n", - pdata->mac_idx, pjps_bp ? - "64 bit jam pattern" : - "32 bit jam pattern"); - LMAC_SET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_BP, pjps_bp); + if (MAC_GET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_BP) != pjps_bp) { + mac_printf("LMAC %d Prolong Jam Pattern Size during " + "backpressure : %s\n", + pdata->mac_idx, pjps_bp ? + "64 bit jam pattern" : + "32 bit jam pattern"); + MAC_SET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_BP, pjps_bp); } - if (LMAC_GET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_NOBP) != pjps_nobp) { - xgmac_printf("LMAC %d Prolong Jam Pattern Size during " - "no-backpressure : %s\n", - pdata->mac_idx, pjps_nobp ? - "64 bit jam pattern" : - "32 bit jam pattern"); - LMAC_SET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_NOBP, pjps_nobp); + if (MAC_GET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_NOBP) != pjps_nobp) { + mac_printf("LMAC %d Prolong Jam Pattern Size during " + "no-backpressure : %s\n", + pdata->mac_idx, pjps_nobp ? + "64 bit jam pattern" : + "32 bit jam pattern"); + MAC_SET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_NOBP, pjps_nobp); } LMAC_RGWR(pdata, MAC_CTRL5(pdata->mac_idx), mac_ctrl5); @@ -649,19 +786,19 @@ int lmac_get_jps(void *pdev) u32 mac_ctrl5 = LMAC_RGRD(pdata, MAC_CTRL5(pdata->mac_idx)); u32 pjps_bp, pjps_nobp; - xgmac_printf("LMAC %d JPS %08x\n", pdata->mac_idx, mac_ctrl5); + mac_printf("LMAC %d JPS %08x\n", pdata->mac_idx, mac_ctrl5); - pjps_bp = LMAC_GET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_BP); - xgmac_printf("\tProlong Jam Pattern Size during backpressure : %s\n", - pjps_bp ? - "64 bit jam pattern" : - "32 bit jam pattern"); + pjps_bp = MAC_GET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_BP); + mac_printf("\tProlong Jam Pattern Size during backpressure : %s\n", + pjps_bp ? + "64 bit jam pattern" : + "32 bit jam pattern"); - pjps_nobp = LMAC_GET_BITS(mac_ctrl5, MAC_CTRL5, PJPS_NOBP); - xgmac_printf("\tProlong Jam Pattern Size during no-backpressure : %s\n", - pjps_nobp ? - "64 bit jam pattern" : - "32 bit jam pattern"); + pjps_nobp = MAC_GET_VAL(mac_ctrl5, MAC_CTRL5, PJPS_NOBP); + mac_printf("\tProlong Jam Pattern Size during no-backpressure : %s\n", + pjps_nobp ? + "64 bit jam pattern" : + "32 bit jam pattern"); return 0; } @@ -671,10 +808,10 @@ int lmac_set_loopback(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_testen, MAC_TESTEN, LOOP) != val) { - xgmac_printf("LMAC %d Loopback : %s\n", pdata->mac_idx, - val ? "ENABLED" : "DISABLED"); - LMAC_SET_BITS(mac_testen, MAC_TESTEN, LOOP, val); + if (MAC_GET_VAL(mac_testen, MAC_TESTEN, LOOP) != val) { + mac_printf("LMAC %d Loopback : %s\n", pdata->mac_idx, + val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_testen, MAC_TESTEN, LOOP, val); LMAC_RGWR(pdata, MAC_TESTEN(pdata->mac_idx), mac_testen); } @@ -688,10 +825,10 @@ int lmac_get_loopback(void *pdev) u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d Loopback: %08x\n", pdata->mac_idx, mac_testen); + mac_printf("LMAC %d Loopback: %08x\n", pdata->mac_idx, mac_testen); - val = LMAC_GET_BITS(mac_testen, MAC_TESTEN, LOOP); - xgmac_printf("\tLMAC: Loopback : %s\n", val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_testen, MAC_TESTEN, LOOP); + mac_printf("\tLMAC: Loopback : %s\n", val ? "ENABLED" : "DISABLED"); return val; } @@ -702,10 +839,10 @@ int lmac_set_txer(void *pdev, u32 val) u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_testen, MAC_TESTEN, TXER) != val) { - xgmac_printf("LMAC %d Inject transmit error : %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - LMAC_SET_BITS(mac_testen, MAC_TESTEN, TXER, val); + if (MAC_GET_VAL(mac_testen, MAC_TESTEN, TXER) != val) { + mac_printf("LMAC %d Inject transmit error : %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_testen, MAC_TESTEN, TXER, val); LMAC_RGWR(pdata, MAC_TESTEN(pdata->mac_idx), mac_testen); } @@ -719,11 +856,11 @@ int lmac_get_txer(void *pdev) u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d TXER %08x\n", pdata->mac_idx, mac_testen); + mac_printf("LMAC %d TXER %08x\n", pdata->mac_idx, mac_testen); - val = LMAC_GET_BITS(mac_testen, MAC_TESTEN, TXER); - xgmac_printf("\tInject transmit error : %s\n", - val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_testen, MAC_TESTEN, TXER); + mac_printf("\tInject transmit error : %s\n", + val ? "ENABLED" : "DISABLED"); return val; } @@ -733,18 +870,18 @@ int lmac_set_lpimonitor_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); - if (LMAC_GET_BITS(mac_testen, MAC_TESTEN, LPITM) != val) { + if (MAC_GET_VAL(mac_testen, MAC_TESTEN, LPITM) != val) { if (val == 0) - xgmac_printf("LMAC %d LPI to be monitored in " - "time recording : TX\n", pdata->mac_idx); + mac_printf("LMAC %d LPI to be monitored in " + "time recording : TX\n", pdata->mac_idx); else if (val == 1) - xgmac_printf("LMAC %d LPI to be monitored in " - "time recording : RX\n", pdata->mac_idx); + mac_printf("LMAC %d LPI to be monitored in " + "time recording : RX\n", pdata->mac_idx); else if (val == 2) - xgmac_printf("LMAC %d LPI to be monitored in " - "time recording : TXRX\n", pdata->mac_idx); + mac_printf("LMAC %d LPI to be monitored in " + "time recording : TXRX\n", pdata->mac_idx); - LMAC_SET_BITS(mac_testen, MAC_TESTEN, LPITM, val); + MAC_SET_VAL(mac_testen, MAC_TESTEN, LPITM, val); LMAC_RGWR(pdata, MAC_TESTEN(pdata->mac_idx), mac_testen); } @@ -758,17 +895,17 @@ int lmac_get_lpimonitor_mode(void *pdev) u32 mac_testen = LMAC_RGRD(pdata, MAC_TESTEN(pdata->mac_idx)); u32 val; - xgmac_printf("LMAC %d LPI MONITORING MODE %08x\n", - pdata->mac_idx, mac_testen); + mac_printf("LMAC %d LPI MONITORING MODE %08x\n", + pdata->mac_idx, mac_testen); - val = LMAC_GET_BITS(mac_testen, MAC_TESTEN, LPITM); + val = MAC_GET_VAL(mac_testen, MAC_TESTEN, LPITM); if (val == 0) - xgmac_printf("\tLPI to be monitored in time recording : TX\n"); + mac_printf("\tLPI to be monitored in time recording : TX\n"); else if (val == 1) - xgmac_printf("\tLPI to be monitored in time recording : RX\n"); + mac_printf("\tLPI to be monitored in time recording : RX\n"); else if (val == 2) - xgmac_printf("\tLPI to be monitored in time recording : TXRX\n"); + mac_printf("\tLPI to be monitored in time recording : TXRX\n"); return val; } @@ -778,12 +915,12 @@ int lmac_set_pauseframe_samode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_pfad = LMAC_RGRD(pdata, MAC_PFADCFG); - if (LMAC_GET_BITS(mac_pfad, MAC_PFADCFG, SAMOD) != val) { - xgmac_printf("LMAC: Pause frame use : %s\n", - val ? - "PORT specific MAC source address" : - "COMMON MAC source address"); - LMAC_SET_BITS(mac_pfad, MAC_PFADCFG, SAMOD, val); + if (MAC_GET_VAL(mac_pfad, MAC_PFADCFG, SAMOD) != val) { + mac_printf("LMAC: Pause frame use : %s\n", + val ? + "PORT specific MAC source address" : + "COMMON MAC source address"); + MAC_SET_VAL(mac_pfad, MAC_PFADCFG, SAMOD, val); LMAC_RGWR(pdata, MAC_PFADCFG, mac_pfad); } @@ -797,13 +934,13 @@ int lmac_get_pauseframe_samode(void *pdev) u32 mac_pfad = LMAC_RGRD(pdata, MAC_PFADCFG); u32 val; - xgmac_printf("LMAC: PAUSE FRAME SAMODE %08x\n", mac_pfad); + mac_printf("LMAC: PAUSE FRAME SAMODE %08x\n", mac_pfad); - val = LMAC_GET_BITS(mac_pfad, MAC_PFADCFG, SAMOD); - xgmac_printf("\tPause frame use : %s\n", - val ? - "PORT specific MAC source address" : - "COMMON MAC source address"); + val = MAC_GET_VAL(mac_pfad, MAC_PFADCFG, SAMOD); + mac_printf("\tPause frame use : %s\n", + val ? + "PORT specific MAC source address" : + "COMMON MAC source address"); return val; } @@ -818,17 +955,17 @@ int lmac_set_pauseframe_addr(void *pdev, u8 *mac_addr) mac_addr_0 = (mac_addr[1] << 8) | (mac_addr[0] << 0); if (LMAC_RGRD(pdata, MAC_PFSA_0) != mac_addr_0) { - xgmac_printf("Setting mac_addr_0 as %08x\n", mac_addr_0); + mac_printf("Setting mac_addr_0 as %08x\n", mac_addr_0); LMAC_RGWR(pdata, MAC_PFSA_0, mac_addr_0); } if (LMAC_RGRD(pdata, MAC_PFSA_1) != mac_addr_1) { - xgmac_printf("Setting mac_addr_1 as %08x\n", mac_addr_1); + mac_printf("Setting mac_addr_1 as %08x\n", mac_addr_1); LMAC_RGWR(pdata, MAC_PFSA_1, mac_addr_1); } if (LMAC_RGRD(pdata, MAC_PFSA_2) != mac_addr_2) { - xgmac_printf("Setting mac_addr_2 as %08x\n", mac_addr_2); + mac_printf("Setting mac_addr_2 as %08x\n", mac_addr_2); LMAC_RGWR(pdata, MAC_PFSA_2, mac_addr_2); } @@ -860,75 +997,75 @@ int lmac_get_mac_pstat(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_pstat = LMAC_RGRD(pdata, MAC_PSTAT(pdata->mac_idx)); - xgmac_printf("LMAC %d PORT STAT: %08x\n", pdata->mac_idx, mac_pstat); + mac_printf("LMAC %d PORT STAT: %08x\n", pdata->mac_idx, mac_pstat); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, RXLPI)) - xgmac_printf("\tReceive Low Power Idle Status : " - "LPI Low power idle state\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, RXLPI)) + mac_printf("\tReceive Low Power Idle Status : " + "LPI Low power idle state\n"); else - xgmac_printf("\tReceive Low Power Idle Status : " - "Normal Power state\n"); + mac_printf("\tReceive Low Power Idle Status : " + "Normal Power state\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, TXLPI)) - xgmac_printf("\tTransmit Low Power Idle Status : " - "LPI Low power idle state\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, TXLPI)) + mac_printf("\tTransmit Low Power Idle Status : " + "LPI Low power idle state\n"); else - xgmac_printf("\tTransmit Low Power Idle Status : " - "Normal Power state\n"); + mac_printf("\tTransmit Low Power Idle Status : " + "Normal Power state\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, CRS)) - xgmac_printf("\tCarrier Detected\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, CRS)) + mac_printf("\tCarrier Detected\n"); else - xgmac_printf("\tNo Carrier Detected\n"); + mac_printf("\tNo Carrier Detected\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, LSTAT)) - xgmac_printf("\tLink is : UP\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, LSTAT)) + mac_printf("\tLink is : UP\n"); else - xgmac_printf("\tLink is : DOWN\n"); + mac_printf("\tLink is : DOWN\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, TXPAUEN)) - xgmac_printf("\tLink Partner accepts Pause frames\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, TXPAUEN)) + mac_printf("\tLink Partner accepts Pause frames\n"); else - xgmac_printf("\tLink Partner doesnot accepts Pause frames\n"); + mac_printf("\tLink Partner doesnot accepts Pause frames\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, RXPAUEN)) - xgmac_printf("\tLink Partner sends Pause frames\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, RXPAUEN)) + mac_printf("\tLink Partner sends Pause frames\n"); else - xgmac_printf("\tLink Partner doesnot sends Pause frames\n"); + mac_printf("\tLink Partner doesnot sends Pause frames\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, TXPAU)) - xgmac_printf("\tTransmit Pause status is active\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, TXPAU)) + mac_printf("\tTransmit Pause status is active\n"); else - xgmac_printf("\tNormal transmit operation\n"); + mac_printf("\tNormal transmit operation\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, RXPAU)) - xgmac_printf("\tReceive Pause status is active\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, RXPAU)) + mac_printf("\tReceive Pause status is active\n"); else - xgmac_printf("\tNormal Receive operation\n"); + mac_printf("\tNormal Receive operation\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, FDUP)) - xgmac_printf("\tFull duplex Mode\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, FDUP)) + mac_printf("\tFull duplex Mode\n"); else - xgmac_printf("\thalf Duplex mode\n"); + mac_printf("\thalf Duplex mode\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, MBIT)) - xgmac_printf("\tAttached PHY runs at a data rate of " - "100 Mbps\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, MBIT)) + mac_printf("\tAttached PHY runs at a data rate of " + "100 Mbps\n"); else - xgmac_printf("\tAttached PHY runs at a data rate of " - "10 Mbps\n"); + mac_printf("\tAttached PHY runs at a data rate of " + "10 Mbps\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, GBIT)) - xgmac_printf("\tAttached PHY runs at a data rate of " - "1000 or 2000 Mbps\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, GBIT)) + mac_printf("\tAttached PHY runs at a data rate of " + "1000 or 2000 Mbps\n"); else - xgmac_printf("\tAttached PHY runs at a data rate of " - "10 or 100 Mbps\n"); + mac_printf("\tAttached PHY runs at a data rate of " + "10 or 100 Mbps\n"); - if (LMAC_GET_BITS(mac_pstat, MAC_PSTAT, PACT)) - xgmac_printf("\tPHY is active and responds to MDIO accesses\n"); + if (MAC_GET_VAL(mac_pstat, MAC_PSTAT, PACT)) + mac_printf("\tPHY is active and responds to MDIO accesses\n"); else - xgmac_printf("\tPHY is inactive or not present\n"); + mac_printf("\tPHY is inactive or not present\n"); return 0; } @@ -938,58 +1075,58 @@ int lmac_get_mac_pisr(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_pisr = LMAC_RGRD(pdata, MAC_PISR(pdata->mac_idx)); - xgmac_printf("LMAC %d PORT INTERRUPT STATUS: %08x\n", - pdata->mac_idx, mac_pisr); + mac_printf("LMAC %d PORT INTERRUPT STATUS: %08x\n", + pdata->mac_idx, mac_pisr); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, RXPAUSE)) - xgmac_printf("\tAtleast 1 pause frame has been Received\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, RXPAUSE)) + mac_printf("\tAtleast 1 pause frame has been Received\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, TXPAUSE)) - xgmac_printf("\tAtleast 1 pause frame has been transmitted\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, TXPAUSE)) + mac_printf("\tAtleast 1 pause frame has been transmitted\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, FCSERR)) - xgmac_printf("\tFrame checksum Error Detected\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, FCSERR)) + mac_printf("\tFrame checksum Error Detected\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, LENERR)) - xgmac_printf("\tLength mismatch Error Detected\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, LENERR)) + mac_printf("\tLength mismatch Error Detected\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, TOOLONG)) - xgmac_printf("\tToo Long frame Error Detected\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, TOOLONG)) + mac_printf("\tToo Long frame Error Detected\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, TOOSHORT)) - xgmac_printf("\tToo Short frame Error Detected\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, TOOSHORT)) + mac_printf("\tToo Short frame Error Detected\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, JAM)) - xgmac_printf("\tJam status detected\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, JAM)) + mac_printf("\tJam status detected\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, LPION)) - xgmac_printf("\tReceive low power idle mode is entered\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, LPION)) + mac_printf("\tReceive low power idle mode is entered\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, LPIOFF)) - xgmac_printf("\tReceive low power idle mode is left\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, LPIOFF)) + mac_printf("\tReceive low power idle mode is left\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, TXPAUEN)) - xgmac_printf("\tA change of Transmit Pause Enable Status\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, TXPAUEN)) + mac_printf("\tA change of Transmit Pause Enable Status\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, RXPAUEN)) - xgmac_printf("\tA change of Receive Pause Enable Status\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, RXPAUEN)) + mac_printf("\tA change of Receive Pause Enable Status\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, FDUP)) - xgmac_printf("\tA change of half- or full-duplex mode\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, FDUP)) + mac_printf("\tA change of half- or full-duplex mode\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, SPEED)) - xgmac_printf("\tA change of speed mode\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, SPEED)) + mac_printf("\tA change of speed mode\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, PACT)) - xgmac_printf("\tA change of link activity\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, PACT)) + mac_printf("\tA change of link activity\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, ALIGN)) - xgmac_printf("\tA frame has been received which an " - "alignment error\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, ALIGN)) + mac_printf("\tA frame has been received which an " + "alignment error\n"); - if (LMAC_GET_BITS(mac_pisr, MAC_PISR, PHYERR)) - xgmac_printf("\tA frame has been received which has an " - "active rx_err signal\n"); + if (MAC_GET_VAL(mac_pisr, MAC_PISR, PHYERR)) + mac_printf("\tA frame has been received which has an " + "active rx_err signal\n"); return 0; } @@ -1039,14 +1176,14 @@ void lmac_check_reg(void *pdev, u32 reg, char *name, int idx, u16 set_val, val = LMAC_RGRD(pdata, reg); if (val != set_val) - xgmac_printf("Setting reg %s: %d with %x FAILED\n", - name, idx, set_val); + mac_printf("Setting reg %s: %d with %x FAILED\n", + name, idx, set_val); LMAC_RGWR(pdata, reg, clr_val); if (val != clr_val) - xgmac_printf("Setting reg %s: %d with %x FAILED\n", - name, idx, clr_val); + mac_printf("Setting reg %s: %d with %x FAILED\n", + name, idx, clr_val); } static u32 read_lmac_cnt(void *pdev) @@ -1080,12 +1217,12 @@ void lmac_rmon_rd(void *pdev, struct lmac_rmon_cnt *lmac_cnt) u32 lmac_cnt_acc = 0; int i = 0; - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_RD); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_RD); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); for (i = 0; i < 6; i++) { - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, i); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, i); LMAC_RGWR(pdata, REG_LMAC_CNT_ACC, lmac_cnt_acc); @@ -1131,12 +1268,12 @@ void lmac_rmon_wr(void *pdev, struct lmac_rmon_cnt *lmac_cnt) u32 lmac_cnt_acc = 0; int i = 0; - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_WR); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_WR); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); for (i = 0; i < 6; i++) { - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, i); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, i); LMAC_RGWR(pdata, REG_LMAC_CNT_ACC, lmac_cnt_acc); @@ -1181,11 +1318,11 @@ void lmac_rmon_clr(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 lmac_cnt_acc = 0; - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_CLR); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_CLR); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, MAC, pdata->mac_idx + 2); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, 0); // ignored + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, 0); // ignored LMAC_RGWR(pdata, REG_LMAC_CNT_ACC, lmac_cnt_acc); @@ -1200,11 +1337,11 @@ void lmac_rmon_clr_allmac(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 lmac_cnt_acc = 0; - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_CLRALL); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, MAC, 0); // ignored + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, OPMOD, LMAC_RMON_CLRALL); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, MAC, 0); // ignored - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); - LMAC_SET_BITS(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, 0); // ignored + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, BAS, 1); + MAC_SET_VAL(lmac_cnt_acc, LMAC_CNT_ACC, ADDR, 0); // ignored LMAC_RGWR(pdata, REG_LMAC_CNT_ACC, lmac_cnt_acc); @@ -1219,43 +1356,44 @@ void lmac_get_rmon(void) struct lmac_rmon_cnt lmac_cnt[3]; int i = 0; struct mac_ops *ops; + u32 max_mac = gsw_get_mac_subifcnt(0); - for (i = 0; i < 3; i++) { + for (i = 0; i < max_mac; i++) { ops = gsw_get_mac_ops(0, i); lmac_rmon_rd(ops, &lmac_cnt[i]); } - xgmac_printf("\nTYPE %11s %11s %11s\n", " LMAC 2", " LMAC 3", " LMAC 4\n"); + mac_printf("\nTYPE %11s %11s %11s\n", " LMAC 2", " LMAC 3", " LMAC 4\n"); - xgmac_printf("Single Collision Cnt = "); + mac_printf("Single Collision Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].sing_coln_cnt, - lmac_cnt[1].sing_coln_cnt, lmac_cnt[2].sing_coln_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].sing_coln_cnt, + lmac_cnt[1].sing_coln_cnt, lmac_cnt[2].sing_coln_cnt); - xgmac_printf("Multiple Collision Cnt = "); + mac_printf("Multiple Collision Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].mple_coln_cnt, - lmac_cnt[1].mple_coln_cnt, lmac_cnt[2].mple_coln_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].mple_coln_cnt, + lmac_cnt[1].mple_coln_cnt, lmac_cnt[2].mple_coln_cnt); - xgmac_printf("Late Collision Cnt = "); + mac_printf("Late Collision Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].late_coln_cnt, - lmac_cnt[1].late_coln_cnt, lmac_cnt[2].late_coln_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].late_coln_cnt, + lmac_cnt[1].late_coln_cnt, lmac_cnt[2].late_coln_cnt); - xgmac_printf("Excess Collision Cnt = "); + mac_printf("Excess Collision Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].excs_coln_cnt, - lmac_cnt[1].excs_coln_cnt, lmac_cnt[2].excs_coln_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].excs_coln_cnt, + lmac_cnt[1].excs_coln_cnt, lmac_cnt[2].excs_coln_cnt); - xgmac_printf("Rx Pause Cnt = "); + mac_printf("Rx Pause Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].rx_pause_cnt, - lmac_cnt[1].rx_pause_cnt, lmac_cnt[2].rx_pause_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].rx_pause_cnt, + lmac_cnt[1].rx_pause_cnt, lmac_cnt[2].rx_pause_cnt); - xgmac_printf("Tx Pause Cnt = "); + mac_printf("Tx Pause Cnt = "); - xgmac_printf("%11u %11u %11u", lmac_cnt[0].tx_pause_cnt, - lmac_cnt[1].tx_pause_cnt, lmac_cnt[2].tx_pause_cnt); + mac_printf("%11u %11u %11u", lmac_cnt[0].tx_pause_cnt, + lmac_cnt[1].tx_pause_cnt, lmac_cnt[2].tx_pause_cnt); - xgmac_printf("\n"); + mac_printf("\n"); } diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.h b/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.h index 77855340aea31b0d74ba9cfb457d9df6eba1b4ed..1b73516037682392adb84117fd56b9f7e9e8b11f 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/lmac_api.h @@ -10,7 +10,7 @@ #ifndef _LMAC_ #define _LMAC_ -#include "xgmac_common.h" +#include <xgmac_common.h> #if defined(PC_UTILITY) && PC_UTILITY #define LEGACY_MAC_BASE 0x42000 #else @@ -268,7 +268,7 @@ static inline u32 LMAC_RGRD(struct mac_prv_data *pdata, u32 reg) #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_rd(reg_addr, ®_val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ reg_val = ltq_r32(reg_addr); #endif return reg_val; @@ -288,7 +288,7 @@ static inline void LMAC_RGWR(struct mac_prv_data *pdata, u32 reg, u32 val) #if defined(PC_UTILITY) && PC_UTILITY pcuart_reg_wr(reg_addr, val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ ltq_w32(val, reg_addr); #endif } @@ -307,16 +307,6 @@ static inline void LMAC_RGWR(struct mac_prv_data *pdata, u32 reg, u32 val) LMAC_RGWR(reg, reg_val); \ } while (0) -#define LMAC_GET_BITS(var, prefix, field) \ - GET_N_BITS((var), \ - prefix##_##field##_POS, \ - prefix##_##field##_WIDTH) - -#define LMAC_SET_BITS(var, prefix, field, _val) \ - SET_N_BITS((var), \ - prefix##_##field##_POS, \ - prefix##_##field##_WIDTH, (_val)) - int lmac_set_intf_mode(void *pdev, u32 val) ; int lmac_set_duplex_mode(void *pdev, u32 val); int lmac_set_flowcon_mode(void *pdev, u32 val); @@ -332,7 +322,9 @@ int lmac_set_lpimonitor_mode(void *pdev, u32 val); int lmac_set_pauseframe_samode(void *pdev, u32 val); int lmac_set_pauseframe_addr(void *pdev, u8 *mac_addr); int lmac_set_int(void *pdev, u32 val); +int lmac_set_event_int(void *pdev, u32 evnt, u32 val); +int lmac_get_event_int(void *pdev, u32 evnt); int lmac_get_intf_mode(void *pdev); int lmac_get_duplex_mode(void *pdev); u32 lmac_get_flowcon_mode(void *pdev); @@ -350,6 +342,8 @@ int lmac_get_mac_pstat(void *pdev); int lmac_get_mac_pisr(void *pdev); int lmac_get_pauseframe_addr(void *pdev, u8 *mac_addr); int lmac_get_int_stat(void *pdev); +int lmac_get_int(void *pdev); +int lmac_clear_int(void *pdev, u32 event); void lmac_test_all_reg(void *pdev); void lmac_check_reg(void *pdev, u32 reg, char *name, int idx, diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.c b/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.c index ba75b1310f0128c5964a7c395374936bab9f6c48..ae16ea28be28cb2102ba29078f6f14335bb91e48 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.c @@ -7,19 +7,24 @@ * ******************************************************************************/ -#include "xgmac.h" -#include "gswss_mac_api.h" -#include "lmac_api.h" +#include <xgmac.h> +#include <gswss_mac_api.h> +#include <lmac_api.h> +#include <xgmac_mdio.h> int mac_set_flowctrl(void *pdev, u32 val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); if (val > 4) { - xgmac_printf("mac_config_flowctrl invalid val %d\n", val); + mac_printf("mac_config_flowctrl invalid val %d\n", val); return -1; } +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + lmac_set_flowcon_mode(pdev, val); switch (val) { @@ -66,13 +71,23 @@ int mac_set_flowctrl(void *pdev, u32 val) break; } +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_flowctrl(void *pdev) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 flow_ctrl_tx, flow_ctrl_rx, flow_ctrl; +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + flow_ctrl_tx = gswss_get_flowctrl_tx(pdev); flow_ctrl_rx = gswss_get_flowctrl_rx(pdev); @@ -87,38 +102,78 @@ int mac_get_flowctrl(void *pdev) else if (flow_ctrl_tx == 0 && flow_ctrl_rx == 0) flow_ctrl = 0; /* Auto */ +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return flow_ctrl; } int mac_reset(void *pdev) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + gswss_xgmac_reset(pdev, 1); gswss_set_xgmac_rx_disable(pdev, 1); gswss_set_xgmac_tx_disable(pdev, 1); gswss_lmac_reset(pdev, 1); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_config_loopback(void *pdev, u32 loopback) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + xgmac_set_loopback(pdev, loopback); lmac_set_loopback(pdev, loopback); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_config_ipg(void *pdev, u32 ipg) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + xgmac_set_ipg(pdev, ipg); lmac_set_ipg(pdev, ((96 + (32 * ipg)) / 8)); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_set_duplex(void *pdev, u32 val) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + if (val == GSW_DUPLEX_FULL) /* Full Duplex */ val = MAC_FULL_DPLX; else if (val == GSW_DUPLEX_HALF) /* Half Duplex */ @@ -129,12 +184,21 @@ int mac_set_duplex(void *pdev, u32 val) gswss_set_duplex_mode(pdev, val); lmac_set_duplex_mode(pdev, val); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_duplex(void *pdev) { int val = 0; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif val = gswss_get_duplex_mode(pdev); @@ -145,11 +209,22 @@ int mac_get_duplex(void *pdev) else val = -1; +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return val; } int mac_set_mii_if(void *pdev, u32 mii_mode) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int ret = 0; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + /* Default values for 2.5G is XGMAC_GMII, 1G is LMAC_GMII, */ /* FE is LMAC_MII */ if (mii_mode == GSW_PORT_HW_XGMII) { @@ -163,17 +238,29 @@ int mac_set_mii_if(void *pdev, u32 mii_mode) } else if (mii_mode == 5) { /* For Testing LMAC 1G only */ gswss_set_1g_intf(pdev, LMAC_GMII); } else { - xgmac_printf("Wrong MII Interface\n"); - return -1; + mac_printf("Wrong MII Interface\n"); + ret = -1; + goto err; } - return 0; +err: + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + + return -1; } int mac_get_mii_if(void *pdev) { int mac_speed; u32 intf; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif mac_speed = gswss_get_speed(pdev); @@ -182,20 +269,20 @@ int mac_get_mii_if(void *pdev) if (intf == XGMAC_GMII) { intf = GSW_PORT_HW_GMII; - xgmac_printf("Speed %s got intf XGMAC GMII\n", - (mac_speed == SPEED_10M ? "10M" : "100M")); + mac_printf("Speed %s got intf XGMAC GMII\n", + (mac_speed == SPEED_10M ? "10M" : "100M")); } else { intf = GSW_PORT_HW_MII; - xgmac_printf("Speed %s got intf LMAC MII\n", - (mac_speed == SPEED_10M ? "10M" : "100M")); + mac_printf("Speed %s got intf LMAC MII\n", + (mac_speed == SPEED_10M ? "10M" : "100M")); } } else if (mac_speed == SPEED_1G) { intf = gswss_get_1g_intf(pdev); if (intf == XGMAC_GMII) - xgmac_printf("Speed 1G got intf XGMAC GMII\n"); + mac_printf("Speed 1G got intf XGMAC GMII\n"); else - xgmac_printf("Speed 1G got intf LMAC GMII\n"); + mac_printf("Speed 1G got intf LMAC GMII\n"); intf = GSW_PORT_HW_GMII; } else if (mac_speed == SPEED_2G5) { @@ -203,25 +290,35 @@ int mac_get_mii_if(void *pdev) if (intf == XGMAC_GMII) { intf = GSW_PORT_HW_GMII; - xgmac_printf("Speed 2.5G got intf XGMAC GMII\n"); + mac_printf("Speed 2.5G got intf XGMAC GMII\n"); } else { intf = GSW_PORT_HW_XGMII; - xgmac_printf("Speed 2.5G got intf XGMAC XGMII\n"); + mac_printf("Speed 2.5G got intf XGMAC XGMII\n"); } } else if (mac_speed == SPEED_10G) { intf = GSW_PORT_HW_XGMII; - xgmac_printf("Speed 10G got intf XGMAC XGMII\n"); + mac_printf("Speed 10G got intf XGMAC XGMII\n"); } else if (mac_speed == SPEED_AUTO) { intf = GSW_PORT_HW_XGMII; - xgmac_printf("Speed 10G got intf AUTO\n"); + mac_printf("Speed 10G got intf AUTO\n"); } +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return intf; } int mac_set_speed(void *pdev, u32 phy_speed) { u32 mii_intf; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int ret = 0; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif if (phy_speed == GSW_PORT_SPEED_10) { /* 10 Mbps */ mii_intf = gswss_get_fe_intf(pdev); @@ -256,16 +353,28 @@ int mac_set_speed(void *pdev, u32 phy_speed) } else if (phy_speed == 0) { phy_speed = SPEED_MAC_AUTO; } else { - return -1; + ret = -1; + goto err; } mac_set_physpeed(pdev, phy_speed); - return 0; +err: +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + + return ret; } int mac_set_physpeed(void *pdev, u32 phy_speed) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + xgmac_set_extcfg(pdev, 1); switch (phy_speed) { @@ -330,12 +439,21 @@ int mac_set_physpeed(void *pdev, u32 phy_speed) break; } +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_speed(void *pdev) { int mac_speed; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif mac_speed = gswss_get_speed(pdev); @@ -352,12 +470,22 @@ int mac_get_speed(void *pdev) else if (mac_speed == SPEED_AUTO) mac_speed = 0; - xgmac_printf("Returning Speed = %d\n", mac_speed); + mac_printf("Returning Speed = %d\n", mac_speed); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return mac_speed; } int mac_set_linksts(void *pdev, u8 linksts) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + if (linksts == GSW_PORT_LINK_UP) gswss_set_linkstatus(pdev, 1); else if (linksts == GSW_PORT_LINK_DOWN) @@ -365,12 +493,23 @@ int mac_set_linksts(void *pdev, u8 linksts) else gswss_set_linkstatus(pdev, 0); /* Auto */ +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_linksts(void *pdev) { - int linksts = gswss_get_linkstatus(pdev); + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int linksts; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + + linksts = gswss_get_linkstatus(pdev); if (linksts == 1) linksts = GSW_PORT_LINK_UP; @@ -379,7 +518,12 @@ int mac_get_linksts(void *pdev) else linksts = -1; - xgmac_printf("Returning linksts = %d\n", linksts); + mac_printf("Returning linksts = %d\n", linksts); + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return linksts; } @@ -387,32 +531,59 @@ int mac_set_lpien(void *pdev, u32 enable, u32 lpi_waitg, u32 lpi_waitm) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + + #ifdef CONFIG_SILVER_WORKAROUND #else - xgmac_printf("Configuring LPIEN\n"); + mac_printf("Configuring LPIEN\n"); lmac_set_lpi(pdev, enable, lpi_waitg, lpi_waitm); xgmac_set_eee_mode(pdev, enable); xgmac_set_eee_timer(pdev, pdata->twt, pdata->lst); #endif +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_lpien(void *pdev) { int enable; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif enable = xgmac_get_eee_mode(pdev); - xgmac_printf("Returning lpien = %d\n", enable); + mac_printf("Returning lpien = %d\n", enable); + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif return enable; } int mac_set_mtu(void *pdev, u32 mtu) { - if (mtu > FALCON_MAX_MTU) - return -1; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int ret = 0; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + + if (mtu > FALCON_MAX_MTU) { + ret = -1; + goto err; + } gswss_set_mtu(pdev, mtu); @@ -421,40 +592,79 @@ int mac_set_mtu(void *pdev, u32 mtu) else xgmac_config_std_pkt(pdev); - return 0; +err: +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + + return ret; } int mac_get_mtu(void *pdev) { - return gswss_get_mtu(pdev); + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int mtu = 0; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + + mtu = gswss_get_mtu(pdev); + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + + return mtu; } int mac_set_pfsa(void *pdev, u8 *mac_addr, u32 mode) { - int i = 0; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif lmac_set_pauseframe_samode(pdev, mode); lmac_set_pauseframe_addr(pdev, mac_addr); - // TODO: Need to change this to per port MAC Addr setting in XGMAC - for (i = 0; i < 3; i++) { - /* Program MAC Address */ - xgmac_set_mac_address(&prv_data[i].ops, mac_addr); - } + /* Program MAC Address */ + xgmac_set_mac_address(pdev, mac_addr); + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif return 0; } int mac_get_pfsa(void *pdev, u8 *mac_addr, u32 *mode) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + *mode = lmac_get_pauseframe_samode(pdev); lmac_get_pauseframe_addr(pdev, mac_addr); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_set_fcs_gen(void *pdev, u32 val) { + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + /* CRC Insertion enable, PAD insertion Disable */ if (val == 1) gswss_set_xgmac_crc_ctrl(pdev, 1); @@ -464,52 +674,461 @@ int mac_set_fcs_gen(void *pdev, u32 val) lmac_set_txfcs(pdev, val); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_get_fcs_gen(void *pdev) { - return lmac_get_txfcs(pdev); + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int tx_fcs = 0; + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif + + tx_fcs = lmac_get_txfcs(pdev); + +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + + return tx_fcs; } -/* TTSE: Enables the IEEE 1588 hw ts for Tx Frame - * OSTC: One step ts correction with ref to ts provided in TTSH and TTSL - * OST_AVAIl: It indicates ref ts is available in TTSH and TTSL - * CIC: - * 0: Csum Insertion disabled - * 1: Only IP hdr csum calc and insert enabled - * 2: IP hdr csum, Payload csum calc and insertion enabled, - * pseudo hdr csum is not calc in HW - * 3: IP hdr csum, Payload csum calc and insertion enabled, - * pseudo hdr csum is calc in HW +/*TTSE: Enables the IEEE 1588 hw ts for Tx Frame + *OSTC: One step ts correction with ref to ts provided in TTSH and TTSL + *OST_AVAIl: It indicates ref ts is available in TTSH and TTSL + *CIC: + * 0: Csum Insertion disabled + * 1: Only IP hdr csum calc and insert enabled + * 2: IP hdr csum, Payload csum calc and insertion enabled, + * pseudo hdr csum is not calc in HW + * 3: IP hdr csum, Payload csum calc and insertion enabled, + * pseudo hdr csum is calc in HW */ -int mac_enable_onestep_ts(void *pdev, u32 ttse, u32 ostc, - u32 ostc_avail) +int mac_enable_onestep_ts(void *pdev) { - gswss_set_txtstamp_cic(pdev, ttse, ostc, ostc_avail, 0); + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif gswss_set_mac_rxtime_op(pdev, MODE1); gswss_set_mac_txsptag_op(pdev, MODE3); - /* gswss_set_mac_rxsptag_op(pdev, MODE2); - * gswss_set_mac_txsptag_op(pdev, MODE0); - * gswss_set_mac_rxsptag_op(pdev, MODE0); - * xgmac_init_systime(pdev, 1, 1); - */ +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } int mac_disable_onestep_ts(void *pdev) { - gswss_set_txtstamp_cic(pdev, 0, 0, 0, 0); + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#ifdef __KERNEL__ + spin_lock_bh(&pdata->mac_lock); +#endif gswss_set_mac_rxtime_op(pdev, MODE0); gswss_set_mac_txsptag_op(pdev, MODE0); gswss_set_mac_rxsptag_op(pdev, MODE0); xgmac_disable_tstamp(pdev); +#ifdef __KERNEL__ + spin_unlock_bh(&pdata->mac_lock); +#endif + return 0; } +int mac_get_int_sts(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int val = 0; + u32 mac_isr = XGMAC_RGRD(pdata, MAC_ISR); + u32 mtl_q_isr = XGMAC_RGRD(pdata, MTL_Q_ISR); + u32 lmac_pisr = LMAC_RGRD(pdata, MAC_PISR(pdata->mac_idx)); + + //mac_printf("MAC ISR %x MTL ISR %x LMAC Pisr %x\n", mac_isr, mtl_q_isr, + // lmac_pisr); + + /* XGMAC Mac ISR Status */ + if (mac_isr) { + /* Timestamp interrupt */ + if (MAC_GET_VAL(mac_isr, MAC_ISR, TSIS)) + val |= (1 << XGMAC_TSTAMP_EVNT); + + /* LPI interrupt (EEE) */ + if (MAC_GET_VAL(mac_isr, MAC_ISR, LPIIS)) + val |= (1 << XGMAC_LPI_EVNT); + + /* transmit error status interrupt */ + if (MAC_GET_VAL(mac_isr, MAC_ISR, TXESIS)) + val |= (1 << XGMAC_TXERR_STS_EVNT); + + /* Receive error status interrupt */ + if (MAC_GET_VAL(mac_isr, MAC_ISR, RXESIS)) + val |= (1 << XGMAC_RXERR_STS_EVNT); + + /* Power Management interrupt */ + if (MAC_GET_VAL(mac_isr, MAC_ISR, PMTIS)) + val |= (1 << XGMAC_PMT_EVNT); + } + + /* XGMAC MTL ISR Status */ + if (mtl_q_isr) { + /* Tx Q Overflow Interrupt Enable */ + if (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, TXUNFIS)) + val |= (1 << XGMAC_TXQ_OVFW_EVNT); + + /* Rx Q Overflow Interrupt Enable */ + if (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, ABPSIS)) + val |= (1 << XGMAC_RXQ_OVFW_EVNT); + + /* Average bits per slot interrupt enable */ + if (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, RXOVFIS)) + val |= (1 << XGMAC_AVG_BPS_EVNT); + } + + /* LMAC ISR Status */ + if (lmac_pisr) { + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, PHYERR)) + val |= (1 << LMAC_PHYERR_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, ALIGN)) + val |= (1 << LMAC_ALIGN_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, SPEED)) + val |= (1 << LMAC_SPEED_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, FDUP)) + val |= (1 << LMAC_FDUP_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, RXPAUEN)) + val |= (1 << LMAC_RXPAUEN_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, TXPAUEN)) + val |= (1 << LMAC_TXPAUEN_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, LPIOFF)) + val |= (1 << LMAC_LPIOFF_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, LPION)) + val |= (1 << LMAC_LPION_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, JAM)) + val |= (1 << LMAC_JAM_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, FCSERR)) + val |= (1 << LMAC_FCSERR_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, TXPAUSE)) + val |= (1 << LMAC_TXPAU_EVNT); + + if (MAC_GET_VAL(lmac_pisr, MAC_PISR, RXPAUSE)) + val |= (1 << LMAC_RXPAU_EVNT); + } + + return val; +} + + +int mac_init(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + +#if defined(PC_UTILITY) || defined(CHIPTEST) + xgmac_init_pdata(pdata, -1); +#endif + xgmac_cli_init(); + + mac_printf("XGMAC INIT for Module %d\n", pdata->mac_idx); + + /* Initialize MAC related features */ + + /* Program MAC Address */ + xgmac_set_mac_address(pdev, pdata->mac_addr); + + /* Program for Jumbo/Std settings */ + mac_set_mtu(pdev, pdata->mtu); + + /* TODO: Interrupt enable change to Irq register */ + /* Configure RWK filter frames */ + + populate_filter_frames(pdev); + + xgmac_set_extcfg(pdev, 1); + + /* Program Promisc mode and All multicast mode */ + xgmac_set_promiscuous_mode(pdev, pdata->promisc_mode); + + /* Program All multicast mode */ + xgmac_set_all_multicast_mode(pdev, pdata->all_mcast_mode); + + /* Configure MAC Speed to 10/2.5/1 G */ + mac_set_physpeed(pdev, pdata->phy_speed); + +#ifdef __KERNEL__ + /* Default enable flow control Rx and TX */ + mac_set_flowctrl(pdev, 3); +#endif + /* Set the link status as UP */ + mac_set_linksts(pdev, GSW_PORT_LINK_UP); + + /* Set the Duplex as Full Duplex */ + mac_set_duplex(pdev, GSW_DUPLEX_FULL); + + /* Set LPI TX Automate and LPI Auto Timer Enable to + * overcome packet-drop issue + */ + xgmac_set_mac_lpitx(pdev, 1); + +#if defined(UPTIME) && UPTIME + + if (pdata->mac_idx == 0) + xgmac_set_hwtstamp_settings(pdev, 1, 1); + +#endif + /* POWER ON MAC Tx/Rx */ + xgmac_powerup(pdev); + +#ifdef __KERNEL__ + /* Filter pause frames from XGMAC */ + xgmac_pause_frame_filtering(pdev, 1); +#endif + /* Set XGMAC Port to MDIO Clause 22 */ + mdio_set_clause(pdev, 1, pdata->mac_idx); + +#ifdef __KERNEL__ + xgmac_mdio_register(pdev); +#endif + + return 0; +} + +/* TRCSTS: MTL Tx Queue Read Controller Status + * This field indicates the state of the Tx Queue Read Controller: + * 00 Idle state + * 01 Read state (transferring data to the MAC transmitter) + * 10 Waiting for pending Tx Status from the MAC transmitter + * 11 Flushing the Tx queue because of the Packet Abort request from + * the MAC + * TXQSTS: MTL Tx Queue Not Empty Status + * if 1, it indicates that the MTL Tx Queue is not empty + * and some data is left for transmission. + * PRXQ: Number of Packets in Receive Queue + * This field indicates the current number of packets in the Rx Queue. The + * theoretical maximum value for this field is 256KB/16B = 16K Packets, + * that is, Max_Queue_Size/Min_Packet_Size. + * RXQSTS: MTL Rx Queue Fill-Level Status + * This field gives the status of the fill-level of the Rx Queue: + * 00 Rx Queue empty + * 01 Rx Queue fill-level below flow-control deactivate threshold + * 10 Rx Queue fill-level above flow-control activate threshold + * 11 Rx Queue full + */ +int mac_exit(void *pdev) +{ + u32 mtl_tx_debugq, trcsts, txqsts; + u32 mtl_rx_debugq, prxq, rxqsts; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + mtl_tx_debugq = XGMAC_RGRD(pdata, MTL_Q_TQDG); + trcsts = MAC_GET_VAL(mtl_tx_debugq, MTL_Q_TQDG, TRCSTS); + txqsts = MAC_GET_VAL(mtl_tx_debugq, MTL_Q_TQDG, TXQSTS); + + if ((trcsts != 1) && (txqsts == 0)) { + mac_printf("XGMAC EXIT for Module %d\n", pdata->mac_idx); + /* POWER OFF MAC Tx/Rx */ + xgmac_powerdown(pdev); + } else + mac_printf("Can't Exit XGMAC %d now,data is left for txing\n", + pdata->mac_idx); + + mtl_rx_debugq = XGMAC_RGRD(pdata, MTL_Q_RQDG); + prxq = MAC_GET_VAL(mtl_tx_debugq, MTL_Q_RQDG, PRXQ); + rxqsts = MAC_GET_VAL(mtl_tx_debugq, MTL_Q_RQDG, RXQSTS); + + if ((prxq == 0) && (rxqsts == 0)) + mac_printf("All Data is transferred to system memory\n"); + else + mac_printf("ERROR: Data is still txing to system memory\n"); + +#ifdef __KERNEL__ + xgmac_mdio_unregister(pdev); +#endif + + return 0; +} + + +int mac_int_enable(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + struct adap_ops *adap_ops = gsw_get_adap_ops(0); + + /* Enable LMAC 2/3/4 Interrupt */ + lmac_set_int(pdev, 1); + /* Enable XGMAC 2/3/4 Interrupt */ + gswss_set_interrupt(adap_ops, XGMAC, pdata->mac_idx, 1); + + return 0; +} + + +int mac_int_disable(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + struct adap_ops *adap_ops = gsw_get_adap_ops(0); + + /* Enable LMAC 2/3/4 Interrupt */ + lmac_set_int(pdev, 0); + /* Enable XGMAC 2/3/4 Interrupt */ + gswss_set_interrupt(adap_ops, XGMAC, pdata->mac_idx, 0); + + return 0; +} + +int mac_irq_event_enable(void *pdev, GSW_Irq_Op_t *irq) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + /* Enable LMAC and XGMAC Interrupt */ + mac_int_enable(pdev); + + if (irq->blk == LMAC_BLK) { + mac_printf("LMAC %d: mac_irq_enable Event %x\n", + pdata->mac_idx, irq->event); + /* Enable LMAC Event Interrupt */ + lmac_set_event_int(pdev, irq->event, 1); + } else if (irq->blk == XGMAC_BLK) { + mac_printf("XGMAC %d: mac_irq_enable Event %x\n", + pdata->mac_idx, irq->event); + /* Enable XGMAC Event Interrupt */ + xgmac_set_mac_int(pdev, irq->event, 1); + } else { + mac_printf("Unsupported MAC Block %d\n", irq->blk); + return GSW_statusErr; + } + + return 0; +} + +int mac_irq_event_disable(void *pdev, GSW_Irq_Op_t *irq) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + if (irq->blk == LMAC_BLK) { + mac_printf("LMAC %d: mac_irq_disable Event %x\n", + pdata->mac_idx, irq->event); + /* Disable LMAC Event Interrupt */ + lmac_set_event_int(pdev, irq->event, 0); + } else if (irq->blk == XGMAC_BLK) { + mac_printf("XGMAC %d: mac_irq_disable Event %x\n", + pdata->mac_idx, irq->event); + /* Disable XGMAC Event Interrupt */ + xgmac_set_mac_int(pdev, irq->event, 0); + } else { + mac_printf("Unsupported MAC Block %d\n", irq->blk); + return GSW_statusErr; + } + + return 0; +} + +int mac_irq_register(void *pdev, GSW_Irq_Op_t *irq) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + if (irq->event >= MAX_IRQ_EVNT) { + mac_printf("Wrong Irq event\n"); + return -1; + } + + mac_printf("MAC %d: mac_irq_register Event %x\n", + pdata->mac_idx, irq->event); + + pdata->irq_hdl[irq->event].cb = irq->call_back; + pdata->irq_hdl[irq->event].param = irq->param; + + return 0; +} + +int mac_irq_unregister(void *pdev, GSW_Irq_Op_t *irq) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + if (irq->event >= MAX_IRQ_EVNT) { + mac_printf("Wrong Irq event\n"); + return -1; + } + + mac_printf("MAC %d: mac_irq_unregister Event %x\n", + pdata->mac_idx, irq->event); + + pdata->irq_hdl[irq->event].cb = NULL; + pdata->irq_hdl[irq->event].param = NULL; + + return 0; +} + +int mac_irq_clr(void *pdev, u32 event) +{ + switch (event) { + case XGMAC_PMT_EVNT: + xgmac_pmt_int_clr(pdev); + break; + + case XGMAC_TSTAMP_EVNT: +#ifdef __KERNEL__ + xgmac_ptp_isr_hdlr(pdev); +#endif + break; + + case XGMAC_LPI_EVNT: + xgmac_lpi_int_clr(pdev); + break; + + /* These 2 interrupts are cleared by a read RXESIS or TXESIS + Which will be done while reading Interrupt Status */ + case XGMAC_TXERR_STS_EVNT: + case XGMAC_RXERR_STS_EVNT: + break; + + case XGMAC_TXQ_OVFW_EVNT: + case XGMAC_RXQ_OVFW_EVNT: + case XGMAC_AVG_BPS_EVNT: + xgmac_clear_mtl_int(pdev, event); + break; + + case LMAC_PHYERR_EVNT: + case LMAC_ALIGN_EVNT: + case LMAC_SPEED_EVNT: + case LMAC_FDUP_EVNT: + case LMAC_RXPAUEN_EVNT: + case LMAC_TXPAUEN_EVNT: + case LMAC_LPIOFF_EVNT: + case LMAC_LPION_EVNT: + case LMAC_JAM_EVNT: + case LMAC_FCSERR_EVNT: + case LMAC_TXPAU_EVNT: + case LMAC_RXPAU_EVNT: + lmac_clear_int(pdev, event); + break; + + default: + break; + } + + return 0; +} void mac_init_fn_ptrs(struct mac_ops *mac_op) { mac_op->set_flow_ctl = mac_set_flowctrl; @@ -544,6 +1163,9 @@ void mac_init_fn_ptrs(struct mac_ops *mac_op) mac_op->set_fcsgen = mac_set_fcs_gen; mac_op->get_fcsgen = mac_get_fcs_gen; + mac_op->get_int_sts = mac_get_int_sts; + mac_op->clr_int_sts = mac_irq_clr; + mac_op->init_systime = xgmac_init_systime; mac_op->config_addend = xgmac_set_tstamp_addend; mac_op->adjust_systime = xgmac_adjust_systime; @@ -551,9 +1173,10 @@ void mac_init_fn_ptrs(struct mac_ops *mac_op) mac_op->get_tx_tstamp = xgmac_get_tx_tstamp; mac_op->config_hw_time_stamping = xgmac_set_hwtstamp_settings; mac_op->config_subsec_inc = xgmac_config_subsec_inc; + mac_op->get_txtstamp_cap_cnt = xgmac_get_txtstamp_cnt; - mac_op->init = xgmac_init; - mac_op->exit = xgmac_exit; + mac_op->init = mac_init; + mac_op->exit = mac_exit; mac_op->xgmac_cli = xgmac_main; mac_op->lmac_cli = lmac_main; mac_op->xgmac_reg_rd = xgmac_rd_reg; @@ -561,5 +1184,14 @@ void mac_init_fn_ptrs(struct mac_ops *mac_op) mac_op->lmac_reg_rd = lmac_rd_reg; mac_op->lmac_reg_wr = lmac_wr_reg; + + mac_op->mac_int_en = mac_int_enable; + mac_op->mac_int_dis = mac_int_disable; + + mac_op->IRQ_Disable = mac_irq_event_disable; + mac_op->IRQ_Enable = mac_irq_event_enable; + mac_op->IRQ_Register = mac_irq_register; + mac_op->IRQ_UnRegister = mac_irq_unregister; + } diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.h b/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.h index f7cac64d1bf377eba6bd7f47f535f6ac938a138a..46d25a0a7f0b363a5025c7debbd29f3bfcd10446 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/mac_cfg.h @@ -10,7 +10,7 @@ #ifndef _MAC_CFG_ #define _MAC_CFG_ -#include "xgmac_common.h" +#include <xgmac_common.h> /* MAC Interface API's */ int mac_config_loopback(void *pdev, u32 loopback); @@ -34,6 +34,10 @@ int mac_get_pfsa(void *pdev, u8 *mac_addr, u32 *mode); int mac_reset(void *pdev); +int mac_init(void *pdev); +int mac_exit(void *pdev); + + int mac_set_flowctrl(void *pdev, u32 val); int mac_get_flowctrl(void *pdev); @@ -46,8 +50,16 @@ int mac_get_linksts(void *pdev); int mac_set_fcs_gen(void *pdev, u32 val); int mac_get_fcs_gen(void *pdev); -int mac_enable_onestep_ts(void *pdev, u32 ttse, u32 ostc, u32 ostc_avail); +int mac_enable_onestep_ts(void *pdev); int mac_disable_onestep_ts(void *pdev); +int mac_irq_enable(void *pdev, GSW_Irq_Op_t *irq); +int mac_irq_disable(void *pdev, GSW_Irq_Op_t *irq); +int mac_irq_register(void *pdev, GSW_Irq_Op_t *irq); +int mac_irq_unregister(void *pdev, GSW_Irq_Op_t *irq); + +int mac_int_enable(void *pdev); +int mac_int_disable(void *pdev); + #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.c b/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.c index 2489373313b0333e43b9f103f95ce79a83455f99..ab79a5e2fc0246761f914040c2549d26e9ef8050 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.c @@ -10,65 +10,126 @@ #include <lantiq_soc.h> #include <net/switch_api/gsw_dev.h> #include <net/switch_api/adap_ops.h> -#include "gswss_api.h" -#include "xgmac_common.h" +#include <gswss_api.h> +#include <xgmac_common.h> +#include <xgmac.h> +#include <lmac_api.h> -static void __iomem *g_adap_base; -static void __iomem *g_lmac_base; +static void __iomem *base[2]; -void debug_print(struct platform_device *pdev) +static irqreturn_t mac_isr(int irq, void *dev_id) { - struct gswss *gswdev = dev_get_drvdata(pdev->dev.parent); - struct adap_prv_data *adap_pdata = GET_ADAP_PDATA(gswdev->adap_ops); - struct mac_prv_data *mac_pdata = - GET_MAC_PDATA(platform_get_drvdata(pdev)); - int i = 0; - struct resource *res[2]; + u32 devid = 0; + struct adap_ops *adap_ops = gsw_get_adap_ops(devid); + struct mac_ops *mac_ops; + struct mac_prv_data *pdata; + int i = 0, mac_int_sts = 0, lmac_int_sts = 0; + u32 max_mac = gsw_get_mac_subifcnt(devid); + int task_sched = 0; - pr_info("LOCAL Driver\n"); + /* Handle all the MAC Interrupts */ + for (i = 0; i < max_mac; i++) { - pr_info("ADAP ops Ptr %p\n", gswdev->adap_ops); - pr_info("ADAP pdata %p\n", adap_pdata); - pr_info("MAC ops Ptr %p\n", platform_get_drvdata(pdev)); - pr_info("Core Dev %p\n", gsw_get_coredev(0)); - pr_info("Mac Pdev Global %p\n", gswdev->mac_dev[pdev->id]); - pr_info("Mac Pdev Local %p\n", pdev); - pr_info("Mac Index %x\n", mac_pdata->mac_idx); + task_sched = 0; - pr_info("::::: MAC Platform driver probe :::::: pdev %p drv_data %p\n", - pdev, mac_pdata); + mac_int_sts = gswss_get_int_stat(adap_ops, XGMAC); - pr_info("pdata %p\n", mac_pdata); - pr_info("Got Index %x\n", mac_pdata->mac_idx); - pr_info("Number of resources %d\n", pdev->num_resources); + mac_ops = gsw_get_mac_ops(devid, i); + pdata = GET_MAC_PDATA(mac_ops); - pr_info("adap_base %p\n", g_adap_base); - pr_info("lmac_base %p\n", g_lmac_base); + /* Check XGMAC i Interrupts */ + if (mac_int_sts & (1 << (GSWIPSS_IER0_XGMAC2_POS + i))) { - pr_info("mac addr %02x:%02x:%02x:%02x:%02x:%02x\n", - mac_pdata->mac_addr[0], - mac_pdata->mac_addr[1], - mac_pdata->mac_addr[2], - mac_pdata->mac_addr[3], - mac_pdata->mac_addr[4], - mac_pdata->mac_addr[5]); - pr_info("speed_set %d\n", mac_pdata->phy_speed); - pr_info("phy_mode [%s]\n", mac_pdata->phy_mode); + /* Disable the XGMAC 2/3/4 Interrupt First */ + gswss_set_interrupt(adap_ops, XGMAC, + pdata->mac_idx, 0); - for (i = 0; i < pdev->num_resources; i++) { - res[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); - pr_info("Resource.start %x Resource.end %x\n", - res[i]->start, res[i]->end); + task_sched = 1; + } + + lmac_int_sts = lmac_get_int(mac_ops); + + /* Check LMAC i Interrupts */ + if (lmac_int_sts & (1 << (LMAC_ISR_MAC2_POS + i))) { + + /* Disable the LMAC 2/3/4 Interrupt First */ + lmac_set_int(mac_ops, 0); + + task_sched = 1; + } + + /* Schedule tasklet for this MAC */ + if (task_sched) + tasklet_schedule(&pdata->mac_tasklet); } - pr_info("EXPORT API's\n"); - pr_info("ADAP ops Ptr %p\n", gsw_get_adap_ops(0)); - pr_info("MAC ops Ptr %p\n", gsw_get_mac_ops(0, pdev->id)); - pr_info("Core Dev %p\n", gsw_get_coredev(0)); - pr_info("Mac Dev %p\n", gsw_get_macdev(0, pdev->id)); - pr_info("Mac Subif Count %x\n", gsw_get_mac_subifcnt(0)); - pr_info("Total Gsw devs %x\n", gsw_get_total_devs(0)); + return IRQ_HANDLED; +} + +static void mac_irq_tasklet(unsigned long data) +{ + int evnt = 0, j = 0; + void *param; + struct mac_prv_data *pdata = (struct mac_prv_data *)data; + struct mac_ops *ops = &pdata->ops; + + /* Get all events available for this idx XGMAC and LMAC events */ + evnt = ops->get_int_sts(ops); + + if (evnt) { + /* Check all events for this MAC */ + for (j = 0; j < MAX_IRQ_EVNT; j++) { + if (evnt & (1 << j)) { + + /* Clear the MAC Interrupt status */ + ops->clr_int_sts(ops, j); + + /* If callback is registered, return callback */ + if (pdata->irq_hdl[j].cb) { + param = pdata->irq_hdl[j].param; + /* Call the Upper level callback */ + pdata->irq_hdl[j].cb(param); + } + } + } + + + /* Enable Corresponding XGMAC and LMAC Interrupts back */ + ops->mac_int_en(ops); + } + + + return; +} + +static int mac_irq_init(struct mac_prv_data *pdata) +{ + int ret = 0; + + pdata->irq_hdl = kzalloc(sizeof(struct mac_irq_hdl) * (MAX_IRQ_EVNT - 1), + GFP_KERNEL); + + if (!pdata->irq_hdl) { + mac_printf("IRQ handler alloc error\n"); + return -1; + } + + if (pdata->mac_idx == 0) { + + ret = request_irq(pdata->irq_num, mac_isr, 0, "gsw_mac", NULL); + + if (ret) { + mac_printf("request_irq Error for MAC - %d", ret); + return ret; + } + } + + tasklet_init(&pdata->mac_tasklet, + mac_irq_tasklet, + (unsigned long)pdata); + + return ret; } static int mac_probe(struct platform_device *pdev) @@ -77,13 +138,13 @@ static int mac_probe(struct platform_device *pdev) struct resource *res[2]; struct gswss *gswdev = dev_get_drvdata(pdev->dev.parent); struct adap_prv_data *adap_pdata = GET_ADAP_PDATA(gswdev->adap_ops); - struct mac_prv_data *mac_pdata = + struct mac_prv_data *pdata = GET_MAC_PDATA(platform_get_drvdata(pdev)); gswdev->mac_dev[pdev->id] = pdev; /* Initialize MAC Spin lock */ - spin_lock_init(&mac_pdata->mac_lock); + spin_lock_init(&pdata->mac_lock); /* load the memory ranges */ for (i = 0; i < pdev->num_resources; i++) { @@ -93,31 +154,30 @@ static int mac_probe(struct platform_device *pdev) pr_info("failed to get resources %d\n", i); return -1; } - } - - if (g_adap_base == 0) { - g_adap_base = devm_ioremap_resource(&pdev->dev, res[0]); - - /* Init Adaption layer base address */ - adap_pdata->ss_addr_base = (u32)g_adap_base; - g_lmac_base = devm_ioremap_resource(&pdev->dev, res[1]); + if (pdata->mac_idx == 0) + base[i] = devm_ioremap_resource(&pdev->dev, res[i]); } /* Update Adaption layer pointer and Lmac base address per Mac private * data.This is needed since all MAC api's have Private data as argument */ - mac_pdata->ss_addr_base = (u32)g_adap_base; - mac_pdata->lmac_addr_base = (u32)g_lmac_base; + pdata->ss_addr_base = (u32)base[0]; + adap_pdata->ss_addr_base = (u32)base[0]; + pdata->lmac_addr_base = (u32)base[1]; + + pdata->max_mac = gsw_get_mac_subifcnt(0); /* Init function fointers */ - mac_init_fn_ptrs(&mac_pdata->ops); + mac_init_fn_ptrs(&pdata->ops); + + /* Request IRQ for MAC */ + mac_irq_init(pdata); - //debug_print(pdev); + pr_info("XGMAC INIT %d Started\n", pdata->mac_idx); + pdata->ops.init(&pdata->ops); + pr_info("XGMAC INIT %d completed\n\n", pdata->mac_idx); - pr_info("XGMAC INIT %d Started\n", mac_pdata->mac_idx); - mac_pdata->ops.init(&mac_pdata->ops); - pr_info("XGMAC INIT %d completed\n", mac_pdata->mac_idx); return 0; } diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.h b/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.h deleted file mode 100644 index f96491757f38ef7bc01c91977913f19044bfc2f8..0000000000000000000000000000000000000000 --- a/drivers/net/ethernet/lantiq/switch-api/mac/mac_drv.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _MAC_DRV_H -#define _MAC_DRV_H - -#include "xgmac_common.h" - -extern u32 mac_reg_read(struct mac_prv_data *pdata, u32 reg); -extern int mac_reg_write(struct mac_prv_data *pdata, u32 reg, u8 val); -extern int mac_set_bits(struct mac_prv_data *pdata, u32 reg, u8 mask); -extern int mac_clear_bits(struct mac_prv_data *pdata, u32 reg, u8 mask); - -#endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac.h b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac.h index 866fd8b1d6cc5b93ee390270293083fd58db02b3..4e4987c208a6cd9a0c45574fe1738a19a85c691c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac.h @@ -42,9 +42,9 @@ #ifndef __XGMAC_H__ #define __XGMAC_H__ -#include "xgmac_common.h" -#include "xgmac_cli.h" -#include "mac_cfg.h" +#include <xgmac_common.h> +#include <xgmac_cli.h> +#include <mac_cfg.h> #define XGMAC_MIN_PACKET 60 #define XGMAC_STD_PACKET_MTU 1500 @@ -110,6 +110,7 @@ #define MAC_TSTAMP_STSR 0x0d20 #define MAC_TXTSTAMP_NSECR 0x0d30 #define MAC_TXTSTAMP_SECR 0x0d34 +#define MAC_TXTSTAMP_STS 0x0d38 /* MTL register offsets */ #define MTL_OMR 0x1000 @@ -129,6 +130,8 @@ #define MTL_Q_IER 0x1170 #define MTL_Q_ISR 0x1174 + + #define MAC_LPS_TLPIEN 0x00000001 #define MAC_LPS_TLPIEX 0x00000002 #define MAC_LPS_RLPIEN 0x00000004 @@ -142,6 +145,8 @@ #define XGMAC_CTRL_REG_BAS_POS 15 #define XGMAC_CTRL_REG_BAS_WIDTH 1 + + /* MAC register entry bit positions and sizes */ #define MAC_HW_F0_ADDMACADRSEL_POS 18 #define MAC_HW_F0_ADDMACADRSEL_WIDTH 5 @@ -257,6 +262,14 @@ #define MAC_ISR_LS_POS 24 #define MAC_ISR_LS_WIDTH 2 +#define MAC_LPI_CSR_TLPIEN_POS 0 +#define MAC_LPI_CSR_TLPIEN_WIDTH 1 +#define MAC_LPI_CSR_TLPIEX_POS 1 +#define MAC_LPI_CSR_TLPIEX_WIDTH 1 +#define MAC_LPI_CSR_RLPIEN_POS 2 +#define MAC_LPI_CSR_RLPIEN_WIDTH 1 +#define MAC_LPI_CSR_RLPIEX_POS 3 +#define MAC_LPI_CSR_RLPIEX_WIDTH 1 #define MAC_LPI_CSR_LPITXEN_POS 16 #define MAC_LPI_CSR_LPITXEN_WIDTH 1 #define MAC_LPI_CSR_LPIATE_POS 20 @@ -265,6 +278,7 @@ #define MAC_LPI_CSR_LPITXA_WIDTH 1 #define MAC_LPI_CSR_PLS_POS 17 #define MAC_LPI_CSR_PLS_WIDTH 1 + #define MAC_LPI_TCR_LST_POS 16 #define MAC_LPI_TCR_LST_WIDTH 10 #define MAC_LPI_TCR_TWT_POS 0 @@ -411,6 +425,8 @@ #define MAC_TSTAMP_STSR_ATSSTN_WIDTH 4 #define MAC_TSTAMP_STSR_TXTSC_POS 15 #define MAC_TSTAMP_STSR_TXTSC_WIDTH 1 +#define MAC_TSTAMP_STSR_TTSNS_POS 10 +#define MAC_TSTAMP_STSR_TTSNS_WIDTH 5 #define MAC_TSTAMP_STSR_TSTRGTERR3_POS 9 #define MAC_TSTAMP_STSR_TSTRGTERR3_WIDTH 1 #define MAC_TSTAMP_STSR_TSTARGT3_POS 8 @@ -435,6 +451,9 @@ #define MAC_TXTSTAMP_NSECR_TXTSSTSMIS_POS 31 #define MAC_TXTSTAMP_NSECR_TXTSSTSMIS_WIDTH 1 +#define MAC_TXTSTAMP_STS_PKTID_POS 0 +#define MAC_TXTSTAMP_STS_PKTID_WIDTH 10 + #define MAC_VR_SNPSVER_POS 0 #define MAC_VR_SNPSVER_WIDTH 8 @@ -649,24 +668,24 @@ enum { }; struct _vlan_tag { - u32 vlan_tag2:16; - u32 vlan_tag1:16; + u32 vlan_tag2: 16; + u32 vlan_tag1: 16; }; struct _pkt_len_ctrl { - u32 vxn:1; - u32 svtv:1; - u32 vtv:1; - u32 vtir:2; - u32 saic:3; - u32 ivtir:2; - u32 cic_ost_avail:2; - u32 ostc:1; - u32 ttse:1; - u32 cpc:2; - u32 ost_avail:1; - u32 res:11; - u32 pl:5; + u32 vxn: 1; + u32 svtv: 1; + u32 vtv: 1; + u32 vtir: 2; + u32 saic: 3; + u32 ivtir: 2; + u32 cic_ost_avail: 2; + u32 ostc: 1; + u32 ttse: 1; + u32 cpc: 2; + u32 ost_avail: 1; + u32 res: 11; + u32 pl: 5; }; struct ctrl_word0 { @@ -691,19 +710,55 @@ enum { XGMAC_SPEEDS, }; -#define XGMAC_GET_BITS(var, reg, field) \ - GET_N_BITS((var), \ - reg##_##field##_POS, \ - reg##_##field##_WIDTH) - -#define XGMAC_SET_BITS(var, reg, field, val) \ - SET_N_BITS((var), \ - reg##_##field##_POS, \ - reg##_##field##_WIDTH, (val)) - #define MASK(reg, field) (1 << reg##_##field##_POS) #define MASK_N_BITS(reg, field) ((1 << (reg##_##field##_WIDTH)) - 1) + + +#ifdef __KERNEL__ +static inline u32 XGMAC_IO_R32(struct mac_prv_data *pdata, u16 reg) +{ + u32 reg_val; + volatile void *xgmac_ctrl_reg = + (volatile void *)(pdata->ss_addr_base + pdata->xgmac_ctrl_reg); + volatile void *xgmac_data0_reg = + (volatile void *)pdata->ss_addr_base + pdata->xgmac_data0_reg; + volatile void *xgmac_data1_reg = + (volatile void *)pdata->ss_addr_base + pdata->xgmac_data1_reg; + + ltq_w32((0x8000 | reg), xgmac_ctrl_reg); + + while (1) { + if ((ltq_r32(xgmac_ctrl_reg) & 0x8000) == 0) + break; + } + + reg_val = ((ltq_r32(xgmac_data1_reg) << 16) | + (ltq_r32(xgmac_data0_reg))); + + return reg_val; +} + +static inline void XGMAC_IO_W32(struct mac_prv_data *pdata, u16 reg, + u32 val) +{ + volatile void *xgmac_ctrl_reg = + (volatile void *)(pdata->ss_addr_base + pdata->xgmac_ctrl_reg); + volatile void *xgmac_data0_reg = + (volatile void *)(pdata->ss_addr_base + pdata->xgmac_data0_reg); + volatile void *xgmac_data1_reg = + (volatile void *)(pdata->ss_addr_base + pdata->xgmac_data1_reg); + + ltq_w32(((val & 0xFFFF0000) >> 16), xgmac_data1_reg); + ltq_w32((val & 0x0000FFFF), xgmac_data0_reg); + ltq_w32((0xC000 | reg), xgmac_ctrl_reg); + + while (1) { + if ((ltq_r32(xgmac_ctrl_reg) & 0x8000) == 0) + break; + } +} +#else static inline u32 XGMAC_R32(struct mac_prv_data *pdata, u16 reg) { u32 reg_val; @@ -785,50 +840,6 @@ static inline void XGMAC_URT_W32(struct mac_prv_data *pdata, u16 reg, } #endif - -#if defined(KERNEL_MODE) && KERNEL_MODE -static inline u32 XGMAC_IO_R32(struct mac_prv_data *pdata, u16 reg) -{ - u32 reg_val; - volatile void *xgmac_ctrl_reg = - (volatile void *)(pdata->ss_addr_base + pdata->xgmac_ctrl_reg); - volatile void *xgmac_data0_reg = - (volatile void *)pdata->ss_addr_base + pdata->xgmac_data0_reg; - volatile void *xgmac_data1_reg = - (volatile void *)pdata->ss_addr_base + pdata->xgmac_data1_reg; - - ltq_w32((0x8000 | reg), xgmac_ctrl_reg); - - while (1) { - if ((ltq_r32(xgmac_ctrl_reg) & 0x8000) == 0) - break; - } - - reg_val = ((ltq_r32(xgmac_data1_reg) << 16) | - (ltq_r32(xgmac_data0_reg))); - - return reg_val; -} - -static inline void XGMAC_IO_W32(struct mac_prv_data *pdata, u16 reg, - u32 val) -{ - volatile void *xgmac_ctrl_reg = - (volatile void *)(pdata->ss_addr_base + pdata->xgmac_ctrl_reg); - volatile void *xgmac_data0_reg = - (volatile void *)(pdata->ss_addr_base + pdata->xgmac_data0_reg); - volatile void *xgmac_data1_reg = - (volatile void *)(pdata->ss_addr_base + pdata->xgmac_data1_reg); - - ltq_w32(((val & 0xFFFF0000) >> 16), xgmac_data1_reg); - ltq_w32((val & 0x0000FFFF), xgmac_data0_reg); - ltq_w32((0xC000 | reg), xgmac_ctrl_reg); - - while (1) { - if ((ltq_r32(xgmac_ctrl_reg) & 0x8000) == 0) - break; - } -} #endif static inline u32 XGMAC_RGRD(struct mac_prv_data *pdata, u16 reg) @@ -840,7 +851,7 @@ static inline u32 XGMAC_RGRD(struct mac_prv_data *pdata, u16 reg) #if defined(CHIPTEST) && CHIPTEST reg_val = XGMAC_R32(pdata, reg); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ reg_val = XGMAC_IO_R32(pdata, reg); #endif @@ -855,7 +866,7 @@ static inline void XGMAC_RGWR(struct mac_prv_data *pdata, u16 reg, u32 val) #if defined(CHIPTEST) && CHIPTEST XGMAC_W32(pdata, reg, val); #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ XGMAC_IO_W32(pdata, reg, val); #endif } @@ -881,7 +892,7 @@ int xgmac_set_mtl_rx_mode(void *pdev, u32 rx_mode); int xgmac_set_mtl_rx_thresh(void *pdev, u32 rx_thresh); int xgmac_set_mtl_tx_mode(void *pdev, u32 tx_mode); int xgmac_set_mtl_tx_thresh(void *pdev, u32 tx_thresh); -int xgmac_clear_mtl_int(void *pdev); +int xgmac_clear_mtl_int(void *pdev, u32 event); int xgmac_set_mtl_int(void *pdev, u32 val); int xgmac_flush_tx_queues(void *pdev); int xgmac_set_flow_control_threshold(void *pdev, @@ -911,7 +922,7 @@ int xgmac_enable_tx_flow_ctl(void *pdev, u32 pause_time); int xgmac_enable_rx_flow_ctl(void *pdev); int xgmac_initiate_pause_tx(void *pdev); int xgmac_clear_mac_int(void *pdev); -int xgmac_set_mac_int(void *pdev, u32 val); +int xgmac_set_mac_int(void *pdev, u32 event, u32 val); int xgmac_set_gmii_speed(void *pdev); int xgmac_set_gmii_2500_speed(void *pdev); int xgmac_set_xgmii_2500_speed(void *pdev); @@ -936,9 +947,10 @@ int xgmac_config_std_pkt(void *pdev); int xgmac_powerup(void *pdev); int xgmac_powerdown(void *pdev); int xgmac_config_subsec_inc(void *pdev, u32 ptp_clk); -void xgmac_onestep_ptp_txtstamp_mode(void *pdev, - u32 snaptypesel, u32 tsmstrena, - u32 tsevntena); +void xgmac_ptp_txtstamp_mode(void *pdev, + u32 snaptypesel, + u32 tsmstrena, + u32 tsevntena); int xgmac_set_eee_mode(void *pdev, u32 val); int xgmac_set_eee_pls(void *pdev, u32 val); @@ -956,12 +968,11 @@ int xgmac_set_pmt_gucast(void *pdev, u32 val); int xgmac_set_ptp_offload(void *pdev, u32 type, u32 val); int xgmac_set_ptp_offload_msg_gen(void *pdev, u32 mode); int xgmac_set_mac_lpitx(void *pdev, u32 val); -int xgmac_init(void *pdev); int xgmac_pause_frame_filtering(void *pdev, u32 val); /* GET API's */ int xgmac_get_all_hw_features(void *pdev); -int xgmac_get_eee_status(void *pdev); +int xgmac_dbg_eee_status(void *pdev); int xgmac_get_priv_data(void *pdev); int xgmac_get_stats(void *pdev); int xgmac_get_tx_cfg(void *pdev); @@ -990,7 +1001,11 @@ u64 xgmac_get_tx_tstamp(void *pdev); int xgmac_get_stats_all(void *pdev); int xgmac_get_fup_fep_setting(void *pdev); int xgmac_get_int_sts(void *pdev); +int xgmac_dbg_int_sts(void *pdev); int xgmac_get_ipg(void *pdev); +int xgmac_get_txtstamp_cnt(void *pdev); +int xgmac_get_txtstamp_pktid(void *pdev); + #if defined(CHIPTEST) && CHIPTEST u32 xgmac_mmc_read(void *pdev, u32 reg_lo); @@ -998,7 +1013,7 @@ u32 xgmac_mmc_read(void *pdev, u32 reg_lo); u64 xgmac_mmc_read(void *pdev, u32 reg_lo); #endif int xgmac_get_mtl_int_sts(void *pdev); -int xgmac_get_pmt(void *pdev); +int xgmac_dbg_pmt(void *pdev); int xgmac_get_debug_sts(void *pdev); int xgmac_get_debug_data(void *pdev, u32 *dbg_data); int xgmac_get_extcfg(void *pdev); @@ -1012,4 +1027,8 @@ u32 xgmac_get_eee_mode(void *pdev); int xgmac_get_txtstamp_mode(void *pdev); int xgmac_print_system_time(void *pdev); +int xgmac_pmt_int_clr(void *pdev); +int xgmac_lpi_int_clr(void *pdev); +int xgmac_ptp_isr_hdlr(void *pdev); + #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.c index 71ad76e8265e24e45f4d481399ebc381c4dd8ad3..30ca05977f9fb73b113bd1869960a965d97427ea 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.c @@ -39,10 +39,11 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" -#include "gswss_mac_api.h" -#include "lmac_api.h" -#include "xgmac_mdio.h" + +#include <xgmac.h> +#include <gswss_mac_api.h> +#include <lmac_api.h> +#include <xgmac_mdio.h> void cli_set_mtl_tx(void *pdev) { @@ -51,7 +52,7 @@ void cli_set_mtl_tx(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_mtl_tx_mode(ops, pdata->tx_sf_mode); xgmac_set_mtl_tx_thresh(ops, @@ -70,7 +71,7 @@ void cli_set_mtl_rx(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_mtl_rx_mode(ops, pdata->rx_sf_mode); xgmac_set_mtl_rx_thresh(ops, @@ -89,7 +90,7 @@ void cli_flow_ctrl_thresh(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_flow_control_threshold(ops, pdata->rfa, @@ -107,7 +108,7 @@ void cli_set_tstamp_addend(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_tstamp_addend(ops, pdata->tstamp_addend); @@ -124,14 +125,12 @@ void cli_set_tstamp_enable(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); - mac_enable_onestep_ts(ops, pdata->ttse, - pdata->ostc, pdata->ostc_avail); + mac_enable_onestep_ts(ops); } } else { - mac_enable_onestep_ts(pdev, pdata->ttse, pdata->ostc, - pdata->ostc_avail); + mac_enable_onestep_ts(pdev); } } @@ -142,7 +141,7 @@ void cli_set_tstamp_disable(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_disable_onestep_ts(ops); } @@ -158,7 +157,7 @@ void cli_set_hwtstamp_settings(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_hwtstamp_settings(ops, pdata->tstamp_config.tx_type, @@ -178,7 +177,7 @@ void cli_flush_tx_queues(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_flush_tx_queues(ops); } @@ -194,7 +193,7 @@ void cli_set_debug_ctl(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_debug_ctl(ops, pdata->dbg_en, pdata->dbg_mode); @@ -211,7 +210,7 @@ void cli_set_tx_debug_data(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_tx_debug_data(ops, pdata->dbg_pktstate); } @@ -227,7 +226,7 @@ void cli_set_rx_debug_data(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_rx_debug_data(ops, &pdata->dbg_pktstate, @@ -246,7 +245,7 @@ void cli_set_debug_data(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_rx_debug_data(ops, &pdata->dbg_pktstate, @@ -264,7 +263,7 @@ void cli_set_rx_debugctrl_int(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_rx_debugctrl_int(ops, pdata->dbg_pktie); @@ -281,7 +280,7 @@ void cli_set_fifo_reset(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_fifo_reset(ops, pdata->dbg_rst_sel, @@ -300,7 +299,7 @@ void cli_set_fup_fep_pkt(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_forward_fup_fep_pkt(ops, pdata->fup, pdata->fef); @@ -317,13 +316,13 @@ void cli_set_int(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); - xgmac_set_mac_int(ops, pdata->enable_mac_int); + xgmac_set_mac_int(ops, pdata->enable_mac_int, 1); xgmac_set_mtl_int(ops, pdata->enable_mtl_int); } } else { - xgmac_set_mac_int(pdev, pdata->enable_mac_int); + xgmac_set_mac_int(pdev, pdata->enable_mac_int, 1); xgmac_set_mtl_int(pdev, pdata->enable_mtl_int); } } @@ -336,7 +335,7 @@ void cli_set_mac_enable(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); if (pdata->mac_en) @@ -359,7 +358,7 @@ void cli_set_mac_address(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_mac_address(ops, pdata->mac_addr); } @@ -375,7 +374,7 @@ void cli_set_mac_rx_mode(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_promiscuous_mode(ops, pdata->promisc_mode); @@ -394,10 +393,10 @@ void cli_set_mtu(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); struct mac_ops *ops; - xgmac_printf("MTU going to set %d\n", pdata->mtu); + mac_printf("MTU going to set %d\n", pdata->mtu); if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_set_mtu(ops, pdata->mtu); } @@ -413,7 +412,7 @@ void cli_set_pause_frame_ctrl(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); if (pdata->pause_frm_enable) { @@ -443,7 +442,7 @@ void cli_set_pause_frame_filter(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_pause_frame_filtering(ops, pdata->pause_filter); @@ -460,7 +459,7 @@ void cli_initiate_pause_tx(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_initiate_pause_tx(ops); } @@ -476,7 +475,7 @@ void cli_set_mac_speed(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_set_physpeed(ops, pdata->phy_speed); } @@ -492,7 +491,7 @@ void cli_set_duplex_mode(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_set_duplex(ops, pdata->duplex_mode); } @@ -508,7 +507,7 @@ void cli_set_csum_offload(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_checksum_offload(ops, pdata->rx_checksum_offload); @@ -525,7 +524,7 @@ void cli_set_loopback(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_config_loopback(ops, pdata->loopback); } @@ -541,7 +540,7 @@ void cli_set_eee_mode(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_eee_timer(ops, pdata->twt, pdata->lst); @@ -560,7 +559,7 @@ void cli_set_crc_strip_type(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_crc_strip_type(ops, pdata->crc_strip_type); @@ -577,7 +576,7 @@ void cli_set_crc_strip_acs(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_acs(ops, pdata->padcrc_strip); } @@ -593,7 +592,7 @@ void cli_set_ipg(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_config_ipg(ops, pdata->ipg); } @@ -609,7 +608,7 @@ void cli_set_pmt_magic(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_magic_pmt(ops, pdata->magic_pkt_en); } @@ -625,7 +624,7 @@ void cli_set_pmt_gucast(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_pmt_gucast(ops, pdata->gucast); } @@ -641,7 +640,7 @@ void cli_set_pmt_rwk(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_rwk_filter_registers(ops, pdata->rwk_filter_length, @@ -676,7 +675,7 @@ void cli_clear_rmon_all(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_clear_rmon(ops, pdata->rmon_reset); } @@ -692,7 +691,7 @@ void cli_reset(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_reset(ops); } @@ -708,12 +707,12 @@ void cli_init(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); - xgmac_init(ops); + mac_init(ops); } } else { - xgmac_init(pdev); + mac_init(pdev); } } @@ -724,7 +723,7 @@ void cli_set_extcfg(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_extcfg(ops, pdata->extcfg); } @@ -740,7 +739,7 @@ void cli_set_macrxtxcfg(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_mac_rxtx(ops, pdata->wd, pdata->jd); } @@ -756,7 +755,7 @@ void cli_set_linksts(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_set_linksts(ops, pdata->linksts); } @@ -772,7 +771,7 @@ void cli_set_lpitx(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_set_mac_lpitx(ops, pdata->lpitxa); } @@ -788,7 +787,7 @@ void cli_set_mdio_cl(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mdio_set_clause(ops, pdata->mdio_cl, pdata->phy_id); @@ -805,7 +804,7 @@ void cli_mdio_rd_cont(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); print_mdio_rd_cnt(ops, pdata->dev_adr, @@ -829,7 +828,7 @@ void cli_mdio_rd(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_mdio_single_rd(ops, pdata->dev_adr, @@ -853,7 +852,7 @@ void cli_mdio_wr(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); xgmac_mdio_single_wr(ops, pdata->dev_adr, @@ -877,7 +876,7 @@ void cli_set_mdio_int(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mdio_set_interrupt(ops, pdata->mdio_int); } @@ -893,7 +892,7 @@ void cli_set_fcsgen(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); mac_set_fcs_gen(ops, pdata->fcsgen); } @@ -909,18 +908,18 @@ void cli_set_txtstamp_mode(void *pdev) struct mac_ops *ops; if (pdata->set_all) { - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); - xgmac_onestep_ptp_txtstamp_mode(ops, - pdata->snaptype, - pdata->tsmstrena, - pdata->tsevntena); - } - } else { - xgmac_onestep_ptp_txtstamp_mode(pdev, + xgmac_ptp_txtstamp_mode(ops, pdata->snaptype, pdata->tsmstrena, pdata->tsevntena); + } + } else { + xgmac_ptp_txtstamp_mode(pdev, + pdata->snaptype, + pdata->tsmstrena, + pdata->tsevntena); } } @@ -956,9 +955,9 @@ void cli_rx_packet_slavemode(void *pdev) xgmac_clr_debug_sts(pdev); - xgmac_printf("Packet State %x\n", pdata->dbg_pktstate); - xgmac_printf("Byteen %x\n", pdata->dbg_byteen); - xgmac_printf("Dbg Data %x\n", pdata->dbg_data); + mac_printf("Packet State %x\n", pdata->dbg_pktstate); + mac_printf("Byteen %x\n", pdata->dbg_byteen); + mac_printf("Dbg Data %x\n", pdata->dbg_data); } void cli_rx_packet_dbgmode(void *pdev) @@ -972,17 +971,17 @@ void cli_rx_packet_dbgmode(void *pdev) pdata->dbg_en = 1; pdata->dbg_mode = 1, - xgmac_set_debug_ctl(pdev, pdata->dbg_en, pdata->dbg_mode); + xgmac_set_debug_ctl(pdev, pdata->dbg_en, pdata->dbg_mode); pdata->dbg_rst_all = 1, - xgmac_set_fifo_reset(pdev, 0, pdata->dbg_rst_all); + xgmac_set_fifo_reset(pdev, 0, pdata->dbg_rst_all); pdata->dbg_pktstate = RX_PKT_DATA; xgmac_rx_debug_data(pdev, &pdata->dbg_pktstate, &pdata->dbg_byteen); xgmac_get_debug_data(pdev, &pdata->dbg_data); - xgmac_printf("Packet State %x\n", pdata->dbg_pktstate); - xgmac_printf("Byteen %x\n", pdata->dbg_byteen); - xgmac_printf("Dbg Data %x\n", pdata->dbg_data); + mac_printf("Packet State %x\n", pdata->dbg_pktstate); + mac_printf("Byteen %x\n", pdata->dbg_byteen); + mac_printf("Dbg Data %x\n", pdata->dbg_data); } diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.h b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.h index 8f73162cecc14fecc67075355e2c1e8d67be0e35..e9eb986e3300149544ab856ef56636a99ccca5c1 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_cli.h @@ -39,10 +39,11 @@ * DAMAGE. * ========================================================================= */ + #ifndef _XGMAC_CLI_ #define _XGMAC_CLI_ -#include "xgmac_common.h" +#include <xgmac_common.h> /* CLI SET API's */ diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_common.h b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_common.h index ffc4e8c640c7943dc0d3df1e01a690a0f9fd8909..dd08871e29ab116820071c66491fd20ffdd33bab 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_common.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_common.h @@ -44,7 +44,7 @@ //#define CHIPTEST 0 //#define PC_UTILITY 0 -#define KERNEL_MODE 1 +//#define KERNEL_MODE 1 //#define CONFIG_SILVER_WORKAROUND 1 #if defined(PC_UTILITY) && PC_UTILITY @@ -52,7 +52,7 @@ #include <string.h> #endif -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ #include <linux/unistd.h> #include <linux/interrupt.h> #include <linux/module.h> @@ -81,7 +81,6 @@ #include <lantiq_soc.h> #include <linux/netdevice.h> #include <linux/net_tstamp.h> -#include <net/switch_api/lantiq_gsw.h> #include <linux/clocksource.h> #include <linux/ptp_clock_kernel.h> #include <linux/net_tstamp.h> @@ -101,12 +100,9 @@ #include <lantiq_gsw.h> #include <mac_ops.h> #include <adap_ops.h> +#include <types.h> #endif -typedef unsigned int u32; -typedef unsigned short u16; -typedef unsigned char u8; -typedef unsigned long long u64; #if defined(PC_UTILITY) && PC_UTILITY extern int pc_uart_dataread(u32 Offset, u32 *value); @@ -124,11 +120,6 @@ extern int pc_uart_datawrite_32(u32 Offset, u32 value); #define NANOSEC_IN_ONESEC 550000 #endif -#define REG64(addr) (*((volatile u64 *)(addr))) -#define REG32(addr) (*((volatile u32 *)(addr))) -#define REG16(addr) (*((volatile u16 *)(addr))) -#define REG8(addr) (*((volatile u8 *)(addr))) - #define XGMAC_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) #define GET_N_BITS(reg, pos, n) \ @@ -140,6 +131,17 @@ extern int pc_uart_datawrite_32(u32 Offset, u32 value); (reg) |= (((val) & ((0x1 << (n)) - 1)) << (pos)); \ } while (0) + +#define MAC_GET_VAL(var, reg, field) \ + GET_N_BITS((var), \ + reg##_##field##_POS, \ + reg##_##field##_WIDTH) + +#define MAC_SET_VAL(var, reg, field, val) \ + SET_N_BITS((var), \ + reg##_##field##_POS, \ + reg##_##field##_WIDTH, (val)) + #if defined(PC_UTILITY) && PC_UTILITY /* UART inetrface suppot function */ @@ -179,16 +181,16 @@ static inline void pcuart_reg_wr_32(u32 regaddr, u32 data) extern FILE *g_fp; FILE *get_fp(void); -#define xgmac_printf(...) \ +#define mac_printf(...) \ do { FILE *fp; \ fp = (FILE *) get_fp(); \ fprintf(fp, __VA_ARGS__); \ } while (0) #else -#define xgmac_printf printf +#define mac_printf printf #endif #else -#define xgmac_printf printk +#define mac_printf printk #endif static inline int mac_nstrlen(char *s) @@ -496,6 +498,13 @@ struct xgmac_hw_features { u32 aux_snap_num; /* Number of Aux snapshot inputs */ }; +struct mac_irq_hdl { + u32 irq_event; + void (*cb)(void *); + void *param; +}; + + /* do forward declaration of private data structure */ struct mac_prv_data; @@ -552,7 +561,9 @@ struct mac_prv_data { u32 nsec; u32 one_nsec_accuracy; u32 two_step; -#if defined(KERNEL_MODE) && KERNEL_MODE + u32 cic; + u32 rec_id; +#ifdef __KERNEL__ /* will be pointing to skb which is * queued for transmission and device * will take timesstamp for this skb @@ -565,6 +576,9 @@ struct mac_prv_data { struct ptp_clock *ptp_clock; u32 ptp_tx_init; spinlock_t mac_lock; + struct mii_bus *mii; + struct phy_device *phydev; + struct tasklet_struct mac_tasklet; #endif u32 snaptype; u32 tsmstrena; @@ -665,12 +679,24 @@ struct mac_prv_data { u32 phy_data; u32 mdio_int; + u32 phyadr; + u32 bus_id; + u32 ptp_clk; + /* Maximum number of MAC present */ + u32 max_mac; + + /* MAC IRQ Number */ + u32 irq_num; + + /* MAC IRQ handler */ + struct mac_irq_hdl *irq_hdl; + struct mac_ops ops; }; -extern struct mac_prv_data prv_data[3]; +extern struct mac_prv_data prv_data[10]; #if defined(PC_UTILITY) || defined(CHIPTEST) #define container_of(ptr, type, member) ({ \ @@ -691,6 +717,7 @@ static inline struct mac_prv_data *GET_MAC_PDATA(void *pdev) #if defined(PC_UTILITY) || defined(CHIPTEST) struct adap_ops *gsw_get_adap_ops(u32 devid); struct mac_ops *gsw_get_mac_ops(u32 devid, u32 mac_idx); +u32 gsw_get_mac_subifcnt(u32 devid); #endif int xgmac_main(u32 argc, u8 *argv[]); @@ -707,5 +734,7 @@ int xgmac_init(void *pdev); int xgmac_exit(void *pdev); void xgmac_init_pdata(struct mac_prv_data *pdata, int idx); int xgmac_get_all_hw_settings(void *pdev); +void xgmac_cli_init(void); +int populate_filter_frames(void *pdev); #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_debug.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_debug.c index 9809e28f6251b93d29ee0318c72c1d8a0d7c6d13..af1cbd68daaddc9b212e85196979bce72198ebe3 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_debug.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_debug.c @@ -39,8 +39,9 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" -#include "gswss_mac_api.h" + +#include <xgmac.h> +#include <gswss_mac_api.h> int xgmac_get_tx_cfg(void *pdev) { @@ -48,11 +49,11 @@ int xgmac_get_tx_cfg(void *pdev) u32 txq_en; - xgmac_printf("XGMAC %d: MTL_Q CFG\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL_Q CFG\n", pdata->mac_idx); txq_en = XGMAC_RGRD_BITS(pdata, MTL_Q_TQOMR, TXQEN); - xgmac_printf("\tMTL TX Q is %s by default\n", - txq_en ? "ENABLED" : "DISABLED"); + mac_printf("\tMTL TX Q is %s by default\n", + txq_en ? "ENABLED" : "DISABLED"); return 0; } @@ -64,12 +65,12 @@ int xgmac_get_counters_cfg(void *pdev) ror = XGMAC_RGRD_BITS(pdata, MMC_CR, ROR); - xgmac_printf("XGMAC %d: RMON_CFG\n", pdata->mac_idx); + mac_printf("XGMAC %d: RMON_CFG\n", pdata->mac_idx); if (ror) - xgmac_printf("\tMMC mode: Counters reset to zero after read\n"); + mac_printf("\tMMC mode: Counters reset to zero after read\n"); else - xgmac_printf("\tCounters will not get to Zero after a read\n"); + mac_printf("\tCounters will not get to Zero after a read\n"); return 0; } @@ -80,7 +81,7 @@ int xgmac_get_fifo_size(void *pdev) u32 rx_fifo_size, tx_fifo_size; - xgmac_printf("XGMAC %d: FIFO SIZE\n", pdata->mac_idx); + mac_printf("XGMAC %d: FIFO SIZE\n", pdata->mac_idx); rx_fifo_size = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, RQS); tx_fifo_size = XGMAC_RGRD_BITS(pdata, MTL_Q_TQOMR, TQS); @@ -88,8 +89,8 @@ int xgmac_get_fifo_size(void *pdev) rx_fifo_size = ((rx_fifo_size + 1) * 256); tx_fifo_size = ((tx_fifo_size + 1) * 256); - xgmac_printf("\tRX Q, RQS %d byte fifo per queue\n", rx_fifo_size); - xgmac_printf("\tTX Q, TQS %d byte fifo per queue\n", tx_fifo_size); + mac_printf("\tRX Q, RQS %d byte fifo per queue\n", rx_fifo_size); + mac_printf("\tTX Q, TQS %d byte fifo per queue\n", tx_fifo_size); return 0; } @@ -99,7 +100,7 @@ int xgmac_get_flow_control_threshold(void *pdev) u32 fifo_size, rx_fc, rfa, rfd; - xgmac_printf("XGMAC %d: MTL FLOW Control Thresh\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL FLOW Control Thresh\n", pdata->mac_idx); fifo_size = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, RQS); fifo_size = ((fifo_size + 1) * 256); @@ -107,20 +108,20 @@ int xgmac_get_flow_control_threshold(void *pdev) rfa = XGMAC_RGRD_BITS(pdata, MTL_Q_RQFCR, RFA); rfd = XGMAC_RGRD_BITS(pdata, MTL_Q_RQFCR, RFD); - xgmac_printf("\tRX Q, RQS %d byte fifo per queue\n", fifo_size); - xgmac_printf("\tRx Q, Flow control activte Thresh value %d\n", rfa); - xgmac_printf("\tRx Q, Flow Control deactivate Thresh value %d\n", rfd); + mac_printf("\tRX Q, RQS %d byte fifo per queue\n", fifo_size); + mac_printf("\tRx Q, Flow control activte Thresh value %d\n", rfa); + mac_printf("\tRx Q, Flow Control deactivate Thresh value %d\n", rfd); if ((fifo_size >= 4096) && (rx_fc == 1)) - xgmac_printf("\tFLow Control will get triggered according" - "to Thresh values\n"); + mac_printf("\tFLow Control will get triggered according" + "to Thresh values\n"); if (fifo_size < 4096) - xgmac_printf("\tRQS is less than 4KB, Flow control" - "will not get triggered\n"); + mac_printf("\tRQS is less than 4KB, Flow control" + "will not get triggered\n"); if (rx_fc == 0) - xgmac_printf("\tFlow control is disabled\n"); + mac_printf("\tFlow control is disabled\n"); return 0; } @@ -131,11 +132,11 @@ int xgmac_get_mtl_rx_flow_ctl(void *pdev) u32 rx_fc; - xgmac_printf("XGMAC %d: MTL RX Flow Control\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL RX Flow Control\n", pdata->mac_idx); rx_fc = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, EHFC); - xgmac_printf("\tRX Flow control operation is %s\n", - rx_fc ? "ENABLED" : "DISABLED"); + mac_printf("\tRX Flow control operation is %s\n", + rx_fc ? "ENABLED" : "DISABLED"); return 0; } @@ -145,19 +146,19 @@ int xgmac_get_mtl_tx(void *pdev) u32 tx_mode; - xgmac_printf("XGMAC %d: MTL TX mode\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL TX mode\n", pdata->mac_idx); tx_mode = XGMAC_RGRD_BITS(pdata, MTL_Q_TQOMR, TSF); if (tx_mode == 1) - xgmac_printf("\tXGMAC %d TX Q Mode: Store and Forward mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q Mode: Store and Forward mode\n", + pdata->mac_idx); else if (tx_mode == 0) - xgmac_printf("\tXGMAC %d TX Q Mode: Thresh mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q Mode: Thresh mode\n", + pdata->mac_idx); else - xgmac_printf("\tXGMAC %d TX Q Mode: unknown mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q Mode: unknown mode\n", + pdata->mac_idx); xgmac_get_tx_threshold(pdev); return 0; @@ -169,19 +170,19 @@ int xgmac_get_mtl_rx(void *pdev) u32 rx_mode; - xgmac_printf("XGMAC %d: MTL RX mode\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL RX mode\n", pdata->mac_idx); rx_mode = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, RSF); if (rx_mode == 1) - xgmac_printf("\tXGMAC %d RX Q Mode: Store and Forward mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q Mode: Store and Forward mode\n", + pdata->mac_idx); else if (rx_mode == 0) - xgmac_printf("\tXGMAC %d RX Q Mode: Thresh mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q Mode: Thresh mode\n", + pdata->mac_idx); else - xgmac_printf("\tXGMAC %d RX Q Mode: unknown mode\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q Mode: unknown mode\n", + pdata->mac_idx); xgmac_get_rx_threshold(pdev); return 0; @@ -192,34 +193,34 @@ int xgmac_get_tx_threshold(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 tx_thresh; - xgmac_printf("XGMAC %d: MTL TX Thresh\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL TX Thresh\n", pdata->mac_idx); tx_thresh = XGMAC_RGRD_BITS(pdata, MTL_Q_TQOMR, TTC); if (tx_thresh == MTL_TX_THRESHOLD_32) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 32 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 32 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_64) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 64 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 64 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_96) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 96 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 96 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_128) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 128 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 128 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_192) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 192 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 192 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_256) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 256 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 256 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_384) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 384 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 384 bytes\n", + pdata->mac_idx); else if (tx_thresh == MTL_TX_THRESHOLD_512) - xgmac_printf("\tXGMAC %d TX Q operates in Thresh 512 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d TX Q operates in Thresh 512 bytes\n", + pdata->mac_idx); return 0; } @@ -230,22 +231,22 @@ int xgmac_get_rx_threshold(void *pdev) u32 rx_thresh; - xgmac_printf("XGMAC %d: MTL RX Thresh\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL RX Thresh\n", pdata->mac_idx); rx_thresh = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, RTC); if (rx_thresh == MTL_RX_THRESHOLD_32) - xgmac_printf("\tXGMAC %d RX Q operates in Thresh 32 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q operates in Thresh 32 bytes\n", + pdata->mac_idx); else if (rx_thresh == MTL_RX_THRESHOLD_64) - xgmac_printf("\tXGMAC %d RX Q operates in Thresh 64 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q operates in Thresh 64 bytes\n", + pdata->mac_idx); else if (rx_thresh == MTL_RX_THRESHOLD_96) - xgmac_printf("\tXGMAC %d RX Q operates in Thresh 96 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q operates in Thresh 96 bytes\n", + pdata->mac_idx); else if (rx_thresh == MTL_RX_THRESHOLD_128) - xgmac_printf("\tXGMAC %d RX Q operates in Thresh 128 bytes\n", - pdata->mac_idx); + mac_printf("\tXGMAC %d RX Q operates in Thresh 128 bytes\n", + pdata->mac_idx); return 0; } @@ -257,21 +258,21 @@ int xgmac_get_mtl_q_alg(void *pdev) tx_mtl_alg = XGMAC_RGRD_BITS(pdata, MTL_OMR, ETSALG); - xgmac_printf("XGMAC %d: MTL_Q ALG\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL_Q ALG\n", pdata->mac_idx); if (tx_mtl_alg == MTL_ETSALG_WRR) - xgmac_printf("\tTX is set to WRR Algorithm\n"); + mac_printf("\tTX is set to WRR Algorithm\n"); else if (tx_mtl_alg == MTL_ETSALG_WFQ) - xgmac_printf("\tTX is set to WFQ Algorithm\n"); + mac_printf("\tTX is set to WFQ Algorithm\n"); else if (tx_mtl_alg == MTL_ETSALG_DWRR) - xgmac_printf("\tTX is set to DWRR Algorithm\n"); + mac_printf("\tTX is set to DWRR Algorithm\n"); rx_mtl_alg = XGMAC_RGRD_BITS(pdata, MTL_OMR, RAA); if (rx_mtl_alg == MTL_RAA_SP) - xgmac_printf("\tRX is set to Strict Priority Algorithm\n"); + mac_printf("\tRX is set to Strict Priority Algorithm\n"); else if (rx_mtl_alg == MTL_RAA_WSP) - xgmac_printf("\tRX is set to WSP Algorithm\n"); + mac_printf("\tRX is set to WSP Algorithm\n"); return 0; } @@ -281,41 +282,41 @@ int xgmac_get_crc_settings(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 cst, acs, dcrcc; - xgmac_printf("XGMAC %d: CRC Stripping\n", pdata->mac_idx); + mac_printf("XGMAC %d: CRC Stripping\n", pdata->mac_idx); cst = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, CST); - xgmac_printf("\tCRC stripping for Type packets: %s\n", - cst ? "ENABLED" : "DISABLED"); + mac_printf("\tCRC stripping for Type packets: %s\n", + cst ? "ENABLED" : "DISABLED"); acs = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, ACS); - xgmac_printf("\tAutomatic Pad or CRC Stripping: %s\n", - acs ? "ENABLED" : "DISABLED"); + mac_printf("\tAutomatic Pad or CRC Stripping: %s\n", + acs ? "ENABLED" : "DISABLED"); dcrcc = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, DCRCC); - xgmac_printf("\tMAC RX do not check the CRC field in the rx pkt: %s\n", - dcrcc ? "ENABLED" : "DISABLED"); + mac_printf("\tMAC RX do not check the CRC field in the rx pkt: %s\n", + dcrcc ? "ENABLED" : "DISABLED"); return 0; } -int xgmac_get_eee_status(void *pdev) +int xgmac_dbg_eee_status(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 varmac_lps; varmac_lps = XGMAC_RGRD(pdata, MAC_LPI_CSR); - xgmac_printf("XGMAC %d: EEE Status\n", pdata->mac_idx); + mac_printf("XGMAC %d: EEE Status\n", pdata->mac_idx); - xgmac_printf("\tMAC_LPI_Control_Status = %x\n", varmac_lps); + mac_printf("\tMAC_LPI_Control_Status = %x\n", varmac_lps); if (varmac_lps & MAC_LPS_TLPIEN) - xgmac_printf("\tMAC Transmitter has entered the LPI state\n"); + mac_printf("\tMAC Transmitter has entered the LPI state\n"); if (varmac_lps & MAC_LPS_TLPIEX) - xgmac_printf("\tMAC Transmitter has exited the LPI state\n"); + mac_printf("\tMAC Transmitter has exited the LPI state\n"); if (varmac_lps & MAC_LPS_RLPIEN) - xgmac_printf("\tMAC Receiver has entered the LPI state\n"); + mac_printf("\tMAC Receiver has entered the LPI state\n"); if (varmac_lps & MAC_LPS_RLPIEX) - xgmac_printf("\tMAC Receiver has exited the LPI state\n"); + mac_printf("\tMAC Receiver has exited the LPI state\n"); return 0; } @@ -331,18 +332,18 @@ int xgmac_get_eee_settings(void *pdev) lpitxa = XGMAC_RGRD_BITS(pdata, MAC_LPI_CSR, LPITXA); lpitxen = XGMAC_RGRD_BITS(pdata, MAC_LPI_CSR, LPITXEN); - xgmac_printf("XGMAC %d: EEE Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: EEE Settings\n", pdata->mac_idx); - xgmac_printf("\tLPI LS TIMER: %d\n", lst); - xgmac_printf("\tLPI TW TIMER: %d\n", twt); - xgmac_printf("\tPhy link Status: %s\n", - pls ? "ENABLED" : "DISABLED"); - xgmac_printf("\tLPI Transmit Automate: %s\n", - lpitxa ? "ENABLED" : "DISABLED"); - xgmac_printf("\tLPI Transmit Enable: %s\n", - lpitxen ? "ENABLED" : "DISABLED"); + mac_printf("\tLPI LS TIMER: %d\n", lst); + mac_printf("\tLPI TW TIMER: %d\n", twt); + mac_printf("\tPhy link Status: %s\n", + pls ? "ENABLED" : "DISABLED"); + mac_printf("\tLPI Transmit Automate: %s\n", + lpitxa ? "ENABLED" : "DISABLED"); + mac_printf("\tLPI Transmit Enable: %s\n", + lpitxen ? "ENABLED" : "DISABLED"); - xgmac_get_eee_status(pdev); + xgmac_dbg_eee_status(pdev); return 0; } @@ -351,14 +352,14 @@ int xgmac_get_mac_settings(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 te, re, ra; - xgmac_printf("XGMAC %d: MAC Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC Settings\n", pdata->mac_idx); te = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, TE); - xgmac_printf("\tMAC TX: %s\n", te ? "ENABLED" : "DISABLED"); + mac_printf("\tMAC TX: %s\n", te ? "ENABLED" : "DISABLED"); re = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, RE); - xgmac_printf("\tMAC RX: %s\n", re ? "ENABLED" : "DISABLED"); + mac_printf("\tMAC RX: %s\n", re ? "ENABLED" : "DISABLED"); ra = XGMAC_RGRD_BITS(pdata, MAC_PKT_FR, RA); - xgmac_printf("\tMAC Filter RX ALL: %s\n", ra ? "ENABLED" : "DISABLED"); + mac_printf("\tMAC Filter RX ALL: %s\n", ra ? "ENABLED" : "DISABLED"); return 0; } @@ -367,41 +368,41 @@ int xgmac_get_mac_rxtx_sts(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 rwt, tjt, wd, jd; - xgmac_printf("XGMAC %d: MAC RXTX Status\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC RXTX Status\n", pdata->mac_idx); jd = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, JD); wd = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, WD); - xgmac_printf("\tWATCHDOG Disable : %s\n", - wd ? "ENABLED" : "DISABLED"); - xgmac_printf("\tJABBER TIMEOUT Disable : %s\n", - jd ? "ENABLED" : "DISABLED"); + mac_printf("\tWATCHDOG Disable : %s\n", + wd ? "ENABLED" : "DISABLED"); + mac_printf("\tJABBER TIMEOUT Disable : %s\n", + jd ? "ENABLED" : "DISABLED"); rwt = XGMAC_RGRD_BITS(pdata, MAC_RXTX_STS, RWT); if (wd) - xgmac_printf("\tMAC : %s\n", - rwt ? - "Received packet > 16383 bytes with WD=1" : - "No packet recived with RWT"); + mac_printf("\tMAC : %s\n", + rwt ? + "Received packet > 16383 bytes with WD=1" : + "No packet recived with RWT"); else - xgmac_printf("\tMAC : %s\n", - rwt ? - "Received packet > 2048 bytes with WD=0" : - "No packet recived with RWT"); + mac_printf("\tMAC : %s\n", + rwt ? + "Received packet > 2048 bytes with WD=0" : + "No packet recived with RWT"); tjt = XGMAC_RGRD_BITS(pdata, MAC_RXTX_STS, TJT); if (jd) - xgmac_printf("\tMAC : %s\n", - tjt ? - "Transmitted packet > 16383 bytes with JD=1" : - "No packet transmitted with TJT"); + mac_printf("\tMAC : %s\n", + tjt ? + "Transmitted packet > 16383 bytes with JD=1" : + "No packet transmitted with TJT"); else - xgmac_printf("\tMAC : %s\n", - tjt ? - "Transmitted packet > 2048 bytes with JD=0" : - "No packet transmitted with TJT"); + mac_printf("\tMAC : %s\n", + tjt ? + "Transmitted packet > 2048 bytes with JD=0" : + "No packet transmitted with TJT"); return 0; } @@ -413,50 +414,50 @@ int xgmac_get_mtu_settings(void *pdev) mac_rcr = XGMAC_RGRD(pdata, MAC_RX_CFG); - je = XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, JE); - wd = XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, WD); - gpslce = XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, GPSLCE); - gpsl = XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, GPSL); + je = MAC_GET_VAL(mac_rcr, MAC_RX_CFG, JE); + wd = MAC_GET_VAL(mac_rcr, MAC_RX_CFG, WD); + gpslce = MAC_GET_VAL(mac_rcr, MAC_RX_CFG, GPSLCE); + gpsl = MAC_GET_VAL(mac_rcr, MAC_RX_CFG, GPSL); jd = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, JD); - xgmac_printf("XGMAC %d: MTU Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTU Settings\n", pdata->mac_idx); - xgmac_printf("\tMTU CONFIGURED %d\n", pdata->mtu); + mac_printf("\tMTU CONFIGURED %d\n", pdata->mtu); if (je) - xgmac_printf("\tJumbo Enabled: 1, MAC allows jumbo packets of " - "9,018 bytes (9,022 bytes for VLAN tagged packets)" - "without reporting a giant packet error\n"); + mac_printf("\tJumbo Enabled: 1, MAC allows jumbo packets of " + "9,018 bytes (9,022 bytes for VLAN tagged packets)" + "without reporting a giant packet error\n"); if (wd) - xgmac_printf("\tWatchdog Disable: 1,MAC disables the " - "watchdog timer on the receiver. The MAC can " - "receive packets of up to 16,383 bytes.\n"); + mac_printf("\tWatchdog Disable: 1,MAC disables the " + "watchdog timer on the receiver. The MAC can " + "receive packets of up to 16,383 bytes.\n"); else - xgmac_printf("\tWatchdog Disable: 0, MAC does not allow more " - "than 2,048 bytes (10,240 if JE is 1) of the pkt " - "being received.The MAC cuts off any bytes " - "received after 2,048 bytes\n"); + mac_printf("\tWatchdog Disable: 0, MAC does not allow more " + "than 2,048 bytes (10,240 if JE is 1) of the pkt " + "being received.The MAC cuts off any bytes " + "received after 2,048 bytes\n"); if (gpslce) { - xgmac_printf("\tGPSLCE: 1, MAC considers the value in " - "GPSL field to declare a received packet " - "as Giant packet\n"); - xgmac_printf("\tGPSL: %04x\n", gpsl); + mac_printf("\tGPSLCE: 1, MAC considers the value in " + "GPSL field to declare a received packet " + "as Giant packet\n"); + mac_printf("\tGPSL: %04x\n", gpsl); } else { - xgmac_printf("\tGPSLCE: 0, MAC considers a RX packet as Giant " - "packet when its size is greater than 1,518 bytes" - "(1522 bytes for tagged packet)\n"); + mac_printf("\tGPSLCE: 0, MAC considers a RX packet as Giant " + "packet when its size is greater than 1,518 bytes" + "(1522 bytes for tagged packet)\n"); } if (jd) - xgmac_printf("\tJabber Disable: 1, XGMAC disables the " - "jabber timer on the tx. Tx of up to 16,383-byte " - "frames is supported.\n"); + mac_printf("\tJabber Disable: 1, XGMAC disables the " + "jabber timer on the tx. Tx of up to 16,383-byte " + "frames is supported.\n"); else - xgmac_printf("\tJabber Disable: 0, XGMAC cuts off the TX " - "if the application sends more than 2,048 bytes " - "of data (10,240 bytes if JE is 1 during TX\n"); + mac_printf("\tJabber Disable: 0, XGMAC cuts off the TX " + "if the application sends more than 2,048 bytes " + "of data (10,240 bytes if JE is 1 during TX\n"); return 0; } @@ -467,8 +468,8 @@ int xgmac_get_checksum_offload(void *pdev) u32 co = 0; co = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, IPC); - xgmac_printf("XGMAC %d: Checksum Offload Settings\n", pdata->mac_idx); - xgmac_printf("\tChecksum Offload : %s\n", co ? "ENABLED" : "DISABLED"); + mac_printf("XGMAC %d: Checksum Offload Settings\n", pdata->mac_idx); + mac_printf("\tChecksum Offload : %s\n", co ? "ENABLED" : "DISABLED"); return 0; } @@ -481,10 +482,10 @@ int xgmac_get_mac_addr(void *pdev) mac_addr_hi = XGMAC_RGRD(pdata, MAC_MACA0HR); mac_addr_lo = XGMAC_RGRD(pdata, MAC_MACA0LR); - xgmac_printf("XGMAC %d: MAC ADDR\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC ADDR\n", pdata->mac_idx); - xgmac_printf("\tmac_addr_hi = %08x\n", mac_addr_hi); - xgmac_printf("\tmac_addr_lo = %08x\n", mac_addr_lo); + mac_printf("\tmac_addr_hi = %08x\n", mac_addr_hi); + mac_printf("\tmac_addr_lo = %08x\n", mac_addr_lo); mac_addr[5] = ((mac_addr_hi & 0x0000FF00) >> 8); mac_addr[4] = (mac_addr_hi & 0x000000FF); @@ -493,13 +494,13 @@ int xgmac_get_mac_addr(void *pdev) mac_addr[1] = ((mac_addr_lo & 0x0000FF00) >> 8); mac_addr[0] = (mac_addr_lo & 0x000000FF); - xgmac_printf("\tSet mac address %02x:%02x:%02x:%02x:%02x:%02x\n", - mac_addr[0], - mac_addr[1], - mac_addr[2], - mac_addr[3], - mac_addr[4], - mac_addr[5]); + mac_printf("\tSet mac address %02x:%02x:%02x:%02x:%02x:%02x\n", + mac_addr[0], + mac_addr[1], + mac_addr[2], + mac_addr[3], + mac_addr[4], + mac_addr[5]); return 0; } @@ -508,14 +509,14 @@ int xgmac_get_mac_rx_mode(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mode = 0; - xgmac_printf("XGMAC %d: MAC RX MODE\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC RX MODE\n", pdata->mac_idx); mode = XGMAC_RGRD_BITS(pdata, MAC_PKT_FR, PR); - xgmac_printf("\tPromiscous Mode : %s\n", - mode ? "ENABLED" : "DISABLED"); + mac_printf("\tPromiscous Mode : %s\n", + mode ? "ENABLED" : "DISABLED"); mode = XGMAC_RGRD_BITS(pdata, MAC_PKT_FR, PM); - xgmac_printf("\tPass All Multicast : %s\n", - mode ? "ENABLED" : "DISABLED"); + mac_printf("\tPass All Multicast : %s\n", + mode ? "ENABLED" : "DISABLED"); return 0; } @@ -526,9 +527,9 @@ int xgmac_get_rx_vlan_filtering_mode(void *pdev) vtfe = XGMAC_RGRD_BITS(pdata, MAC_PKT_FR, VTFE); - xgmac_printf("XGMAC %d: RX VLAN Filtering\n", pdata->mac_idx); - xgmac_printf("\tRX VLAN Filtering is %s\n", - vtfe ? "ENABLED" : "DISABLED"); + mac_printf("XGMAC %d: RX VLAN Filtering\n", pdata->mac_idx); + mac_printf("\tRX VLAN Filtering is %s\n", + vtfe ? "ENABLED" : "DISABLED"); return 0; } @@ -538,14 +539,14 @@ int xgmac_get_mac_speed(void *pdev) u32 speed; speed = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, SS); - xgmac_printf("XGMAC %d: MAC Speed\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC Speed\n", pdata->mac_idx); if (speed == 0) - xgmac_printf("\tXGMAC configured for XGMII 10G speed\n"); + mac_printf("\tXGMAC configured for XGMII 10G speed\n"); else if (speed == 2) - xgmac_printf("\tXGMAC configured for GMII 2.5G speed\n"); + mac_printf("\tXGMAC configured for GMII 2.5G speed\n"); else if (speed == 3) - xgmac_printf("\tXGMAC configured for GMII 1G speed\n"); + mac_printf("\tXGMAC configured for GMII 1G speed\n"); return 0; } @@ -560,36 +561,36 @@ int xgmac_get_pause_frame_ctl(void *pdev) tfe = XGMAC_RGRD_BITS(pdata, MAC_TX_FCR, TFE); pt = XGMAC_RGRD_BITS(pdata, MAC_TX_FCR, PT); - xgmac_printf("XGMAC %d: Pause Frame Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: Pause Frame Settings\n", pdata->mac_idx); - xgmac_printf("\tPriority based Flow control: %s\n", - pfce ? "ENABLED" : "DISABLED"); + mac_printf("\tPriority based Flow control: %s\n", + pfce ? "ENABLED" : "DISABLED"); if (pfce) - xgmac_printf("\tEnables TX of priority based flow Ctrl Pkts\n"); + mac_printf("\tEnables TX of priority based flow Ctrl Pkts\n"); else - xgmac_printf("\tEnables TX and RX of 802.3x Pause Ctrl Pkts\n"); + mac_printf("\tEnables TX and RX of 802.3x Pause Ctrl Pkts\n"); - xgmac_printf("\tReceive Flow control: %s\n", - rfe ? "ENABLED" : "DISABLED"); + mac_printf("\tReceive Flow control: %s\n", + rfe ? "ENABLED" : "DISABLED"); if (rfe) - xgmac_printf("\tMAC decodes the Rx Pause packets and " - "disables the TX for a specified Pause time\n"); + mac_printf("\tMAC decodes the Rx Pause packets and " + "disables the TX for a specified Pause time\n"); else - xgmac_printf("\tMAC doesnot decode the Pause packet\n"); + mac_printf("\tMAC doesnot decode the Pause packet\n"); - xgmac_printf("\tTransmit Flow control: %s\n", - tfe ? "ENABLED" : "DISABLED"); + mac_printf("\tTransmit Flow control: %s\n", + tfe ? "ENABLED" : "DISABLED"); if (tfe) - xgmac_printf("\tMAC enables Flow control operation " - "based on Pause frame\n"); + mac_printf("\tMAC enables Flow control operation " + "based on Pause frame\n"); else - xgmac_printf("\tMAC does not transmit and Pause packets by " - "itself\n"); + mac_printf("\tMAC does not transmit and Pause packets by " + "itself\n"); - xgmac_printf("\tPause Time: %d\n", pt); + mac_printf("\tPause Time: %d\n", pt); return 0; } @@ -600,8 +601,8 @@ int xgmac_get_mac_loopback_mode(void *pdev) lm = XGMAC_RGRD_BITS(pdata, MAC_RX_CFG, LM); - xgmac_printf("XGMAC %d: MAC Loopback\n", pdata->mac_idx); - xgmac_printf("\tMAC Loopback mode: %s\n", lm ? "ENABLED" : "DISABLED"); + mac_printf("XGMAC %d: MAC Loopback\n", pdata->mac_idx); + mac_printf("\tMAC Loopback mode: %s\n", lm ? "ENABLED" : "DISABLED"); return 0; } @@ -612,57 +613,57 @@ int xgmac_get_tstamp_settings(void *pdev) mac_tscr = XGMAC_RGRD(pdata, MAC_TSTAMP_CR); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA); - - xgmac_printf("XGMAC %d: Timestamp Settings\n", pdata->mac_idx); - xgmac_printf("\tTimestamp is added for TX and RX packets: %s\n", - val ? "ENABLED" : "DISABLED"); - - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSCFUPDT); - xgmac_printf("\tTimestamp Update type: %s\n", val ? "FINE" : "COARSE"); - xgmac_printf("\tAddend present only in FINE update, " - "Timestamp Addend value %d\n", - XGMAC_RGRD(pdata, MAC_TSTAMP_ADDNDR)); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENALL); - xgmac_printf("\tTimestamp for All Packets Received: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR); - xgmac_printf("\tTimestamp Digital or Binary Rollover Control %s\n", - val ? - "TIME STAMP DIGITAL (1ns accuracy)" : - "BINARY ROLLOVER"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSTRIG); - xgmac_printf("\tTSTRIG: Timestamp Interrupt trigger: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA); - xgmac_printf("\tTSVER2ENA: PTP Pkt Processing for Ver 2 Format: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPENA); - xgmac_printf("\tTSIPENA: MAC receiver processes the PTP packets " - "encapsulated directly in the Ethernet packets: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA); - xgmac_printf("\tTSIPV6ENA: MAC receiver processes the PTP packets " - "encapsulated in IPv6-UDP packets: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA); - xgmac_printf("\tTSIPV4ENA: MAC receiver processes the PTP packets " - "encapsulated in IPv4-UDP packets: %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA); - xgmac_printf("\tTSEVNTENA: Timestamp snapshot is taken only for " - "event msg (SYNC, Delay_Req, Pdelay_Req, or " - "Pdelay_Resp): %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL); - xgmac_printf("\tSNAPTYPSEL: These bits, along with TSMSTRENA " - "TSEVNTENA, decide the set of PTP packet types for which " - "snapshot needs to be taken. %s\n", - val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA); - xgmac_printf("\tTSMSTRENA: Snapshot is taken only for the " - "messages that are relevant to the master node: %s\n", - val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA); + + mac_printf("XGMAC %d: Timestamp Settings\n", pdata->mac_idx); + mac_printf("\tTimestamp is added for TX and RX packets: %s\n", + val ? "ENABLED" : "DISABLED"); + + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSCFUPDT); + mac_printf("\tTimestamp Update type: %s\n", val ? "FINE" : "COARSE"); + mac_printf("\tAddend present only in FINE update, " + "Timestamp Addend value %d\n", + XGMAC_RGRD(pdata, MAC_TSTAMP_ADDNDR)); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENALL); + mac_printf("\tTimestamp for All Packets Received: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR); + mac_printf("\tTimestamp Digital or Binary Rollover Control %s\n", + val ? + "TIME STAMP DIGITAL (1ns accuracy)" : + "BINARY ROLLOVER"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSTRIG); + mac_printf("\tTSTRIG: Timestamp Interrupt trigger: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA); + mac_printf("\tTSVER2ENA: PTP Pkt Processing for Ver 2 Format: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPENA); + mac_printf("\tTSIPENA: MAC receiver processes the PTP packets " + "encapsulated directly in the Ethernet packets: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA); + mac_printf("\tTSIPV6ENA: MAC receiver processes the PTP packets " + "encapsulated in IPv6-UDP packets: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA); + mac_printf("\tTSIPV4ENA: MAC receiver processes the PTP packets " + "encapsulated in IPv4-UDP packets: %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA); + mac_printf("\tTSEVNTENA: Timestamp snapshot is taken only for " + "event msg (SYNC, Delay_Req, Pdelay_Req, or " + "Pdelay_Resp): %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL); + mac_printf("\tSNAPTYPSEL: These bits, along with TSMSTRENA " + "TSEVNTENA, decide the set of PTP packet types for which " + "snapshot needs to be taken. %s\n", + val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA); + mac_printf("\tTSMSTRENA: Snapshot is taken only for the " + "messages that are relevant to the master node: %s\n", + val ? "ENABLED" : "DISABLED"); return 0; } @@ -674,59 +675,65 @@ int xgmac_get_tstamp_status(void *pdev) mac_tscr = XGMAC_RGRD(pdata, MAC_TSTAMP_STSR); - xgmac_printf("XGMAC %d: Timestamp Status\n", pdata->mac_idx); - - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, ATSNS); - xgmac_printf("\tNumber of Auxiliary Timestamp Snapshots: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, ATSSTM); - xgmac_printf("\tAuxiliary Timestamp Snapshot Trigger Missed: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, ATSSTN); - xgmac_printf("\tAuxiliary Timestamp Snapshot Trigger Identifier %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TXTSC); - xgmac_printf("\tTX Timestamp Captured: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR3); - xgmac_printf("\tTimestamp Target Time Error: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTARGT3); - xgmac_printf("\tTimestamp Target Time Reached for Time PPS3: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR2); - xgmac_printf("\tTimestamp Target Time Error: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTARGT2); - xgmac_printf("\tTimestamp Target Time Reached for Time PPS2: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR1); - xgmac_printf("\tTimestamp Target Time Error: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTARGT1); - xgmac_printf("\tTimestamp Target Time Reached for Time PPS1: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR0); - xgmac_printf("\tTimestamp Target Time Error: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSTARGT0); - xgmac_printf("\tTimestamp Target Time Reached: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, AUXTSTRIG); - xgmac_printf("\tAuxiliary Timestamp Trigger Snapshot: %d\n", - val); - val = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_STSR, TSSOVF); - xgmac_printf("\tTimestamp Seconds Overflow %d\n", - val); - - xgmac_printf("\n\n"); + mac_printf("XGMAC %d: Timestamp Status\n", pdata->mac_idx); + + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, ATSNS); + mac_printf("\tNumber of Auxiliary Timestamp Snapshots: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, ATSSTM); + mac_printf("\tAuxiliary Timestamp Snapshot Trigger Missed: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, ATSSTN); + mac_printf("\tAuxiliary Timestamp Snapshot Trigger Identifier %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TXTSC); + mac_printf("\tTX Timestamp Captured: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR3); + mac_printf("\tTimestamp Target Time Error: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTARGT3); + mac_printf("\tTimestamp Target Time Reached for Time PPS3: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR2); + mac_printf("\tTimestamp Target Time Error: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTARGT2); + mac_printf("\tTimestamp Target Time Reached for Time PPS2: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR1); + mac_printf("\tTimestamp Target Time Error: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTARGT1); + mac_printf("\tTimestamp Target Time Reached for Time PPS1: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTRGTERR0); + mac_printf("\tTimestamp Target Time Error: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSTARGT0); + mac_printf("\tTimestamp Target Time Reached: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, AUXTSTRIG); + mac_printf("\tAuxiliary Timestamp Trigger Snapshot: %d\n", + val); + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TSSOVF); + mac_printf("\tTimestamp Seconds Overflow %d\n", + val); + + mac_printf("\n\n"); time = xgmac_get_systime(pdev); - xgmac_printf("\t64 bit system time in nsec %lld\n", - time); + mac_printf("\t64 bit system time in nsec %lld\n", + time); + + val = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_STSR, TTSNS); + mac_printf("\tTstamp captured count in xgmac Fifo: %d\n", + val); + time = xgmac_get_tx_tstamp(pdev); - xgmac_printf("\tTimestamp captured for the transmit pkt in nsec %lld\n", - time); + mac_printf("\tTimestamp captured in nsec: %lld\n", + time); + return 0; } @@ -768,12 +775,12 @@ int xgmac_print_system_time(void *pdev) days = 0; } - xgmac_printf("Uptime(d:h:m:s): %02d:%02d:%02d:%02d\n", - days, hr, min, sec); + mac_printf("Uptime(d:h:m:s): %02d:%02d:%02d:%02d\n", + days, hr, min, sec); - xgmac_printf("Sec %d\n", reg_sec); - xgmac_printf("NanoSec %d\n", nanosec); - xgmac_printf("Total in nsec %lld\n", nsec); + mac_printf("Sec %d\n", reg_sec); + mac_printf("NanoSec %d\n", nanosec); + mac_printf("Total in nsec %lld\n", nsec); return 0; } @@ -784,24 +791,24 @@ int xgmac_get_txtstamp_mode(void *pdev) u32 snaptypesel, tsmstrena, tsevntena, tsena; mac_txtstamp = GSWSS_MAC_RGRD(pdata, MAC_TXTS_CIC(pdata->mac_idx)); - xgmac_printf("TTSE: %s\n", - GET_N_BITS(mac_txtstamp, 4, 1) ? "ENABLED" : "DISABLED"); - xgmac_printf("OSTC: %s\n", - GET_N_BITS(mac_txtstamp, 3, 1) ? "ENABLED" : "DISABLED"); - xgmac_printf("OSTC_AVAIL: %s\n", - GET_N_BITS(mac_txtstamp, 2, 1) ? "ENABLED" : "DISABLED"); + mac_printf("TTSE: %s\n", + GET_N_BITS(mac_txtstamp, 4, 1) ? "ENABLED" : "DISABLED"); + mac_printf("OSTC: %s\n", + GET_N_BITS(mac_txtstamp, 3, 1) ? "ENABLED" : "DISABLED"); + mac_printf("OSTC_AVAIL: %s\n", + GET_N_BITS(mac_txtstamp, 2, 1) ? "ENABLED" : "DISABLED"); mac_tscr = XGMAC_RGRD(pdata, MAC_TSTAMP_CR); - snaptypesel = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL); - tsevntena = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA); - tsmstrena = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA); - tsena = XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA); + snaptypesel = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL); + tsevntena = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA); + tsmstrena = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA); + tsena = MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA); - xgmac_printf("snaptypesel %d\n", snaptypesel); - xgmac_printf("tsevntena %d\n", tsevntena); - xgmac_printf("tsmstrena %d\n", tsmstrena); - xgmac_printf("tsena %d\n", tsena); + mac_printf("snaptypesel %d\n", snaptypesel); + mac_printf("tsevntena %d\n", tsevntena); + mac_printf("tsmstrena %d\n", tsmstrena); + mac_printf("tsena %d\n", tsena); return 0; } @@ -813,52 +820,52 @@ int xgmac_get_debug_sts(void *pdev) dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); dbg_sts = XGMAC_RGRD(pdata, MTL_DBG_STS); - fifo_sel = XGMAC_GET_BITS(dbg_sts, MTL_DBG_CTL, FIFOSEL); + fifo_sel = MAC_GET_VAL(dbg_sts, MTL_DBG_CTL, FIFOSEL); - xgmac_printf("XGMAC %d: Debug Status\n", pdata->mac_idx); + mac_printf("XGMAC %d: Debug Status\n", pdata->mac_idx); - if (XGMAC_GET_BITS(dbg_sts, MTL_DBG_STS, FIFOBUSY)) { - xgmac_printf("\tA FIFO operation is in progress in the MAC, " - "All other fields in this register is Invalid\n"); + if (MAC_GET_VAL(dbg_sts, MTL_DBG_STS, FIFOBUSY)) { + mac_printf("\tA FIFO operation is in progress in the MAC, " + "All other fields in this register is Invalid\n"); return 0; } - pktstate = XGMAC_GET_BITS(dbg_sts, MTL_DBG_CTL, PKTSTATE); + pktstate = MAC_GET_VAL(dbg_sts, MTL_DBG_CTL, PKTSTATE); if (fifo_sel == 0) { - xgmac_printf("\tTX FIFO Selected\n"); + mac_printf("\tTX FIFO Selected\n"); if (pktstate == 0) - xgmac_printf("\tType of Data Read: PACKET_DATA\n"); + mac_printf("\tType of Data Read: PACKET_DATA\n"); else if (pktstate == 1) - xgmac_printf("\tType of Data Read: CONTROL_WORD\n"); + mac_printf("\tType of Data Read: CONTROL_WORD\n"); else if (pktstate == 2) - xgmac_printf("\tType of Data Read: SOP_DATA\n"); + mac_printf("\tType of Data Read: SOP_DATA\n"); else if (pktstate == 3) - xgmac_printf("\tType of Data Read: EOP_DATA\n"); + mac_printf("\tType of Data Read: EOP_DATA\n"); - xgmac_printf("\tSpace Available in Tx Fifo %d\n", - XGMAC_GET_BITS(dbg_sts, MTL_DBG_STS, LOCR)); + mac_printf("\tSpace Available in Tx Fifo %d\n", + MAC_GET_VAL(dbg_sts, MTL_DBG_STS, LOCR)); } else if (fifo_sel == 3) { - xgmac_printf("\tRX FIFO Selected\n"); + mac_printf("\tRX FIFO Selected\n"); if (pktstate == 0) - xgmac_printf("\tType of Data Read: PACKET_DATA\n"); + mac_printf("\tType of Data Read: PACKET_DATA\n"); else if (pktstate == 1) - xgmac_printf("\tType of Data Read: NORMAL_STS\n"); + mac_printf("\tType of Data Read: NORMAL_STS\n"); else if (pktstate == 2) - xgmac_printf("\tType of Data Read: LAST_STS\n"); + mac_printf("\tType of Data Read: LAST_STS\n"); else if (pktstate == 3) - xgmac_printf("\tType of Data Read: EOP\n"); + mac_printf("\tType of Data Read: EOP\n"); - xgmac_printf("\tSpace Available in Rx Fifo %d\n", - XGMAC_GET_BITS(dbg_sts, MTL_DBG_STS, LOCR)); + mac_printf("\tSpace Available in Rx Fifo %d\n", + MAC_GET_VAL(dbg_sts, MTL_DBG_STS, LOCR)); } - byteen = XGMAC_GET_BITS(dbg_ctl, MTL_DBG_CTL, BYTEEN); + byteen = MAC_GET_VAL(dbg_ctl, MTL_DBG_CTL, BYTEEN); - if (XGMAC_GET_BITS(dbg_sts, MTL_DBG_STS, PKTI)) - xgmac_printf("\tFull packet is available in RxFIFO\n"); + if (MAC_GET_VAL(dbg_sts, MTL_DBG_STS, PKTI)) + mac_printf("\tFull packet is available in RxFIFO\n"); return 0; } @@ -870,14 +877,14 @@ int xgmac_get_debug_data(void *pdev, u32 *dbg_data) dbg_ctrl = XGMAC_RGRD(pdata, MTL_DBG_CTL); *dbg_data = XGMAC_RGRD(pdata, MTL_DBG_DAT); - fifo_sel = XGMAC_GET_BITS(dbg_ctrl, MTL_DBG_CTL, FIFOSEL); + fifo_sel = MAC_GET_VAL(dbg_ctrl, MTL_DBG_CTL, FIFOSEL); - xgmac_printf("XGMAC %d: Debug Data\n", pdata->mac_idx); + mac_printf("XGMAC %d: Debug Data\n", pdata->mac_idx); if (fifo_sel == 0) - xgmac_printf("\tData pointer in the Tx FIFO %08x\n", *dbg_data); + mac_printf("\tData pointer in the Tx FIFO %08x\n", *dbg_data); else if (fifo_sel == 3) - xgmac_printf("\tData pointer in the Rx FIFO %08x\n", *dbg_data); + mac_printf("\tData pointer in the Rx FIFO %08x\n", *dbg_data); return 0; } @@ -891,155 +898,158 @@ int xgmac_get_fifo_space_left(void *pdev) dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); - fifo_sel = XGMAC_GET_BITS(dbg_ctl, MTL_DBG_CTL, FIFOSEL); - fdbgen = XGMAC_GET_BITS(dbg_ctl, MTL_DBG_CTL, FDBGEN); - dbgmod = XGMAC_GET_BITS(dbg_ctl, MTL_DBG_CTL, DBGMOD); + fifo_sel = MAC_GET_VAL(dbg_ctl, MTL_DBG_CTL, FIFOSEL); + fdbgen = MAC_GET_VAL(dbg_ctl, MTL_DBG_CTL, FDBGEN); + dbgmod = MAC_GET_VAL(dbg_ctl, MTL_DBG_CTL, DBGMOD); - xgmac_printf("XGMAC %d: Fifo Space Left\n", pdata->mac_idx); + mac_printf("XGMAC %d: Fifo Space Left\n", pdata->mac_idx); if (fdbgen && !dbgmod) { if (fifo_sel == 0) - xgmac_printf("\tSlave Mode: Space Available in the " - "TX FIFO %d\n", locr); + mac_printf("\tSlave Mode: Space Available in the " + "TX FIFO %d\n", locr); if (fifo_sel == 3) - xgmac_printf("\tSlave Mode: Space Available in the " - "RX FIFO %d\n", locr); + mac_printf("\tSlave Mode: Space Available in the " + "RX FIFO %d\n", locr); } if (fdbgen && dbgmod) { if (fifo_sel == 0) - xgmac_printf("\tData to be written to the Tx FIFO %d\n", - locr); + mac_printf("\tData to be written to the Tx FIFO %d\n", + locr); if (fifo_sel == 3) - xgmac_printf("\tData to be written to the Rx FIFO %d\n", - locr); + mac_printf("\tData to be written to the Rx FIFO %d\n", + locr); } return 0; } -int xgmac_get_int_sts(void *pdev) +int xgmac_dbg_int_sts(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_isr = 0, val; - xgmac_printf("XGMAC %d: MAC Interrupt Status\n", pdata->mac_idx); + mac_printf("XGMAC %d: MAC Interrupt Status\n", pdata->mac_idx); mac_isr = XGMAC_RGRD(pdata, MAC_ISR); val = XGMAC_RGRD(pdata, MAC_IER); - xgmac_printf("\tMAC_IER interrupts %s %08x\n", - val ? "ENABLED" : "DISABLED", val); + mac_printf("\tMAC_IER interrupts %s %08x\n", + val ? "ENABLED" : "DISABLED", val); /* Enable Timestamp interrupt */ if (val & MASK(MAC_IER, TSIE)) - xgmac_printf("\t\tTimestamp Interrupt Enabled\n"); + mac_printf("\t\tTimestamp Interrupt Enabled\n"); /* Enable LPI interrupt (EEE) */ if (val & MASK(MAC_IER, LPIIE)) - xgmac_printf("\t\tLPI interrupt (EEE) Enabled\n"); + mac_printf("\t\tLPI interrupt (EEE) Enabled\n"); /* Enable transmit error status interrupt */ if (val & MASK(MAC_IER, TXESIE)) - xgmac_printf("\t\tTransmit error status interrupt Enabled\n"); + mac_printf("\t\tTransmit error status interrupt Enabled\n"); /* Enable Receive error status interrupt */ if (val & MASK(MAC_IER, RXESIE)) - xgmac_printf("\t\tReceive error status interrupt Enabled\n"); + mac_printf("\t\tReceive error status interrupt Enabled\n"); /* Enable power management interrupt */ if (val & MASK(MAC_IER, PMTIE)) - xgmac_printf("\tPower Management interrupt Enabled\n"); + mac_printf("\tPower Management interrupt Enabled\n"); if (!mac_isr) { - xgmac_printf("\tNo MAC interrupt status available %d\n", - mac_isr); + mac_printf("\tNo MAC interrupt status available %d\n", + mac_isr); } else { - xgmac_printf("XGMAC %d: MAC Interrupt Status %08x\n", - pdata->mac_idx, mac_isr); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, LSI); + mac_printf("XGMAC %d: MAC Interrupt Status %08x\n", + pdata->mac_idx, mac_isr); + val = MAC_GET_VAL(mac_isr, MAC_ISR, LSI); if (val) - xgmac_printf("\tMAC_INT_STS: Link Status bits change " - "their value\n"); + mac_printf("\tMAC_INT_STS: Link Status bits change " + "their value\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, SMI); + val = MAC_GET_VAL(mac_isr, MAC_ISR, SMI); if (val) - xgmac_printf("\tMAC_INT_STS: Any of the bits in the " - "MDIO Interrupt Status Register is set\n"); + mac_printf("\tMAC_INT_STS: Any of the bits in the " + "MDIO Interrupt Status Register is set\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, PMTIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, PMTIS); if (val) - xgmac_printf("\tMAC_INT_STS: A Magic packet or " - "Wake-on-LAN packet is received in the " - "power-down mode\n"); + mac_printf("\tMAC_INT_STS: A Magic packet or " + "Wake-on-LAN packet is received in the " + "power-down mode\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, LPIIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, LPIIS); if (val) - xgmac_printf("\tMAC_INT_STS: It is set for any LPI " - "state entry or exit in the MAC Tx/Rx\n"); + mac_printf("\tMAC_INT_STS: It is set for any LPI " + "state entry or exit in the MAC Tx/Rx\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, MMCRXIS); if (val) - xgmac_printf("\tMAC_INT_STS: Interrupt is generated " - "in the MMC Receive Interrupt Register\n"); + mac_printf("\tMAC_INT_STS: Interrupt is generated " + "in the MMC Receive Interrupt Register\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, MMCTXIS); if (val) - xgmac_printf("\tMAC_INT_STS: Interrupt is generated in " - "the MMC Transmit Interrupt Register\n"); + mac_printf("\tMAC_INT_STS: Interrupt is generated in " + "the MMC Transmit Interrupt Register\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, TSIS); if (val) - xgmac_printf("\tMAC_INT_STS: Timestamp Interrupt Status" - "is set\n"); + mac_printf("\tMAC_INT_STS: Timestamp Interrupt Status" + "is set\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, TXESIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, TXESIS); if (val) - xgmac_printf("\tMAC_INT_STS: Transmit Error, " - "Jabber Timeout (TJT) event occurs during " - "transmission\n"); + mac_printf("\tMAC_INT_STS: Transmit Error, " + "Jabber Timeout (TJT) event occurs during " + "transmission\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, RXESIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, RXESIS); if (val) - xgmac_printf("\tMAC_INT_STS: Receive Error, Watchdog " - "Timeout (WDT) event occurs during Rx.\n"); + mac_printf("\tMAC_INT_STS: Receive Error, Watchdog " + "Timeout (WDT) event occurs during Rx.\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, GPIIS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, GPIIS); if (val) - xgmac_printf("\tMAC_INT_STS: GPIO Interrupt status " - "is set\n"); + mac_printf("\tMAC_INT_STS: GPIO Interrupt status " + "is set\n"); - val = XGMAC_GET_BITS(mac_isr, MAC_ISR, LS); + val = MAC_GET_VAL(mac_isr, MAC_ISR, LS); if (val == 0) - xgmac_printf("\tMAC_INT_STS: Current Link Status: %s\n", - "LINK OK"); + mac_printf("\tMAC_INT_STS: Current Link Status: %s\n", + "LINK OK"); if (val == 2) - xgmac_printf("\tMAC_INT_STS: Current Link Status: %s\n", - "Local Link Fault"); + mac_printf("\tMAC_INT_STS: Current Link Status: %s\n", + "Local Link Fault"); if (val == 3) - xgmac_printf("\tMAC_INT_STS: Current Link Status: %s\n", - "Remote Link Fault"); + mac_printf("\tMAC_INT_STS: Current Link Status: %s\n", + "Remote Link Fault"); + + xgmac_clear_mac_int(pdev); - xgmac_clear_mac_int(pdata); + return val; } - xgmac_get_mtl_int_sts(pdev); - return 0; + val = xgmac_get_mtl_int_sts(pdev); + return val; } + int xgmac_get_mtl_underflow_pkt_cnt(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); @@ -1047,19 +1057,19 @@ int xgmac_get_mtl_underflow_pkt_cnt(void *pdev) u32 val; mtl_q = XGMAC_RGRD(pdata, MTL_Q_TQUR); - xgmac_printf("XGMAC %d: MTL Underflow Pkt Counter %08x\n", - pdata->mac_idx, mtl_q); + mac_printf("XGMAC %d: MTL Underflow Pkt Counter %08x\n", + pdata->mac_idx, mtl_q); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_TQUR, UFCNTOVF); + val = MAC_GET_VAL(mtl_q, MTL_Q_TQUR, UFCNTOVF); if (val) - xgmac_printf("\t\tOverflow bit of Underflow pkt counter %d\n", - val); + mac_printf("\t\tOverflow bit of Underflow pkt counter %d\n", + val); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_TQUR, UFPKTCNT); + val = MAC_GET_VAL(mtl_q, MTL_Q_TQUR, UFPKTCNT); if (val) - xgmac_printf("\t\tUnerflow packet counter %d\n", val); + mac_printf("\t\tUnerflow packet counter %d\n", val); return 0; } @@ -1071,31 +1081,31 @@ int xgmac_get_mtl_missed_pkt_cnt(void *pdev) u32 val; mtl_q = XGMAC_RGRD(pdata, MTL_Q_RQMPOCR); - xgmac_printf("XGMAC %d: MTL Missed Overflow Pkt Counter %08x\n", - pdata->mac_idx, mtl_q); + mac_printf("XGMAC %d: MTL Missed Overflow Pkt Counter %08x\n", + pdata->mac_idx, mtl_q); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_RQMPOCR, MISCNTOVF); + val = MAC_GET_VAL(mtl_q, MTL_Q_RQMPOCR, MISCNTOVF); if (val) - xgmac_printf("\t\tRx Queue Missed Packet Counter crossed the " - "maximum limit %d\n", val); + mac_printf("\t\tRx Queue Missed Packet Counter crossed the " + "maximum limit %d\n", val); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_RQMPOCR, MISPKTCNT); + val = MAC_GET_VAL(mtl_q, MTL_Q_RQMPOCR, MISPKTCNT); if (val) - xgmac_printf("\t\tNumber of packets missed by XGMAC %d\n", val); + mac_printf("\t\tNumber of packets missed by XGMAC %d\n", val); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_RQMPOCR, OVFCNTOVF); + val = MAC_GET_VAL(mtl_q, MTL_Q_RQMPOCR, OVFCNTOVF); if (val) - xgmac_printf("\t\tRx Queue Overflow Packet Counter field " - "crossed the maximum limit %d\n", val); + mac_printf("\t\tRx Queue Overflow Packet Counter field " + "crossed the maximum limit %d\n", val); - val = XGMAC_GET_BITS(mtl_q, MTL_Q_RQMPOCR, OVFPKTCNT); + val = MAC_GET_VAL(mtl_q, MTL_Q_RQMPOCR, OVFPKTCNT); if (val) - xgmac_printf("\tNo: of packets discarded by the XGMAC %d\n", - val); + mac_printf("\tNo: of packets discarded by the XGMAC %d\n", + val); return 0; } @@ -1109,49 +1119,47 @@ int xgmac_get_mtl_int_sts(void *pdev) mtl_q_isr = XGMAC_RGRD(pdata, MTL_Q_ISR); val = XGMAC_RGRD(pdata, MTL_Q_IER); - xgmac_printf("XGMAC %d: MTL Interrupt Status\n", pdata->mac_idx); + mac_printf("XGMAC %d: MTL Interrupt Status\n", pdata->mac_idx); - xgmac_printf("\tMTL_Q_IER interrupts %s %08x\n", - val ? "ENABLED" : "DISABLED", val); + mac_printf("\tMTL_Q_IER interrupts %s %08x\n", + val ? "ENABLED" : "DISABLED", val); /* Tx Q Overflow Interrupt Enable */ if (val & MASK(MTL_Q_IER, TXUIE)) - xgmac_printf("\t\tTx Q Overflow Interrupt Enabled\n"); + mac_printf("\t\tTx Q Overflow Interrupt Enabled\n"); /* Average bits per slot interrupt enable */ if (val & MASK(MTL_Q_IER, ABPSIE)) - xgmac_printf("\t\tAverage bits per slot interrupt Enabled\n"); + mac_printf("\t\tAverage bits per slot interrupt Enabled\n"); /* Rx Q Overflow Interrupt Enable */ if (val & MASK(MTL_Q_IER, RXOIE)) - xgmac_printf("\t\tRx Q Overflow Interrupt Enabled\n"); + mac_printf("\t\tRx Q Overflow Interrupt Enabled\n"); if (!mtl_q_isr) { - xgmac_printf("\tNo MTL interrupt status available\n"); + mac_printf("\tNo MTL interrupt status available\n"); } else { /* Tx Q Overflow Interrupt Enable */ - val = XGMAC_GET_BITS(mtl_q_isr, MTL_Q_ISR, TXUNFIS); + val = MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, TXUNFIS); if (val) - xgmac_printf("\tTransmit Queue had an Underflow " - "during packet transmission\n"); + mac_printf("\tTransmit Queue had an Underflow " + "during packet transmission\n"); // TODO: Check whether this bit is reserved since traffic class is 1 /* Average bits per slot interrupt enable */ - val = XGMAC_GET_BITS(mtl_q_isr, MTL_Q_ISR, ABPSIS); + val = MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, ABPSIS); if (val) - xgmac_printf("\tMAC has updated the ABS value for " - "Traffic Class 0\n"); + mac_printf("\tMAC has updated the ABS value for " + "Traffic Class 0\n"); /* Rx Q Overflow Interrupt Enable */ - val = XGMAC_GET_BITS(mtl_q_isr, MTL_Q_ISR, RXOVFIS); + val = MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, RXOVFIS); if (val) - xgmac_printf("\tReceive Queue had an Overflow during " - "packet reception\n"); - - xgmac_clear_mtl_int(pdev); + mac_printf("\tReceive Queue had an Overflow during " + "packet reception\n"); } return 0; @@ -1162,14 +1170,14 @@ int xgmac_get_fup_fep_setting(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 fup, fef; - xgmac_printf("XGMAC %d: FUP/FEP Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: FUP/FEP Settings\n", pdata->mac_idx); fup = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, FUP); - xgmac_printf("\tForward Undersized Good Packets for RxQ: %s\n", - fup ? "ENABLE" : "DISABLE"); + mac_printf("\tForward Undersized Good Packets for RxQ: %s\n", + fup ? "ENABLE" : "DISABLE"); fef = XGMAC_RGRD_BITS(pdata, MTL_Q_RQOMR, FEF); - xgmac_printf("\tForward Error Packets for RxQ: %s\n", - fef ? "ENABLE" : "DISABLE"); + mac_printf("\tForward Error Packets for RxQ: %s\n", + fef ? "ENABLE" : "DISABLE"); return 0; } @@ -1182,21 +1190,21 @@ int xgmac_get_ipg(void *pdev) ifp = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, IFP); speed = XGMAC_RGRD_BITS(pdata, MAC_TX_CFG, SS); - xgmac_printf("XGMAC %d: IPG Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: IPG Settings\n", pdata->mac_idx); if (((speed == 3) || (speed == 2)) && (ifp == 0)) { - xgmac_printf("\tGMMI mode Minimum IPG between packets during " - "TX is %d bits\n", (96 - (ipg * 8))); + mac_printf("\tGMMI mode Minimum IPG between packets during " + "TX is %d bits\n", (96 - (ipg * 8))); return 0; } if ((speed == 0) && (ifp == 0)) - xgmac_printf("\tMinimum IPG between packets during TX is %d " - "bits, XGMII mode No reduction possible\n", 96); + mac_printf("\tMinimum IPG between packets during TX is %d " + "bits, XGMII mode No reduction possible\n", 96); if (ifp) - xgmac_printf("\tMinimum IPG between packets during " - "TX is %d bits\n", (96 - (ipg * 32))); + mac_printf("\tMinimum IPG between packets during " + "TX is %d bits\n", (96 - (ipg * 32))); return 0; } @@ -1208,13 +1216,13 @@ int xgmac_get_extcfg(void *pdev) mac_extcfg = XGMAC_RGRD(pdata, MAC_EXTCFG); - val = XGMAC_GET_BITS(mac_extcfg, MAC_EXTCFG, SBDIOEN); - xgmac_printf("XGMAC %d: MAC Extended CFG SGDIOEN: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_extcfg, MAC_EXTCFG, SBDIOEN); + mac_printf("XGMAC %d: MAC Extended CFG SGDIOEN: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); return 0; } -int xgmac_get_pmt(void *pdev) +int xgmac_dbg_pmt(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_pmtcsr, val, i = 0; @@ -1222,38 +1230,38 @@ int xgmac_get_pmt(void *pdev) mac_pmtcsr = XGMAC_RGRD(pdata, MAC_PMT_CSR); - xgmac_printf("XGMAC %d: PMT Settings\n", pdata->mac_idx); + mac_printf("XGMAC %d: PMT Settings\n", pdata->mac_idx); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN); - xgmac_printf("Magic_Packet_Enable: %s\n", - val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN); + mac_printf("Magic_Packet_Enable: %s\n", + val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN); - xgmac_printf("Remote_Wakeup_Packet_Enable: %s\n", - val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN); + mac_printf("Remote_Wakeup_Packet_Enable: %s\n", + val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, PWRDWN); - xgmac_printf("Power_Down: %s\n", - val ? "ENABLED" : "DISABLED"); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, PWRDWN); + mac_printf("Power_Down: %s\n", + val ? "ENABLED" : "DISABLED"); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, MGKPRCVD); - xgmac_printf("Magic_Packet : %s\n", - val ? "Received" : "Not Received"); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, MGKPRCVD); + mac_printf("Magic_Packet : %s\n", + val ? "Received" : "Not Received"); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, RWKPRCVD); - xgmac_printf("Remote_Wakeup_Packet : %s\n", - val ? "Received" : "Not Received"); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPRCVD); + mac_printf("Remote_Wakeup_Packet : %s\n", + val ? "Received" : "Not Received"); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, RWKPTR); - xgmac_printf("Remote_Wakeup_FIFO_Pointer : %d\n", val); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPTR); + mac_printf("Remote_Wakeup_FIFO_Pointer : %d\n", val); - val = XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST); - xgmac_printf("Global_unicast: %d\n", val); + val = MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST); + mac_printf("Global_unicast: %d\n", val); for (i = 0; i < 8; i++) { value[i] = XGMAC_RGRD(pdata, MAC_RWK_PFR); - xgmac_printf("Remote_Wakeup_Packet_REG[%d]: %08x\n", - i, value[i]); + mac_printf("Remote_Wakeup_Packet_REG[%d]: %08x\n", + i, value[i]); } return 0; @@ -1263,104 +1271,105 @@ int xgmac_get_pmt(void *pdev) int xgmac_get_stats_all(void *pdev) { int i = 0; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - for (i = 0; i < 3; i++) { - xgmac_printf("XGMAC %d: Reading rmon\n", i); + for (i = 0; i < pdata->max_mac; i++) { + mac_printf("XGMAC %d: Reading rmon\n", i); xgmac_read_mmc_stats(&prv_data[i], &prv_data[i].mmc_stats); } - xgmac_printf("\nTYPE %s\t%s\t%s\n", " XGMAC 2", " XGMAC 3", " XGMAC 4\n"); + mac_printf("\nTYPE %s\t%s\t%s\n", " XGMAC 2", " XGMAC 3", " XGMAC 4\n"); - xgmac_printf("Rx_Packets = "); + mac_printf("Rx_Packets = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.rxframecount_gb); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.rxframecount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Bytes = "); + mac_printf("Rx_Bytes = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.rxoctetcount_gb); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.rxoctetcount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Byte_errors = "); + mac_printf("Rx_Byte_errors = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", - (prv_data[i].mmc_stats.rxoctetcount_gb - - prv_data[i].mmc_stats.rxoctetcount_g)); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", + (prv_data[i].mmc_stats.rxoctetcount_gb - + prv_data[i].mmc_stats.rxoctetcount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Pauseframe = "); + mac_printf("Rx_Pauseframe = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.rxpauseframes); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.rxpauseframes); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Crc_Errors = "); + mac_printf("Rx_Crc_Errors = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.rxcrcerror); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.rxcrcerror); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Fifo_Errors = "); + mac_printf("Rx_Fifo_Errors = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.rxfifooverflow); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.rxfifooverflow); - xgmac_printf("\n"); - xgmac_printf("\n"); + mac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packets = "); + mac_printf("Tx_Packets = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.txframecount_gb); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.txframecount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Bytes = "); + mac_printf("Tx_Bytes = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.txoctetcount_gb); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.txoctetcount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packet_Errors = "); + mac_printf("Tx_Packet_Errors = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", - (prv_data[i].mmc_stats.txframecount_gb - - prv_data[i].mmc_stats.txframecount_g)); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", + (prv_data[i].mmc_stats.txframecount_gb - + prv_data[i].mmc_stats.txframecount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Byte_Errors = "); + mac_printf("Tx_Byte_Errors = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", - (prv_data[i].mmc_stats.txoctetcount_gb - - prv_data[i].mmc_stats.txoctetcount_g)); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", + (prv_data[i].mmc_stats.txoctetcount_gb - + prv_data[i].mmc_stats.txoctetcount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Pauseframe = "); + mac_printf("Tx_Pauseframe = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.txpauseframes); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.txpauseframes); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_underflow_error = "); + mac_printf("Tx_underflow_error = "); - for (i = 0; i < 3; i++) - xgmac_printf("%11d\t", prv_data[i].mmc_stats.txunderflowerror); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11d\t", prv_data[i].mmc_stats.txunderflowerror); - xgmac_printf("\n"); + mac_printf("\n"); return 0; } @@ -1370,200 +1379,202 @@ int xgmac_get_stats(void *pdev) int i = 0; struct xgmac_mmc_stats *pstats = &pdata->mmc_stats; - xgmac_printf("XGMAC %d: Reading rmon\n", pdata->mac_idx); + mac_printf("XGMAC %d: Reading rmon\n", pdata->mac_idx); xgmac_read_mmc_stats(pdev, pstats); - xgmac_printf("\nTYPE XGMAC %d\n\n", - pdata->mac_idx); - xgmac_printf("Rx_Packets = "); + mac_printf("\nTYPE XGMAC %d\n\n", + pdata->mac_idx); + mac_printf("Rx_Packets = "); - xgmac_printf("%11d\t", pdata->mmc_stats.rxframecount_gb); + mac_printf("%11d\t", pdata->mmc_stats.rxframecount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Bytes = "); + mac_printf("Rx_Bytes = "); - xgmac_printf("%11d\t", pdata->mmc_stats.rxoctetcount_gb); + mac_printf("%11d\t", pdata->mmc_stats.rxoctetcount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Byte_errors = "); + mac_printf("Rx_Byte_errors = "); - xgmac_printf("%11d\t", - (pdata->mmc_stats.rxoctetcount_gb - - pdata->mmc_stats.rxoctetcount_g)); + mac_printf("%11d\t", + (pdata->mmc_stats.rxoctetcount_gb - + pdata->mmc_stats.rxoctetcount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Pauseframe = "); + mac_printf("Rx_Pauseframe = "); - xgmac_printf("%11d\t", pdata->mmc_stats.rxpauseframes); + mac_printf("%11d\t", pdata->mmc_stats.rxpauseframes); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Crc_Errors = "); + mac_printf("Rx_Crc_Errors = "); - xgmac_printf("%11d\t", pdata->mmc_stats.rxcrcerror); + mac_printf("%11d\t", pdata->mmc_stats.rxcrcerror); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Rx_Fifo_Errors = "); + mac_printf("Rx_Fifo_Errors = "); - xgmac_printf("%11d\t", pdata->mmc_stats.rxfifooverflow); + mac_printf("%11d\t", pdata->mmc_stats.rxfifooverflow); - xgmac_printf("\n"); - xgmac_printf("\n"); + mac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packets = "); + mac_printf("Tx_Packets = "); - xgmac_printf("%11d\t", pdata->mmc_stats.txframecount_gb); + mac_printf("%11d\t", pdata->mmc_stats.txframecount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Bytes = "); + mac_printf("Tx_Bytes = "); - xgmac_printf("%11d\t", pdata->mmc_stats.txoctetcount_gb); + mac_printf("%11d\t", pdata->mmc_stats.txoctetcount_gb); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packet_Errors = "); + mac_printf("Tx_Packet_Errors = "); - xgmac_printf("%11d\t", - (pdata->mmc_stats.txframecount_gb - - pdata->mmc_stats.txframecount_g)); + mac_printf("%11d\t", + (pdata->mmc_stats.txframecount_gb - + pdata->mmc_stats.txframecount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Byte_Errors = "); + mac_printf("Tx_Byte_Errors = "); - xgmac_printf("%11d\t", - (pdata->mmc_stats.txoctetcount_gb - - pdata->mmc_stats.txoctetcount_g)); + mac_printf("%11d\t", + (pdata->mmc_stats.txoctetcount_gb - + pdata->mmc_stats.txoctetcount_g)); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Pauseframe = "); + mac_printf("Tx_Pauseframe = "); - xgmac_printf("%11d\t", pdata->mmc_stats.txpauseframes); + mac_printf("%11d\t", pdata->mmc_stats.txpauseframes); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_underflow_error = "); + mac_printf("Tx_underflow_error = "); - xgmac_printf("%11d\t", pdata->mmc_stats.txunderflowerror); + mac_printf("%11d\t", pdata->mmc_stats.txunderflowerror); - xgmac_printf("\n"); + mac_printf("\n"); return 0; } -#else +#endif + +#if defined(PC_UTILITY) && PC_UTILITY int xgmac_get_stats_all(void *pdev) { int i = 0; struct mac_ops *ops; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - for (i = 0; i < 3; i++) { + for (i = 0; i < pdata->max_mac; i++) { ops = gsw_get_mac_ops(0, i); - xgmac_printf("XGMAC %d: Reading rmon\n", i); + mac_printf("XGMAC %d: Reading rmon\n", i); xgmac_read_mmc_stats(ops, &prv_data[i].mmc_stats); } - xgmac_printf("\nTYPE %11s %11s %11s\n", " XGMAC 2", " XGMAC 3", " XGMAC 4\n"); + mac_printf("\nTYPE "); + + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%9s %d", "XGMAC", i); + + mac_printf("\n"); + + mac_printf("Rx_Packets = "); + + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.rxframecount_gb); - xgmac_printf("Rx_Packets = "); + mac_printf("\n"); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.rxframecount_gb, - prv_data[1].mmc_stats.rxframecount_gb, - prv_data[2].mmc_stats.rxframecount_gb); + mac_printf("Rx_Bytes = "); - xgmac_printf("Rx_Bytes = "); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.rxoctetcount_gb); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.rxoctetcount_gb, - prv_data[1].mmc_stats.rxoctetcount_gb, - prv_data[2].mmc_stats.rxoctetcount_gb); + mac_printf("\n"); - xgmac_printf("Rx_Byte_errors = "); + mac_printf("Rx_Byte_errors = "); - xgmac_printf("%11llu %11llu %11llu", - (prv_data[0].mmc_stats.rxoctetcount_gb - - prv_data[0].mmc_stats.rxoctetcount_g), - (prv_data[1].mmc_stats.rxoctetcount_gb - - prv_data[1].mmc_stats.rxoctetcount_g), - (prv_data[2].mmc_stats.rxoctetcount_gb - - prv_data[2].mmc_stats.rxoctetcount_g)); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", + (prv_data[i].mmc_stats.rxoctetcount_gb - + prv_data[i].mmc_stats.rxoctetcount_g)); - xgmac_printf("Rx_Pauseframe = "); + mac_printf("\n"); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.rxpauseframes, - prv_data[1].mmc_stats.rxpauseframes, - prv_data[2].mmc_stats.rxpauseframes); + mac_printf("Rx_Pauseframe = "); - xgmac_printf("Rx_Crc_Errors = "); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.rxpauseframes); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.rxcrcerror, - prv_data[1].mmc_stats.rxcrcerror, - prv_data[2].mmc_stats.rxcrcerror); + mac_printf("\n"); - xgmac_printf("Rx_Fifo_Errors = "); + mac_printf("Rx_Crc_Errors = "); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.rxfifooverflow, - prv_data[1].mmc_stats.rxfifooverflow, - prv_data[2].mmc_stats.rxfifooverflow); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.rxcrcerror); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packets = "); + mac_printf("Rx_Fifo_Errors = "); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.txframecount_gb, - prv_data[1].mmc_stats.txframecount_gb, - prv_data[2].mmc_stats.txframecount_gb); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.rxfifooverflow); - xgmac_printf("Tx_Bytes = "); + mac_printf("\n"); + mac_printf("\n"); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.txoctetcount_gb, - prv_data[1].mmc_stats.txoctetcount_gb, - prv_data[2].mmc_stats.txoctetcount_gb); + mac_printf("Tx_Packets = "); - xgmac_printf("Tx_Packet_Errors = "); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.txframecount_gb); - xgmac_printf("%11llu %11llu %11llu", - (prv_data[0].mmc_stats.txframecount_gb - - prv_data[0].mmc_stats.txframecount_g), - (prv_data[1].mmc_stats.txframecount_gb - - prv_data[1].mmc_stats.txframecount_g), - (prv_data[2].mmc_stats.txframecount_gb - - prv_data[2].mmc_stats.txframecount_g)); + mac_printf("\n"); - xgmac_printf("Tx_Byte_Errors = "); + mac_printf("Tx_Bytes = "); - xgmac_printf("%11llu %11llu %11llu", - (prv_data[0].mmc_stats.txoctetcount_gb - - prv_data[0].mmc_stats.txoctetcount_g), - (prv_data[1].mmc_stats.txoctetcount_gb - - prv_data[1].mmc_stats.txoctetcount_g), - (prv_data[2].mmc_stats.txoctetcount_gb - - prv_data[2].mmc_stats.txoctetcount_g)); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.txoctetcount_gb); - xgmac_printf("Tx_Pauseframe = "); + mac_printf("\n"); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.txpauseframes, - prv_data[1].mmc_stats.txpauseframes, - prv_data[2].mmc_stats.txpauseframes); + mac_printf("Tx_Packet_Errors = "); - xgmac_printf("Tx_underflow_error = "); + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", + (prv_data[i].mmc_stats.txframecount_gb - + prv_data[i].mmc_stats.txframecount_g)); - xgmac_printf("%11llu %11llu %11llu", - prv_data[0].mmc_stats.txunderflowerror, - prv_data[1].mmc_stats.txunderflowerror, - prv_data[2].mmc_stats.txunderflowerror); + mac_printf("\n"); + + mac_printf("Tx_Byte_Errors = "); + + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", + (prv_data[i].mmc_stats.txoctetcount_gb - + prv_data[i].mmc_stats.txoctetcount_g)); + + mac_printf("\n"); + + mac_printf("Tx_Pauseframe = "); + + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.txpauseframes); + + mac_printf("\n"); + + mac_printf("Tx_underflow_error = "); + + for (i = 0; i < pdata->max_mac; i++) + mac_printf("%11llu", prv_data[i].mmc_stats.txunderflowerror); return 0; } @@ -1573,132 +1584,367 @@ int xgmac_get_stats(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); struct xgmac_mmc_stats *pstats = &pdata->mmc_stats; - xgmac_printf("XGMAC %d: Reading rmon\n", pdata->mac_idx); + mac_printf("XGMAC %d: Reading rmon\n", pdata->mac_idx); xgmac_read_mmc_stats(pdev, pstats); - xgmac_printf("\nTYPE XGMAC %d\n\n", - pdata->mac_idx); - xgmac_printf("Rx_Packets = "); + mac_printf("\nTYPE XGMAC %d\n\n", + pdata->mac_idx); + mac_printf("Rx_Packets = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.rxframecount_gb); + mac_printf("%11llu\n", pdata->mmc_stats.rxframecount_gb); + mac_printf("\n"); - xgmac_printf("Rx_Bytes = "); + mac_printf("Rx_Bytes = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.rxoctetcount_gb); + mac_printf("%11llu\n", pdata->mmc_stats.rxoctetcount_gb); + mac_printf("\n"); - xgmac_printf("Rx_Byte_errors = "); + mac_printf("Rx_Byte_errors = "); - xgmac_printf("%11llu\n", - (pdata->mmc_stats.rxoctetcount_gb - - pdata->mmc_stats.rxoctetcount_g)); + mac_printf("%11llu\n", + (pdata->mmc_stats.rxoctetcount_gb - + pdata->mmc_stats.rxoctetcount_g)); + mac_printf("\n"); - xgmac_printf("Rx_Pauseframe = "); + mac_printf("Rx_Pauseframe = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.rxpauseframes); + mac_printf("%11llu\n", pdata->mmc_stats.rxpauseframes); + mac_printf("\n"); - xgmac_printf("Rx_Crc_Errors = "); + mac_printf("Rx_Crc_Errors = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.rxcrcerror); + mac_printf("%11llu\n", pdata->mmc_stats.rxcrcerror); + mac_printf("\n"); - xgmac_printf("Rx_Fifo_Errors = "); + mac_printf("Rx_Fifo_Errors = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.rxfifooverflow); + mac_printf("%11llu\n", pdata->mmc_stats.rxfifooverflow); + mac_printf("\n"); - xgmac_printf("\n"); + mac_printf("\n"); - xgmac_printf("Tx_Packets = "); + mac_printf("Tx_Packets = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.txframecount_gb); + mac_printf("%11llu\n", pdata->mmc_stats.txframecount_gb); + mac_printf("\n"); - xgmac_printf("Tx_Bytes = "); + mac_printf("Tx_Bytes = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.txoctetcount_gb); + mac_printf("%11llu\n", pdata->mmc_stats.txoctetcount_gb); + mac_printf("\n"); - xgmac_printf("Tx_Packet_Errors = "); + mac_printf("Tx_Packet_Errors = "); - xgmac_printf("%11llu\n", - (pdata->mmc_stats.txframecount_gb - - pdata->mmc_stats.txframecount_g)); + mac_printf("%11llu\n", + (pdata->mmc_stats.txframecount_gb - + pdata->mmc_stats.txframecount_g)); + mac_printf("\n"); - xgmac_printf("Tx_Byte_Errors = "); + mac_printf("Tx_Byte_Errors = "); - xgmac_printf("%11llu\n", - (pdata->mmc_stats.txoctetcount_gb - - pdata->mmc_stats.txoctetcount_g)); + mac_printf("%11llu\n", + (pdata->mmc_stats.txoctetcount_gb - + pdata->mmc_stats.txoctetcount_g)); + mac_printf("\n"); - xgmac_printf("Tx_Pauseframe = "); + mac_printf("Tx_Pauseframe = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.txpauseframes); + mac_printf("%11llu\n", pdata->mmc_stats.txpauseframes); + mac_printf("\n"); - xgmac_printf("Tx_underflow_error = "); + mac_printf("Tx_underflow_error = "); - xgmac_printf("%11llu\n", pdata->mmc_stats.txunderflowerror); + mac_printf("%11llu\n", pdata->mmc_stats.txunderflowerror); + mac_printf("\n"); return 0; } #endif +#ifdef __KERNEL__ +int xgmac_get_stats_all(void *pdev) +{ + int i = 0; + struct mac_ops *ops; + static char buf[256] = {'\0'}; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + memset((char *)buf, '\0', 256); + + for (i = 0; i < pdata->max_mac; i++) { + ops = gsw_get_mac_ops(0, i); + mac_printf("XGMAC %d: Reading rmon\n", i); + xgmac_read_mmc_stats(ops, &prv_data[i].mmc_stats); + } + + mac_printf("\nTYPE "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%9s %d\t", "XGMAC", i); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Packets = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.rxframecount_gb); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Bytes = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.rxoctetcount_gb); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Byte_errors = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + (prv_data[i].mmc_stats.rxoctetcount_gb - + prv_data[i].mmc_stats.rxoctetcount_g)); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Pauseframe = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.rxpauseframes); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Crc_Errors = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.rxcrcerror); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Rx_Fifo_Errors = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.rxfifooverflow); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("\n"); + + mac_printf("Tx_Packets = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.txframecount_gb); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Tx_Bytes = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.txoctetcount_gb); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Tx_Packet_Errors = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + (prv_data[i].mmc_stats.txframecount_gb - + prv_data[i].mmc_stats.txframecount_g)); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Tx_Byte_Errors = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + (prv_data[i].mmc_stats.txoctetcount_gb - + prv_data[i].mmc_stats.txoctetcount_g)); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Tx_Pauseframe = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.txpauseframes); + + mac_printf(buf); + + memset((char *)buf, '\0', 256); + + mac_printf("Tx_underflow_error = "); + + for (i = 0; i < pdata->max_mac; i++) + sprintf(buf + strlen(buf), "%11llu\t", + prv_data[i].mmc_stats.txunderflowerror); + + mac_printf(buf); + + return 0; +} + +int xgmac_get_stats(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + struct xgmac_mmc_stats *pstats = &pdata->mmc_stats; + + mac_printf("XGMAC %d: Reading rmon\n", pdata->mac_idx); + + xgmac_read_mmc_stats(pdev, pstats); + + mac_printf("\nTYPE XGMAC %d\n\n", + pdata->mac_idx); + mac_printf("Rx_Packets = "); + + mac_printf("%11llu\n", pdata->mmc_stats.rxframecount_gb); + + mac_printf("Rx_Bytes = "); + + mac_printf("%11llu\n", pdata->mmc_stats.rxoctetcount_gb); + + mac_printf("Rx_Byte_errors = "); + + mac_printf("%11llu\n", + (pdata->mmc_stats.rxoctetcount_gb - + pdata->mmc_stats.rxoctetcount_g)); + + mac_printf("Rx_Pauseframe = "); + + mac_printf("%11llu\n", pdata->mmc_stats.rxpauseframes); + + mac_printf("Rx_Crc_Errors = "); + + mac_printf("%11llu\n", pdata->mmc_stats.rxcrcerror); + + mac_printf("Rx_Fifo_Errors = "); + + mac_printf("%11llu\n", pdata->mmc_stats.rxfifooverflow); + + mac_printf("\n"); + + mac_printf("Tx_Packets = "); + + mac_printf("%11llu\n", pdata->mmc_stats.txframecount_gb); + + mac_printf("Tx_Bytes = "); + + mac_printf("%11llu\n", pdata->mmc_stats.txoctetcount_gb); + + mac_printf("Tx_Packet_Errors = "); + + mac_printf("%11llu\n", + (pdata->mmc_stats.txframecount_gb - + pdata->mmc_stats.txframecount_g)); + + mac_printf("Tx_Byte_Errors = "); + + mac_printf("%11llu\n", + (pdata->mmc_stats.txoctetcount_gb - + pdata->mmc_stats.txoctetcount_g)); + + mac_printf("Tx_Pauseframe = "); + + mac_printf("%11llu\n", pdata->mmc_stats.txpauseframes); + + mac_printf("Tx_underflow_error = "); + + mac_printf("%11llu\n", pdata->mmc_stats.txunderflowerror); + + return 0; +} +#endif + + int xgmac_get_priv_data(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("XGMAC MODULE = %d\n\n", pdata->mac_idx); - xgmac_printf("xgmac_ctrl_reg = %08x\n", pdata->xgmac_ctrl_reg); - xgmac_printf("xgmac_data0_reg = %08x\n", pdata->xgmac_data0_reg); - xgmac_printf("xgmac_data1_reg = %08x\n", pdata->xgmac_data1_reg); - xgmac_printf("tx_q_count = %d\n", pdata->tx_q_count); - xgmac_printf("rx_q_count = %d\n", pdata->rx_q_count); - xgmac_printf("tx_sf_mode = %d\n", pdata->tx_sf_mode); - xgmac_printf("tx_threshold = %d\n", pdata->tx_threshold); - xgmac_printf("rx_sf_mode = %d\n", pdata->rx_sf_mode); - xgmac_printf("rx_threshold = %d\n", pdata->rx_threshold); - xgmac_printf("tx_pause = %d\n", pdata->tx_pause); - xgmac_printf("rx_pause = %d\n", pdata->rx_pause); - xgmac_printf("mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", - pdata->mac_addr[0], - pdata->mac_addr[1], - pdata->mac_addr[2], - pdata->mac_addr[3], - pdata->mac_addr[4], - pdata->mac_addr[5]); - xgmac_printf("tstamp_addend = %d\n", pdata->tstamp_addend); + mac_printf("XGMAC MODULE = %d\n\n", pdata->mac_idx); + mac_printf("xgmac_ctrl_reg = %08x\n", pdata->xgmac_ctrl_reg); + mac_printf("xgmac_data0_reg = %08x\n", pdata->xgmac_data0_reg); + mac_printf("xgmac_data1_reg = %08x\n", pdata->xgmac_data1_reg); + mac_printf("tx_q_count = %d\n", pdata->tx_q_count); + mac_printf("rx_q_count = %d\n", pdata->rx_q_count); + mac_printf("tx_sf_mode = %d\n", pdata->tx_sf_mode); + mac_printf("tx_threshold = %d\n", pdata->tx_threshold); + mac_printf("rx_sf_mode = %d\n", pdata->rx_sf_mode); + mac_printf("rx_threshold = %d\n", pdata->rx_threshold); + mac_printf("tx_pause = %d\n", pdata->tx_pause); + mac_printf("rx_pause = %d\n", pdata->rx_pause); + mac_printf("mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", + pdata->mac_addr[0], + pdata->mac_addr[1], + pdata->mac_addr[2], + pdata->mac_addr[3], + pdata->mac_addr[4], + pdata->mac_addr[5]); + mac_printf("tstamp_addend = %d\n", pdata->tstamp_addend); #if defined(CHIPTEST) && CHIPTEST - xgmac_printf("tx_tstamp = %d\n", pdata->tx_tstamp); + mac_printf("tx_tstamp = %d\n", pdata->tx_tstamp); #else - xgmac_printf("tx_tstamp = %llu\n", pdata->tx_tstamp); + mac_printf("tx_tstamp = %llu\n", pdata->tx_tstamp); #endif - xgmac_printf("promisc_mode = %d\n", pdata->promisc_mode); - xgmac_printf("all_mcast_mode = %d\n", pdata->all_mcast_mode); - xgmac_printf("rfa = %d\n", pdata->rfa); - xgmac_printf("rfd = %d\n", pdata->rfd); - xgmac_printf("tx_mtl_alg = %d\n", pdata->tx_mtl_alg); - xgmac_printf("rx_mtl_alg = %d\n", pdata->rx_mtl_alg); - xgmac_printf("mtu = %d\n", pdata->mtu); - xgmac_printf("pause_time = %d\n", pdata->pause_time); - xgmac_printf("rx_checksum_offload = %d\n", - pdata->rx_checksum_offload); - xgmac_printf("pause_frm_enable = %d\n", pdata->pause_frm_enable); - xgmac_printf("rmon_reset = %d\n", pdata->rmon_reset); - xgmac_printf("reg_off = %d\n", pdata->reg_off); - xgmac_printf("reg_val = %d\n", pdata->reg_val); - xgmac_printf("sec = %d\n", pdata->sec); - xgmac_printf("nsec = %d\n", pdata->nsec); - xgmac_printf("phy_speed = %d\n", pdata->phy_speed); - xgmac_printf("phy_link = %d\n", pdata->phy_link); - xgmac_printf("loopback = %d\n", pdata->loopback); - xgmac_printf("twt = %d\n", pdata->twt); - xgmac_printf("lst = %d\n", pdata->lst); - xgmac_printf("lpitxa = %d\n", pdata->lpitxa); - xgmac_printf("crc_strip = %d\n", pdata->crc_strip); - xgmac_printf("crc_strip_type = %d\n", pdata->crc_strip_type); - xgmac_printf("padcrc_strip = %d\n", pdata->padcrc_strip); - xgmac_printf("dbg_en = %d\n", pdata->dbg_en); - xgmac_printf("dbg_pktie = %d\n", pdata->dbg_pktie); - xgmac_printf("dbg_rst_sel = %d\n", pdata->dbg_rst_sel); - xgmac_printf("dbg_rst_all = %d\n", pdata->dbg_rst_all); - xgmac_printf("fef = %d\n", pdata->fef); - xgmac_printf("fup = %d\n", pdata->fup); + mac_printf("promisc_mode = %d\n", pdata->promisc_mode); + mac_printf("all_mcast_mode = %d\n", pdata->all_mcast_mode); + mac_printf("rfa = %d\n", pdata->rfa); + mac_printf("rfd = %d\n", pdata->rfd); + mac_printf("tx_mtl_alg = %d\n", pdata->tx_mtl_alg); + mac_printf("rx_mtl_alg = %d\n", pdata->rx_mtl_alg); + mac_printf("mtu = %d\n", pdata->mtu); + mac_printf("pause_time = %d\n", pdata->pause_time); + mac_printf("rx_checksum_offload = %d\n", + pdata->rx_checksum_offload); + mac_printf("pause_frm_enable = %d\n", pdata->pause_frm_enable); + mac_printf("rmon_reset = %d\n", pdata->rmon_reset); + mac_printf("reg_off = %d\n", pdata->reg_off); + mac_printf("reg_val = %d\n", pdata->reg_val); + mac_printf("sec = %d\n", pdata->sec); + mac_printf("nsec = %d\n", pdata->nsec); + mac_printf("phy_speed = %d\n", pdata->phy_speed); + mac_printf("phy_link = %d\n", pdata->phy_link); + mac_printf("loopback = %d\n", pdata->loopback); + mac_printf("twt = %d\n", pdata->twt); + mac_printf("lst = %d\n", pdata->lst); + mac_printf("lpitxa = %d\n", pdata->lpitxa); + mac_printf("crc_strip = %d\n", pdata->crc_strip); + mac_printf("crc_strip_type = %d\n", pdata->crc_strip_type); + mac_printf("padcrc_strip = %d\n", pdata->padcrc_strip); + mac_printf("dbg_en = %d\n", pdata->dbg_en); + mac_printf("dbg_pktie = %d\n", pdata->dbg_pktie); + mac_printf("dbg_rst_sel = %d\n", pdata->dbg_rst_sel); + mac_printf("dbg_rst_all = %d\n", pdata->dbg_rst_all); + mac_printf("fef = %d\n", pdata->fef); + mac_printf("fup = %d\n", pdata->fup); return 0; } @@ -1718,248 +1964,248 @@ int xgmac_get_all_hw_features(void *pdev) hw_feat->version = XGMAC_RGRD(pdata, MAC_VR); /* Hardware feature register 0 */ - xgmac_printf("========== Hardware feature register 0 ==============\n"); - hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, GMIISEL); + mac_printf("========== Hardware feature register 0 ==============\n"); + hw_feat->gmii = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, GMIISEL); if (hw_feat->gmii) - xgmac_printf("\t 1Gbps Supported\n"); + mac_printf("\t 1Gbps Supported\n"); - hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, VLHASH); + hw_feat->vlhash = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, VLHASH); if (hw_feat->vlhash) - xgmac_printf("\t Enable Address Filter VLAN Hash Table " - "option is selected.\n"); + mac_printf("\t Enable Address Filter VLAN Hash Table " + "option is selected.\n"); - hw_feat->sma = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, SMASEL); + hw_feat->sma = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, SMASEL); if (hw_feat->sma) - xgmac_printf("\t Enable Station Management Block " - "(MDIO Interface) option is selected.\n"); + mac_printf("\t Enable Station Management Block " + "(MDIO Interface) option is selected.\n"); - hw_feat->rwk = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, RWKSEL); + hw_feat->rwk = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, RWKSEL); if (hw_feat->rwk) - xgmac_printf("\t Enable Remote Wake-Up Packet Detection " - "option is selected\n"); + mac_printf("\t Enable Remote Wake-Up Packet Detection " + "option is selected\n"); - hw_feat->mgk = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, MGKSEL); + hw_feat->mgk = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, MGKSEL); if (hw_feat->mgk) - xgmac_printf("\t Enable Magic Packet Detection option " - "is selected.\n"); + mac_printf("\t Enable Magic Packet Detection option " + "is selected.\n"); - hw_feat->mmc = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, MMCSEL); + hw_feat->mmc = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, MMCSEL); if (hw_feat->mmc) - xgmac_printf("\t Enable XGMAC Management Counter (MMC) option " - "is selected.\n"); + mac_printf("\t Enable XGMAC Management Counter (MMC) option " + "is selected.\n"); - hw_feat->aoe = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, ARPOFFSEL); + hw_feat->aoe = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, ARPOFFSEL); if (hw_feat->aoe) - xgmac_printf("\t Enable IPv4 ARP Offload option " - "is selected\n"); + mac_printf("\t Enable IPv4 ARP Offload option " + "is selected\n"); - hw_feat->ts = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, TSSEL); + hw_feat->ts = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, TSSEL); if (hw_feat->ts) - xgmac_printf("\t Enable IEEE 1588 Timestamp Support option " - "is selected.\n"); + mac_printf("\t Enable IEEE 1588 Timestamp Support option " + "is selected.\n"); - hw_feat->eee = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, EEESEL); + hw_feat->eee = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, EEESEL); if (hw_feat->eee) - xgmac_printf("\t Enable Energy Efficient Ethernet (EEE) option " - "is selected.\n"); + mac_printf("\t Enable Energy Efficient Ethernet (EEE) option " + "is selected.\n"); - hw_feat->tx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, TXCOESEL); + hw_feat->tx_coe = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, TXCOESEL); if (hw_feat->tx_coe) - xgmac_printf("\t Enable Transmit TCP/IP Checksum Offload option" - "is selected.\n"); + mac_printf("\t Enable Transmit TCP/IP Checksum Offload option" + "is selected.\n"); - hw_feat->rx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, RXCOESEL); + hw_feat->rx_coe = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, RXCOESEL); if (hw_feat->rx_coe) - xgmac_printf("\t Enable Receive TCP/IP Checksum Check option" - "is selected.\n"); + mac_printf("\t Enable Receive TCP/IP Checksum Check option" + "is selected.\n"); - hw_feat->addn_mac = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, ADDMACADRSEL); + hw_feat->addn_mac = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, ADDMACADRSEL); if (hw_feat->addn_mac) - xgmac_printf("\t Number of additional MAC addresses " - "selected = %d\n", hw_feat->addn_mac); + mac_printf("\t Number of additional MAC addresses " + "selected = %d\n", hw_feat->addn_mac); - hw_feat->ts_src = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, TSSTSSEL); + hw_feat->ts_src = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, TSSTSSEL); if (hw_feat->ts_src) { if (hw_feat->ts_src == 1) - xgmac_printf("\t Time Stamp time source: INTERNAL\n"); + mac_printf("\t Time Stamp time source: INTERNAL\n"); else if (hw_feat->ts_src == 2) - xgmac_printf("\t Time Stamp time source: EXTERNAL\n"); + mac_printf("\t Time Stamp time source: EXTERNAL\n"); else if (hw_feat->ts_src == 3) - xgmac_printf("\t Time Stamp time source: " - "INTERNAL & EXTERNAL\n"); + mac_printf("\t Time Stamp time source: " + "INTERNAL & EXTERNAL\n"); } else { - xgmac_printf("\t Time Stamp time source: RESERVED\n"); + mac_printf("\t Time Stamp time source: RESERVED\n"); } - hw_feat->sa_vlan_ins = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, SAVLANINS); + hw_feat->sa_vlan_ins = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, SAVLANINS); if (hw_feat->sa_vlan_ins) - xgmac_printf("\t Enable SA and VLAN Insertion on " - "Tx option is selected.\n"); + mac_printf("\t Enable SA and VLAN Insertion on " + "Tx option is selected.\n"); - hw_feat->vxn = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, VXN); + hw_feat->vxn = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, VXN); if (hw_feat->vxn) - xgmac_printf("\t Support for VxLAN/NVGRE is selected\n"); + mac_printf("\t Support for VxLAN/NVGRE is selected\n"); - hw_feat->ediffc = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, EDIFFC); + hw_feat->ediffc = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, EDIFFC); if (hw_feat->ediffc) - xgmac_printf("\t EDMA mode Separate Memory is selected " - "for the Descriptor Cache.\n"); + mac_printf("\t EDMA mode Separate Memory is selected " + "for the Descriptor Cache.\n"); - hw_feat->edma = XGMAC_GET_BITS(mac_hfr0, MAC_HW_F0, EDMA); + hw_feat->edma = MAC_GET_VAL(mac_hfr0, MAC_HW_F0, EDMA); if (hw_feat->edma) - xgmac_printf("\t �Enhanced DMA� option is selected.\n"); + mac_printf("\t �Enhanced DMA� option is selected.\n"); - xgmac_printf("========== Hardware feature register 1 ==============\n"); + mac_printf("========== Hardware feature register 1 ==============\n"); /* Hardware feature register 1 */ hw_feat->rx_fifo_size = - XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, RXFIFOSIZE); + MAC_GET_VAL(mac_hfr1, MAC_HW_F1, RXFIFOSIZE); if (hw_feat->rx_fifo_size) - xgmac_printf("\t Rx Fifo Size %d:%d bytes\n", - hw_feat->rx_fifo_size, - (1 << (hw_feat->rx_fifo_size + 7))); + mac_printf("\t Rx Fifo Size %d:%d bytes\n", + hw_feat->rx_fifo_size, + (1 << (hw_feat->rx_fifo_size + 7))); hw_feat->tx_fifo_size = - XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, TXFIFOSIZE); + MAC_GET_VAL(mac_hfr1, MAC_HW_F1, TXFIFOSIZE); if (hw_feat->tx_fifo_size) - xgmac_printf("\t Tx Fifo Size %d:%d bytes\n", - hw_feat->tx_fifo_size, - (1 << (hw_feat->tx_fifo_size + 7))); + mac_printf("\t Tx Fifo Size %d:%d bytes\n", + hw_feat->tx_fifo_size, + (1 << (hw_feat->tx_fifo_size + 7))); - hw_feat->osten = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, OSTEN); + hw_feat->osten = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, OSTEN); if (hw_feat->osten) - xgmac_printf("\t One Step Timestamping Enabled\n"); + mac_printf("\t One Step Timestamping Enabled\n"); - hw_feat->ptoen = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, PTOEN); + hw_feat->ptoen = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, PTOEN); if (hw_feat->ptoen) - xgmac_printf("\t Enable PTP Timestamp Offload Feature is " - "selected\n"); + mac_printf("\t Enable PTP Timestamp Offload Feature is " + "selected\n"); - hw_feat->adv_ts_hi = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, ADVTHWORD); + hw_feat->adv_ts_hi = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, ADVTHWORD); if (hw_feat->adv_ts_hi) - xgmac_printf("\t Add IEEE 1588 Higher Word Register option is " - "selected.\n"); + mac_printf("\t Add IEEE 1588 Higher Word Register option is " + "selected.\n"); - hw_feat->dma_width = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, ADDR64); + hw_feat->dma_width = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, ADDR64); if (hw_feat->dma_width == 0) - xgmac_printf("\t Dma Width: 32\n"); + mac_printf("\t Dma Width: 32\n"); else if (hw_feat->dma_width == 1) - xgmac_printf("\t Dma Width: 40\n"); + mac_printf("\t Dma Width: 40\n"); else if (hw_feat->dma_width == 2) - xgmac_printf("\t Dma Width: 48\n"); + mac_printf("\t Dma Width: 48\n"); else if (hw_feat->dma_width == 3) - xgmac_printf("\t Dma Width: RESERVED\n"); + mac_printf("\t Dma Width: RESERVED\n"); - hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, DCBEN); + hw_feat->dcb = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, DCBEN); if (hw_feat->dcb) - xgmac_printf("\t Enable Data Center Bridging option is " - "selected.\n"); + mac_printf("\t Enable Data Center Bridging option is " + "selected.\n"); - hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, SPHEN); + hw_feat->sph = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, SPHEN); if (hw_feat->sph) - xgmac_printf("\t Enable Split Header Structure option is " - "selected.\n"); + mac_printf("\t Enable Split Header Structure option is " + "selected.\n"); - hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, TSOEN); + hw_feat->tso = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, TSOEN); if (hw_feat->tso) - xgmac_printf("\t Enable TCP Segmentation Offloading for " - "TCP/IP Packets option is selected.\n"); + mac_printf("\t Enable TCP Segmentation Offloading for " + "TCP/IP Packets option is selected.\n"); - hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, DBGMEMA); + hw_feat->dma_debug = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, DBGMEMA); if (hw_feat->dma_debug) - xgmac_printf("\t Enable Debug Memory Access option is " - "selected.\n"); + mac_printf("\t Enable Debug Memory Access option is " + "selected.\n"); - hw_feat->rss = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, RSSEN); + hw_feat->rss = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, RSSEN); if (hw_feat->rss) - xgmac_printf("\t RSS Feature Enabled\n"); + mac_printf("\t RSS Feature Enabled\n"); - hw_feat->tc_cnt = XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, NUMTC); - xgmac_printf("\t Number of traffic classes selected: %d\n", - (hw_feat->tc_cnt + 1)); + hw_feat->tc_cnt = MAC_GET_VAL(mac_hfr1, MAC_HW_F1, NUMTC); + mac_printf("\t Number of traffic classes selected: %d\n", + (hw_feat->tc_cnt + 1)); hw_feat->hash_table_size = - XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, HASHTBLSZ); + MAC_GET_VAL(mac_hfr1, MAC_HW_F1, HASHTBLSZ); if (hw_feat->hash_table_size) - xgmac_printf("\t Hash table size: %d\n", - (64 << (hw_feat->hash_table_size - 1))); + mac_printf("\t Hash table size: %d\n", + (64 << (hw_feat->hash_table_size - 1))); else - xgmac_printf("\t Hash table size: No hash table selected\n"); + mac_printf("\t Hash table size: No hash table selected\n"); hw_feat->l3l4_filter_num = - XGMAC_GET_BITS(mac_hfr1, MAC_HW_F1, L3L4FNUM); + MAC_GET_VAL(mac_hfr1, MAC_HW_F1, L3L4FNUM); if (hw_feat->l3l4_filter_num) - xgmac_printf("\t Total number of L3 or L4 filters %d\n", - hw_feat->l3l4_filter_num); + mac_printf("\t Total number of L3 or L4 filters %d\n", + hw_feat->l3l4_filter_num); - xgmac_printf("========== Hardware feature register 2 ==============\n"); + mac_printf("========== Hardware feature register 2 ==============\n"); /* Hardware feature register 2 */ - hw_feat->rx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, RXQCNT); - xgmac_printf("\t Number of MTL RX Q: %d\n", (hw_feat->rx_q_cnt + 1)); + hw_feat->rx_q_cnt = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, RXQCNT); + mac_printf("\t Number of MTL RX Q: %d\n", (hw_feat->rx_q_cnt + 1)); - hw_feat->tx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, TXQCNT); - xgmac_printf("\t Number of MTL TX Q: %d\n", (hw_feat->tx_q_cnt + 1)); + hw_feat->tx_q_cnt = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, TXQCNT); + mac_printf("\t Number of MTL TX Q: %d\n", (hw_feat->tx_q_cnt + 1)); - hw_feat->rx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, RXCHCNT); + hw_feat->rx_ch_cnt = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, RXCHCNT); if (hw_feat->rx_ch_cnt) - xgmac_printf("\t Number of DMA Receive channels: %d\n", - (hw_feat->rx_ch_cnt + 1)); + mac_printf("\t Number of DMA Receive channels: %d\n", + (hw_feat->rx_ch_cnt + 1)); - hw_feat->tx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, TXCHCNT); + hw_feat->tx_ch_cnt = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, TXCHCNT); if (hw_feat->tx_ch_cnt) - xgmac_printf("\t Number of DMA transmit channels: %d\n", - (hw_feat->tx_ch_cnt + 1)); + mac_printf("\t Number of DMA transmit channels: %d\n", + (hw_feat->tx_ch_cnt + 1)); - hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, PPSOUTNUM); + hw_feat->pps_out_num = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, PPSOUTNUM); if (hw_feat->pps_out_num) - xgmac_printf("\t Number of PPS outputs %d\n", - hw_feat->pps_out_num); + mac_printf("\t Number of PPS outputs %d\n", + hw_feat->pps_out_num); - hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HW_F2, AUXSNAPNUM); + hw_feat->aux_snap_num = MAC_GET_VAL(mac_hfr2, MAC_HW_F2, AUXSNAPNUM); if (hw_feat->aux_snap_num) { if (hw_feat->aux_snap_num > 4) - xgmac_printf("\t Number of Auxiliary Snapshot Inputs: " - "RESERVED\n"); + mac_printf("\t Number of Auxiliary Snapshot Inputs: " + "RESERVED\n"); else - xgmac_printf("\t Number of Auxiliary Snapshot Inputs: " - "%d\n", hw_feat->aux_snap_num); + mac_printf("\t Number of Auxiliary Snapshot Inputs: " + "%d\n", hw_feat->aux_snap_num); } else { - xgmac_printf("\t No Auxiliary input\n"); + mac_printf("\t No Auxiliary input\n"); } hw_feat->tc_cnt++; @@ -1972,9 +2218,9 @@ int xgmac_get_all_hw_settings(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("\n\n\t\t\tGET ALL SETTINGS for XGMAC %d\n", - pdata->mac_idx); - xgmac_printf("\n"); + mac_printf("\n\n\t\t\tGET ALL SETTINGS for XGMAC %d\n", + pdata->mac_idx); + mac_printf("\n"); xgmac_get_tx_cfg(pdev); xgmac_get_counters_cfg(pdev); xgmac_get_fifo_size(pdev); @@ -1987,7 +2233,7 @@ int xgmac_get_all_hw_settings(void *pdev) xgmac_get_crc_settings(pdev); xgmac_get_eee_settings(pdev); - xgmac_get_eee_status(pdev); + xgmac_dbg_eee_status(pdev); xgmac_get_mac_settings(pdev); xgmac_get_mtu_settings(pdev); @@ -2000,10 +2246,10 @@ int xgmac_get_all_hw_settings(void *pdev) xgmac_get_mac_loopback_mode(pdev); xgmac_get_tstamp_settings(pdev); xgmac_get_debug_sts(pdev); - xgmac_get_int_sts(pdev); + xgmac_dbg_int_sts(pdev); xgmac_get_fup_fep_setting(pdev); xgmac_get_ipg(pdev); - xgmac_get_pmt(pdev); + xgmac_dbg_pmt(pdev); xgmac_get_mac_rxtx_sts(pdev); xgmac_get_mtl_missed_pkt_cnt(pdev); diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mac_api.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mac_api.c index 4c1610bd81954f148d3cecd741adc5b0ccc9a38b..f24b9e6633112380d4b23f34cc24a9377509b314 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mac_api.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mac_api.c @@ -39,9 +39,13 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" -#if defined(KERNEL_MODE) && KERNEL_MODE -#include "xgmac_ptp.h" + +#include <xgmac.h> +#ifdef __KERNEL__ +#include <xgmac_ptp.h> +#include <net/switch_api/gsw_irq.h> +#else +#include <gsw_irq.h> #endif /* LM: Loopback Mode @@ -57,10 +61,10 @@ int xgmac_set_loopback(void *pdev, u32 val) reg_val = XGMAC_RGRD(pdata, MAC_RX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_RX_CFG, LM) != val) { - xgmac_printf("XGMAC %d: LOOPBACK mode: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_RX_CFG, LM, val); + if (MAC_GET_VAL(reg_val, MAC_RX_CFG, LM) != val) { + mac_printf("XGMAC %d: LOOPBACK mode: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_RX_CFG, LM, val); XGMAC_RGWR(pdata, MAC_RX_CFG, reg_val); } @@ -92,10 +96,10 @@ int xgmac_disable_tx_flow_ctl(void *pdev) reg_val = XGMAC_RGRD(pdata, MAC_TX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_TX_FCR, TFE) != 0) { - xgmac_printf("XGMAC %d: Disable TX Flow Control\n", - pdata->mac_idx); - XGMAC_SET_BITS(reg_val, MAC_TX_FCR, TFE, 0); + if (MAC_GET_VAL(reg_val, MAC_TX_FCR, TFE) != 0) { + mac_printf("XGMAC %d: Disable TX Flow Control\n", + pdata->mac_idx); + MAC_SET_VAL(reg_val, MAC_TX_FCR, TFE, 0); XGMAC_RGWR(pdata, MAC_TX_FCR, reg_val); } @@ -109,10 +113,10 @@ int xgmac_disable_rx_flow_ctl(void *pdev) reg_val = XGMAC_RGRD(pdata, MAC_RX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_RX_FCR, RFE) != 0) { - xgmac_printf("XGMAC %d: Disable RX Flow Control\n", - pdata->mac_idx); - XGMAC_SET_BITS(reg_val, MAC_RX_FCR, RFE, 0); + if (MAC_GET_VAL(reg_val, MAC_RX_FCR, RFE) != 0) { + mac_printf("XGMAC %d: Disable RX Flow Control\n", + pdata->mac_idx); + MAC_SET_VAL(reg_val, MAC_RX_FCR, RFE, 0); XGMAC_RGWR(pdata, MAC_RX_FCR, reg_val); } @@ -126,13 +130,13 @@ int xgmac_enable_tx_flow_ctl(void *pdev, u32 pause_time) reg_val = XGMAC_RGRD(pdata, MAC_TX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_TX_FCR, TFE) != 1) { - xgmac_printf("XGMAC %d: Enable TX Flow Control\n", - pdata->mac_idx); + if (MAC_GET_VAL(reg_val, MAC_TX_FCR, TFE) != 1) { + mac_printf("XGMAC %d: Enable TX Flow Control\n", + pdata->mac_idx); /* Enable transmit flow control */ - XGMAC_SET_BITS(reg_val, MAC_TX_FCR, TFE, 1); + MAC_SET_VAL(reg_val, MAC_TX_FCR, TFE, 1); /* Set pause time */ - XGMAC_SET_BITS(reg_val, MAC_TX_FCR, PT, pause_time); + MAC_SET_VAL(reg_val, MAC_TX_FCR, PT, pause_time); XGMAC_RGWR(pdata, MAC_TX_FCR, reg_val); } @@ -147,13 +151,13 @@ int xgmac_enable_rx_flow_ctl(void *pdev) reg_val = XGMAC_RGRD(pdata, MAC_RX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_RX_FCR, RFE) != 1) { - xgmac_printf("XGMAC %d: Enable RX Flow Control\n", - pdata->mac_idx); + if (MAC_GET_VAL(reg_val, MAC_RX_FCR, RFE) != 1) { + mac_printf("XGMAC %d: Enable RX Flow Control\n", + pdata->mac_idx); /* Enable Receive flow control */ - XGMAC_SET_BITS(reg_val, MAC_RX_FCR, RFE, 1); + MAC_SET_VAL(reg_val, MAC_RX_FCR, RFE, 1); // TODO: Need to check whether this is needed - XGMAC_SET_BITS(reg_val, MAC_RX_FCR, PFCE, 0); + MAC_SET_VAL(reg_val, MAC_RX_FCR, PFCE, 0); XGMAC_RGWR(pdata, MAC_RX_FCR, reg_val); } @@ -176,13 +180,13 @@ int xgmac_initiate_pause_tx(void *pdev) reg_val = XGMAC_RGRD(pdata, MAC_TX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_TX_FCR, TFE) == 0) { - xgmac_printf("XGMAC %d: Pause pkt will be txd only if TFE bit is set\n", - pdata->mac_idx); + if (MAC_GET_VAL(reg_val, MAC_TX_FCR, TFE) == 0) { + mac_printf("XGMAC %d: Pause pkt will be txd only if TFE bit is set\n", + pdata->mac_idx); return 0; } - XGMAC_SET_BITS(reg_val, MAC_TX_FCR, FCB, 1); + MAC_SET_VAL(reg_val, MAC_TX_FCR, FCB, 1); /* Initiate Pause TX */ XGMAC_RGWR(pdata, MAC_TX_FCR, reg_val); @@ -190,9 +194,9 @@ int xgmac_initiate_pause_tx(void *pdev) while (1) { reg_val = XGMAC_RGRD(pdata, MAC_TX_FCR); - if (XGMAC_GET_BITS(reg_val, MAC_TX_FCR, FCB) == 0) { - xgmac_printf("XGMAC %d: Pause Pkt Txd complete\n", - pdata->mac_idx); + if (MAC_GET_VAL(reg_val, MAC_TX_FCR, FCB) == 0) { + mac_printf("XGMAC %d: Pause Pkt Txd complete\n", + pdata->mac_idx); break; } } @@ -208,39 +212,73 @@ int xgmac_clear_mac_int(void *pdev) /* Clear all the interrupts which are set */ mac_isr = XGMAC_RGRD(pdata, MAC_ISR); - xgmac_printf("XGMAC %d Clearing MAC ISR registers with %08x\n", - pdata->mac_idx, mac_isr); + mac_printf("XGMAC %d Clearing MAC ISR registers with %08x\n", + pdata->mac_idx, mac_isr); XGMAC_RGWR(pdata, MAC_ISR, mac_isr); return 0; } -int xgmac_set_mac_int(void *pdev, u32 val) +int xgmac_set_mac_int(void *pdev, u32 event, u32 val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - u32 mac_ier = 0; + u32 mac_ier = XGMAC_RGRD(pdata, MAC_IER); + u32 mtl_q_ier = XGMAC_RGRD(pdata, MTL_Q_IER); + switch (event) { /* Enable Timestamp interrupt */ - if (val & MASK(MAC_IER, TSIE)) - XGMAC_SET_BITS(mac_ier, MAC_IER, TSIE, val); + case XGMAC_TSTAMP_EVNT: + MAC_SET_VAL(mac_ier, MAC_IER, TSIE, val); + break; /* Enable LPI interrupt (EEE) */ - if (val & MASK(MAC_IER, LPIIE)) - XGMAC_SET_BITS(mac_ier, MAC_IER, LPIIE, val); + case XGMAC_LPI_EVNT: + MAC_SET_VAL(mac_ier, MAC_IER, LPIIE, val); + break; /* Enable transmit error status interrupt */ - if (val & MASK(MAC_IER, TXESIE)) - XGMAC_SET_BITS(mac_ier, MAC_IER, TXESIE, val); + case XGMAC_TXERR_STS_EVNT: + MAC_SET_VAL(mac_ier, MAC_IER, TXESIE, val); + break; /* Enable Receive error status interrupt */ - if (val & MASK(MAC_IER, RXESIE)) - XGMAC_SET_BITS(mac_ier, MAC_IER, RXESIE, val); + case XGMAC_RXERR_STS_EVNT: + MAC_SET_VAL(mac_ier, MAC_IER, RXESIE, val); + break; /* Enable power management interrupt */ - if (val & MASK(MAC_IER, PMTIE)) - XGMAC_SET_BITS(mac_ier, MAC_IER, PMTIE, val); + case XGMAC_PMT_EVNT: + MAC_SET_VAL(mac_ier, MAC_IER, PMTIE, val); + break; + + /* Tx Q Overflow Interrupt Enable */ + case XGMAC_TXQ_OVFW_EVNT: + MAC_SET_VAL(mtl_q_ier, MTL_Q_IER, TXUIE, val); + break; + + /* Rx Q Overflow Interrupt Enable */ + case XGMAC_RXQ_OVFW_EVNT: + MAC_SET_VAL(mtl_q_ier, MTL_Q_IER, ABPSIE, val); + break; + + /* Average bits per slot interrupt enable */ + case XGMAC_AVG_BPS_EVNT: + MAC_SET_VAL(mtl_q_ier, MTL_Q_IER, RXOIE, val); + break; + + /* Interrupt Enable All */ + case XGMAC_ALL_EVNT: + mac_ier = 0xFFFFFFFF; + mtl_q_ier = 0xFFFFFFFF; + break; + + default: + mac_printf("Unsupported Mac Event\n"); + return GSW_statusErr; + } XGMAC_RGWR(pdata, MAC_IER, mac_ier); + XGMAC_RGWR(pdata, MTL_Q_IER, mtl_q_ier); return 0; } @@ -260,13 +298,13 @@ int xgmac_set_gmii_speed(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, USS) != 0) - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, USS, 0); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, USS) != 0) + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, USS, 0); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, SS) != 0x3) { - xgmac_printf("XGMAC %d: Setting SPEED to GMII 1G\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, SS, 0x3); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, SS) != 0x3) { + mac_printf("XGMAC %d: Setting SPEED to GMII 1G\n", + pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, SS, 0x3); } XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); @@ -279,13 +317,13 @@ int xgmac_set_gmii_2500_speed(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, USS) != 0) - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, USS, 0); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, USS) != 0) + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, USS, 0); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, SS) != 0x2) { - xgmac_printf("XGMAC %d: Setting SPEED to GMII 2.5G\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, SS, 0x2); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, SS) != 0x2) { + mac_printf("XGMAC %d: Setting SPEED to GMII 2.5G\n", + pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, SS, 0x2); } XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); @@ -297,13 +335,13 @@ int xgmac_set_xgmii_2500_speed(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, USS) != 1) - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, USS, 1); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, USS) != 1) + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, USS, 1); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, SS) != 0x2) { - xgmac_printf("XGMAC %d: Setting SPEED to XGMII 2.5G\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, SS, 0x2); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, SS) != 0x2) { + mac_printf("XGMAC %d: Setting SPEED to XGMII 2.5G\n", + pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, SS, 0x2); } XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); @@ -315,13 +353,13 @@ int xgmac_set_xgmii_speed(void *pdev) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, USS) != 0) - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, USS, 0); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, USS) != 0) + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, USS, 0); - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, SS) != 0) { - xgmac_printf("XGMAC %d: Setting SPEED to XGMII 10G\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, SS, 0); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, SS) != 0) { + mac_printf("XGMAC %d: Setting SPEED to XGMII 10G\n", + pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, SS, 0); } XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); @@ -333,17 +371,17 @@ int xgmac_pause_frame_filtering(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_pfr = XGMAC_RGRD(pdata, MAC_PKT_FR); - if (XGMAC_GET_BITS(mac_pfr, MAC_PKT_FR, PCF) != val) { - xgmac_printf("XGMAC %d: Pause filtering %s\n", - pdata->mac_idx, val ? "Enabled" : "Disabled"); + if (MAC_GET_VAL(mac_pfr, MAC_PKT_FR, PCF) != val) { + mac_printf("XGMAC %d: Pause filtering %s\n", + pdata->mac_idx, val ? "Enabled" : "Disabled"); /* Pause filtering */ - XGMAC_SET_BITS(mac_pfr, MAC_PKT_FR, PCF, val); + MAC_SET_VAL(mac_pfr, MAC_PKT_FR, PCF, val); } - if (XGMAC_GET_BITS(mac_pfr, MAC_PKT_FR, RA) == 1) { - xgmac_printf("XGMAC %d: MAC Filter Receive All: DISABLED\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_pfr, MAC_PKT_FR, RA, 0); + if (MAC_GET_VAL(mac_pfr, MAC_PKT_FR, RA) == 1) { + mac_printf("XGMAC %d: MAC Filter Receive All: DISABLED\n", + pdata->mac_idx); + MAC_SET_VAL(mac_pfr, MAC_PKT_FR, RA, 0); } XGMAC_RGWR(pdata, MAC_PKT_FR, mac_pfr); @@ -369,10 +407,10 @@ int xgmac_set_promiscuous_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MAC_PKT_FR); - if (XGMAC_GET_BITS(reg_val, MAC_PKT_FR, PR) != val) { - xgmac_printf("XGMAC %d: %s promiscuous mode\n", - pdata->mac_idx, val ? "Entering" : "Leaving"); - XGMAC_SET_BITS(reg_val, MAC_PKT_FR, PR, val); + if (MAC_GET_VAL(reg_val, MAC_PKT_FR, PR) != val) { + mac_printf("XGMAC %d: %s promiscuous mode\n", + pdata->mac_idx, val ? "Entering" : "Leaving"); + MAC_SET_VAL(reg_val, MAC_PKT_FR, PR, val); XGMAC_RGWR(pdata, MAC_PKT_FR, reg_val); } @@ -391,10 +429,10 @@ int xgmac_set_all_multicast_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MAC_PKT_FR); - if (XGMAC_GET_BITS(reg_val, MAC_PKT_FR, PM) != val) { - XGMAC_SET_BITS(reg_val, MAC_PKT_FR, PM, val); - xgmac_printf("XGMAC %d: %s allmulti mode\n", - pdata->mac_idx, val ? "Entering" : "Leaving"); + if (MAC_GET_VAL(reg_val, MAC_PKT_FR, PM) != val) { + MAC_SET_VAL(reg_val, MAC_PKT_FR, PM, val); + mac_printf("XGMAC %d: %s allmulti mode\n", + pdata->mac_idx, val ? "Entering" : "Leaving"); XGMAC_RGWR(pdata, MAC_PKT_FR, reg_val); } @@ -424,9 +462,9 @@ int xgmac_set_mac_address(void *pdev, u8 *mac_addr) XGMAC_RGWR(pdata, MAC_MACA0HR, mac_addr_hi); if (XGMAC_RGRD(pdata, MAC_MACA0LR) != mac_addr_lo) { - xgmac_printf("XGMAC %d: Setting mac_addr as %08x%04x\n", - pdata->mac_idx, mac_addr_lo, - (mac_addr_hi & 0x0000FFFF)); + mac_printf("XGMAC %d: Setting mac_addr as %08x%04x\n", + pdata->mac_idx, mac_addr_lo, + (mac_addr_hi & 0x0000FFFF)); XGMAC_RGWR(pdata, MAC_MACA0LR, mac_addr_lo); } @@ -453,10 +491,10 @@ int xgmac_set_checksum_offload(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MAC_RX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_RX_CFG, IPC) != val) { - xgmac_printf("XGMAC %d: Setting rx_checksum_offload as %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_RX_CFG, IPC, val); + if (MAC_GET_VAL(reg_val, MAC_RX_CFG, IPC) != val) { + mac_printf("XGMAC %d: Setting rx_checksum_offload as %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_RX_CFG, IPC, val); XGMAC_RGWR(pdata, MAC_RX_CFG, reg_val); } @@ -506,16 +544,16 @@ int xgmac_config_jumbo_pkt(void *pdev, u32 mtu) mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); if (mtu < XGMAC_MAX_GPSL) { /* upto 9018 configuration */ - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, JE, 1); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, WD, 0); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, GPSLCE, 0); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, JD, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, JE, 1); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, WD, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, GPSLCE, 0); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, JD, 0); } else { /* upto 16K configuration */ - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, JE, 0); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, WD, 1); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, GPSLCE, 1); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, GPSL, XGMAC_MAX_SUPPORTED_MTU); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, JD, 1); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, JE, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, WD, 1); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, GPSLCE, 1); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, GPSL, XGMAC_MAX_SUPPORTED_MTU); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, JD, 1); } XGMAC_RGWR(pdata, MAC_RX_CFG, mac_rcr); @@ -533,10 +571,10 @@ int xgmac_config_std_pkt(void *pdev) mac_rcr = XGMAC_RGRD(pdata, MAC_RX_CFG); mac_tcr = XGMAC_RGRD(pdata, MAC_TX_CFG); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, JE, 0); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, WD, 0); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, GPSLCE, 0); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, JD, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, JE, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, WD, 0); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, GPSLCE, 0); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, JD, 0); XGMAC_RGWR(pdata, MAC_RX_CFG, mac_rcr); XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); @@ -571,24 +609,24 @@ int xgmac_powerup(void *pdev) u32 mac_pfr = XGMAC_RGRD(pdata, MAC_PKT_FR); /* Enable MAC Tx */ - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, TE) != 1) { - xgmac_printf("XGMAC %d: MAC TX: ENABLED\n", pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, TE, 1); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, TE) != 1) { + mac_printf("XGMAC %d: MAC TX: ENABLED\n", pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, TE, 1); XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); } /* Enable MAC Rx */ - if (XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, RE) != 1) { - xgmac_printf("XGMAC %d: MAC RX: ENABLED\n", pdata->mac_idx); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, RE, 1); + if (MAC_GET_VAL(mac_rcr, MAC_RX_CFG, RE) != 1) { + mac_printf("XGMAC %d: MAC RX: ENABLED\n", pdata->mac_idx); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, RE, 1); XGMAC_RGWR(pdata, MAC_RX_CFG, mac_rcr); } /* Enable MAC Filter Rx All */ - if (XGMAC_GET_BITS(mac_pfr, MAC_PKT_FR, RA) != 1) { - xgmac_printf("XGMAC %d: MAC Filter Receive All: ENABLED\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_pfr, MAC_PKT_FR, RA, 1); + if (MAC_GET_VAL(mac_pfr, MAC_PKT_FR, RA) != 1) { + mac_printf("XGMAC %d: MAC Filter Receive All: ENABLED\n", + pdata->mac_idx); + MAC_SET_VAL(mac_pfr, MAC_PKT_FR, RA, 1); XGMAC_RGWR(pdata, MAC_PKT_FR, mac_pfr); } @@ -603,24 +641,24 @@ int xgmac_powerdown(void *pdev) u32 mac_pfr = XGMAC_RGRD(pdata, MAC_PKT_FR); /* Disable MAC Tx */ - if (XGMAC_GET_BITS(mac_tcr, MAC_TX_CFG, TE) != 0) { - xgmac_printf("XGMAC %d: MAC TX: DISABLED\n", pdata->mac_idx); - XGMAC_SET_BITS(mac_tcr, MAC_TX_CFG, TE, 0); + if (MAC_GET_VAL(mac_tcr, MAC_TX_CFG, TE) != 0) { + mac_printf("XGMAC %d: MAC TX: DISABLED\n", pdata->mac_idx); + MAC_SET_VAL(mac_tcr, MAC_TX_CFG, TE, 0); XGMAC_RGWR(pdata, MAC_TX_CFG, mac_tcr); } /* Disable MAC Rx */ - if (XGMAC_GET_BITS(mac_rcr, MAC_RX_CFG, RE) != 0) { - xgmac_printf("XGMAC %d: MAC RX: DISABLED\n", pdata->mac_idx); - XGMAC_SET_BITS(mac_rcr, MAC_RX_CFG, RE, 0); + if (MAC_GET_VAL(mac_rcr, MAC_RX_CFG, RE) != 0) { + mac_printf("XGMAC %d: MAC RX: DISABLED\n", pdata->mac_idx); + MAC_SET_VAL(mac_rcr, MAC_RX_CFG, RE, 0); XGMAC_RGWR(pdata, MAC_RX_CFG, mac_rcr); } /* Disable MAC Filter Rx All */ - if (XGMAC_GET_BITS(mac_pfr, MAC_PKT_FR, RA) != 0) { - xgmac_printf("XGMAC %d: MAC Filter Receive All: DISABLED\n", - pdata->mac_idx); - XGMAC_SET_BITS(mac_pfr, MAC_PKT_FR, RA, 0); + if (MAC_GET_VAL(mac_pfr, MAC_PKT_FR, RA) != 0) { + mac_printf("XGMAC %d: MAC Filter Receive All: DISABLED\n", + pdata->mac_idx); + MAC_SET_VAL(mac_pfr, MAC_PKT_FR, RA, 0); XGMAC_RGWR(pdata, MAC_PKT_FR, mac_pfr); } @@ -654,11 +692,11 @@ int xgmac_set_eee_mode(void *pdev, u32 val) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_lpiscr = XGMAC_RGRD(pdata, MAC_LPI_CSR); - if (XGMAC_GET_BITS(mac_lpiscr, MAC_LPI_CSR, LPITXEN) != val) { - xgmac_printf("XGMAC %d: LPI Transmit Enable: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_lpiscr, MAC_LPI_CSR, LPITXA, val); - XGMAC_SET_BITS(mac_lpiscr, MAC_LPI_CSR, LPITXEN, val); + if (MAC_GET_VAL(mac_lpiscr, MAC_LPI_CSR, LPITXEN) != val) { + mac_printf("XGMAC %d: LPI Transmit Enable: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_lpiscr, MAC_LPI_CSR, LPITXA, val); + MAC_SET_VAL(mac_lpiscr, MAC_LPI_CSR, LPITXEN, val); } XGMAC_RGWR(pdata, MAC_LPI_CSR, mac_lpiscr); @@ -673,8 +711,8 @@ u32 xgmac_get_eee_mode(void *pdev) lpitxen = XGMAC_RGRD_BITS(pdata, MAC_LPI_CSR, LPITXEN); - xgmac_printf("\tLPI Transmit Enable: %s\n", - lpitxen ? "ENABLED" : "DISABLED"); + mac_printf("\tLPI Transmit Enable: %s\n", + lpitxen ? "ENABLED" : "DISABLED"); return lpitxen; } @@ -694,10 +732,10 @@ int xgmac_set_eee_pls(void *pdev, u32 val) u32 reg_val = XGMAC_RGRD(pdata, MAC_LPI_CSR); /* Disable MAC Tx */ - if (XGMAC_GET_BITS(reg_val, MAC_LPI_CSR, PLS) != val) { - xgmac_printf("XGMAC %d: Phy link Status: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_LPI_CSR, PLS, val); + if (MAC_GET_VAL(reg_val, MAC_LPI_CSR, PLS) != val) { + mac_printf("XGMAC %d: Phy link Status: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_LPI_CSR, PLS, val); XGMAC_RGWR(pdata, MAC_LPI_CSR, reg_val); } @@ -727,9 +765,9 @@ int xgmac_set_eee_timer(void *pdev, u32 twt, u32 lst) reg_val = XGMAC_RGRD(pdata, MAC_LPI_TCR); /* Waits till the TWT(usec), before starting normal transmission */ - XGMAC_SET_BITS(reg_val, MAC_LPI_TCR, TWT, twt); + MAC_SET_VAL(reg_val, MAC_LPI_TCR, TWT, twt); /* Waits till the LST(msec), before starting to send LPI pattern */ - XGMAC_SET_BITS(reg_val, MAC_LPI_TCR, LST, lst); + MAC_SET_VAL(reg_val, MAC_LPI_TCR, LST, lst); XGMAC_RGWR(pdata, MAC_LPI_TCR, reg_val); @@ -750,10 +788,10 @@ int xgmac_set_crc_strip_type(void *pdev, u32 val) reg_val = XGMAC_RGRD(pdata, MAC_RX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_RX_CFG, CST) != val) { - xgmac_printf("XGMAC %d: CRC stripping for Type packets: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_RX_CFG, CST, val); + if (MAC_GET_VAL(reg_val, MAC_RX_CFG, CST) != val) { + mac_printf("XGMAC %d: CRC stripping for Type packets: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_RX_CFG, CST, val); XGMAC_RGWR(pdata, MAC_RX_CFG, reg_val); } @@ -775,10 +813,10 @@ int xgmac_set_acs(void *pdev, u32 val) reg_val = XGMAC_RGRD(pdata, MAC_RX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_RX_CFG, ACS) != val) { - xgmac_printf("XGMAC %d: Automatic Pad or CRC Stripping: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_RX_CFG, ACS, val); + if (MAC_GET_VAL(reg_val, MAC_RX_CFG, ACS) != val) { + mac_printf("XGMAC %d: Automatic Pad or CRC Stripping: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_RX_CFG, ACS, val); XGMAC_RGWR(pdata, MAC_RX_CFG, reg_val); } @@ -798,10 +836,10 @@ int xgmac_set_ipg(void *pdev, u32 ipg) reg_val = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_TX_CFG, IPG) != ipg) { - xgmac_printf("XGMAC %d: IPG set to %d bytes\n", - pdata->mac_idx, ((96 + (ipg * 32)) / 8)); - XGMAC_SET_BITS(reg_val, MAC_TX_CFG, IPG, ipg); + if (MAC_GET_VAL(reg_val, MAC_TX_CFG, IPG) != ipg) { + mac_printf("XGMAC %d: IPG set to %d bytes\n", + pdata->mac_idx, ((96 + (ipg * 32)) / 8)); + MAC_SET_VAL(reg_val, MAC_TX_CFG, IPG, ipg); XGMAC_RGWR(pdata, MAC_TX_CFG, reg_val); } @@ -829,22 +867,71 @@ int xgmac_set_magic_pmt(void *pdev, u32 val) mac_pmtcsr = XGMAC_RGRD(pdata, MAC_PMT_CSR); - if (XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN) != val) { - xgmac_printf("XGMAC %d: Magic Packet: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN, val); + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN) != val) { + mac_printf("XGMAC %d: Magic Packet: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_pmtcsr, MAC_PMT_CSR, MGKPKTEN, val); } - if (XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, PWRDWN) != val) { - xgmac_printf("XGMAC %d: Power Down Mode: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_pmtcsr, MAC_PMT_CSR, PWRDWN, val); + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, PWRDWN) != val) { + mac_printf("XGMAC %d: Power Down Mode: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_pmtcsr, MAC_PMT_CSR, PWRDWN, val); } XGMAC_RGWR(pdata, MAC_PMT_CSR, mac_pmtcsr); return 0; } +/* Reading MGKPRCVD or RWKPRCVD will clear the XGMAC PMT Interrupt Status */ +int xgmac_pmt_int_clr(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 mac_pmtcsr; + int ret = -1; + + mac_pmtcsr = XGMAC_RGRD(pdata, MAC_PMT_CSR); + + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, MGKPRCVD)) { + mac_printf("XGMAC %d: Clearing Magic packet " + "Interrupt\n", pdata->mac_idx); + ret = 0; + } + + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPRCVD)) { + mac_printf("XGMAC %d: Clearing Remote wakeup packet " + "Interrupt\n", pdata->mac_idx); + ret = 0; + } + + return ret; +} + +/* Reading TLPIEN or RLPIEN will clear the XGMAC LPI Interrupt Status */ +int xgmac_lpi_int_clr(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 varmac_lps; + int ret = -1; + + varmac_lps = XGMAC_RGRD(pdata, MAC_LPI_CSR); + + if (MAC_GET_VAL(varmac_lps, MAC_LPI_CSR, TLPIEN)) { + //mac_printf("XGMAC %d: Clearing LPI TX Interrupt Status\n", + // pdata->mac_idx); + ret = 0; + } + + if (MAC_GET_VAL(varmac_lps, MAC_LPI_CSR, RLPIEN)) { + //mac_printf("XGMAC %d: Clearing LPI RX Interrupt Status\n", + // pdata->mac_idx); + ret = 0; + } + + return ret; +} + + /* RWKPKTEN: Remote Wake-Up Packet Enable * if 1, a power management event is generated when * the MAC receives a remote wake-up packet. @@ -858,16 +945,16 @@ int xgmac_set_rwk_pmt(void *pdev, u32 val) mac_pmtcsr = XGMAC_RGRD(pdata, MAC_PMT_CSR); - if (XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN) != val) { - xgmac_printf("XGMAC %d: Remote Wakeup Packet: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN, val); + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN) != val) { + mac_printf("XGMAC %d: Remote Wakeup Packet: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_pmtcsr, MAC_PMT_CSR, RWKPKTEN, val); } - if (XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, PWRDWN) != val) { - xgmac_printf("XGMAC %d: Power Down Mode: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_pmtcsr, MAC_PMT_CSR, PWRDWN, val); + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, PWRDWN) != val) { + mac_printf("XGMAC %d: Power Down Mode: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_pmtcsr, MAC_PMT_CSR, PWRDWN, val); } XGMAC_RGWR(pdata, MAC_PMT_CSR, mac_pmtcsr); @@ -897,10 +984,10 @@ int xgmac_set_pmt_gucast(void *pdev, u32 val) mac_pmtcsr = XGMAC_RGRD(pdata, MAC_PMT_CSR); - if (XGMAC_GET_BITS(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST) != val) { - xgmac_printf("XGMAC %d: PMT Global Unicast: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST, val); + if (MAC_GET_VAL(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST) != val) { + mac_printf("XGMAC %d: PMT Global Unicast: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(mac_pmtcsr, MAC_PMT_CSR, GLBLUCAST, val); } XGMAC_RGWR(pdata, MAC_PMT_CSR, mac_pmtcsr); @@ -915,11 +1002,11 @@ int xgmac_set_extcfg(void *pdev, u32 val) mac_extcfg = XGMAC_RGRD(pdata, MAC_EXTCFG); - if (XGMAC_GET_BITS(mac_extcfg, MAC_EXTCFG, SBDIOEN) != val) { - xgmac_printf("XGMAC %d: MAC Extended CFG SBDIOEN: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + if (MAC_GET_VAL(mac_extcfg, MAC_EXTCFG, SBDIOEN) != val) { + mac_printf("XGMAC %d: MAC Extended CFG SBDIOEN: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(mac_extcfg, MAC_EXTCFG, SBDIOEN, val); + MAC_SET_VAL(mac_extcfg, MAC_EXTCFG, SBDIOEN, val); XGMAC_RGWR(pdata, MAC_EXTCFG, mac_extcfg); } @@ -934,19 +1021,19 @@ void xgmac_set_mac_rxtx(void *pdev, u32 wd, u32 jd) reg_val = XGMAC_RGRD(pdata, MAC_RX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_RX_CFG, WD) != wd) { - xgmac_printf("XGMAC %d: WD: %s\n", - pdata->mac_idx, wd ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_RX_CFG, WD, wd); + if (MAC_GET_VAL(reg_val, MAC_RX_CFG, WD) != wd) { + mac_printf("XGMAC %d: WD: %s\n", + pdata->mac_idx, wd ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_RX_CFG, WD, wd); XGMAC_RGWR(pdata, MAC_RX_CFG, reg_val); } reg_val = XGMAC_RGRD(pdata, MAC_TX_CFG); - if (XGMAC_GET_BITS(reg_val, MAC_TX_CFG, JD) != jd) { - xgmac_printf("XGMAC %d: JD: %s\n", - pdata->mac_idx, jd ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(reg_val, MAC_TX_CFG, JD, jd); + if (MAC_GET_VAL(reg_val, MAC_TX_CFG, JD) != jd) { + mac_printf("XGMAC %d: JD: %s\n", + pdata->mac_idx, jd ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(reg_val, MAC_TX_CFG, JD, jd); XGMAC_RGWR(pdata, MAC_TX_CFG, reg_val); } } @@ -987,16 +1074,16 @@ int xgmac_set_mac_lpitx(void *pdev, u32 val) lpiate = XGMAC_RGRD(pdata, MAC_LPI_CSR); - if (XGMAC_GET_BITS(lpiate, MAC_LPI_CSR, LPIATE) != val) { - xgmac_printf("XGMAC %d: LPIATE: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(lpiate, MAC_LPI_CSR, LPIATE, val); + if (MAC_GET_VAL(lpiate, MAC_LPI_CSR, LPIATE) != val) { + mac_printf("XGMAC %d: LPIATE: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(lpiate, MAC_LPI_CSR, LPIATE, val); } - if (XGMAC_GET_BITS(lpiate, MAC_LPI_CSR, LPITXA) != val) { - xgmac_printf("XGMAC %d: LPITXA: %s\n", - pdata->mac_idx, val ? "ENABLED" : "DISABLED"); - XGMAC_SET_BITS(lpiate, MAC_LPI_CSR, LPITXA, val); + if (MAC_GET_VAL(lpiate, MAC_LPI_CSR, LPITXA) != val) { + mac_printf("XGMAC %d: LPITXA: %s\n", + pdata->mac_idx, val ? "ENABLED" : "DISABLED"); + MAC_SET_VAL(lpiate, MAC_LPI_CSR, LPITXA, val); } XGMAC_RGWR(pdata, MAC_LPI_CSR, lpiate); @@ -1148,7 +1235,7 @@ u64 xgmac_get_tx_tstamp(void *pdev) /* check whether tstamp of the prev pkt is overwritten with the * tstamp of the cur pkt */ - if (XGMAC_GET_BITS(tx_snr, MAC_TXTSTAMP_NSECR, TXTSSTSMIS)) { + if (MAC_GET_VAL(tx_snr, MAC_TXTSTAMP_NSECR, TXTSSTSMIS)) { /* timesatmp of the current pkt is ignored */ return 0; } @@ -1160,6 +1247,45 @@ u64 xgmac_get_tx_tstamp(void *pdev) return nsec; } +/* This sequence is used to get the number of tx timestamp snapshots captured. + */ +int xgmac_get_txtstamp_cnt(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + u32 tx_sts; + u32 ttsns; + + tx_sts = XGMAC_RGRD(pdata, MAC_TSTAMP_STSR); + + ttsns = MAC_GET_VAL(tx_sts, MAC_TSTAMP_STSR, TTSNS); + mac_printf("\tTx Timestamp Fifo: %d\n", ttsns); + + /* Max Fifo Value*/ + if (ttsns == 16) + mac_printf("XGMAC %d: Tx Timestamp Fifo is Full\n", + pdata->mac_idx); + + return ttsns; +} + +/* This sequence is used to get PktID of Transmitted Packet. + */ +int xgmac_get_txtstamp_pktid(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + u32 tx_sts; + int pktid; + + tx_sts = XGMAC_RGRD(pdata, MAC_TXTSTAMP_STS); + + pktid = MAC_GET_VAL(tx_sts, MAC_TXTSTAMP_STS, PKTID); + mac_printf("\tTx Timestamp PacketID: %d\n", pktid); + + return pktid; +} + + /* TSCTRLSSR:Timestamp Digital or Binary Rollover Control * if 1, the Timestamp Low register rolls over after 0x3B9A_C9FF value * (that is, 1 nanosecond accuracy) and increments @@ -1204,30 +1330,30 @@ int xgmac_config_tstamp(void *pdev, u32 mac_tscr) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); /* Exit if timestamping is not enabled */ - if (!XGMAC_GET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA)) + if (!MAC_GET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA)) return 0; /* Set one nano-second accuracy */ if (pdata->one_nsec_accuracy) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR, 1); else - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR, 0); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSCTRLSSR, 0); /* Set fine timestamp update */ - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSCFUPDT, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSCFUPDT, 1); /* Overwrite earlier timestamps */ - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TXTSSTSM, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TXTSSTSM, 1); XGMAC_RGWR(pdata, MAC_TSTAMP_CR, mac_tscr); -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ #else /* Initialize time registers */ - xgmac_config_subsec_inc(pdata, pdata->ptp_clk); + xgmac_config_subsec_inc(pdev, pdata->ptp_clk); - xgmac_set_tstamp_addend(pdata, pdata->def_addend); - xgmac_init_systime(pdata, pdata->sec, pdata->nsec); + xgmac_set_tstamp_addend(pdev, pdata->def_addend); + xgmac_init_systime(pdev, pdata->sec, pdata->nsec); #endif return 0; @@ -1265,8 +1391,8 @@ int xgmac_disable_tstamp(void *pdev) /* Basically set all bits in MAC_TSTAMP_CR to 0, beloc code is * actually not needed */ - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA, 0); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENALL, 0); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA, 0); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENALL, 0); XGMAC_RGWR(pdata, MAC_TSTAMP_CR, mac_tscr); @@ -1343,7 +1469,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, case HWTSTAMP_TX_ON: pdata->ptp_flgs.ptp_tx_en = 1; - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); break; default: @@ -1359,7 +1485,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, break; case HWTSTAMP_FILTER_ALL: - xgmac_printf("HW tstamp config: Filter All\n"); + mac_printf("HW tstamp config: Filter All\n"); pdata->ptp_flgs.ptp_rx_en |= PTP_RX_EN_ALL; break; @@ -1368,7 +1494,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, pdata->ptp_flgs.ptp_rx_en |= PTP_RX_V2; case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - xgmac_printf("PTP v1, UDP, any kind of event packet\n"); + mac_printf("PTP v1, UDP, any kind of event packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_OVER_IPV4_UDP | PTP_RX_OVER_IPV6_UDP | PTP_RX_SNAP); @@ -1379,7 +1505,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, pdata->ptp_flgs.ptp_rx_en |= PTP_RX_V2; case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - xgmac_printf("PTP v1, UDP, Sync packet\n"); + mac_printf("PTP v1, UDP, Sync packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_OVER_IPV4_UDP | PTP_RX_OVER_IPV6_UDP | PTP_RX_EVNT); @@ -1390,7 +1516,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, pdata->ptp_flgs.ptp_rx_en |= PTP_RX_V2; case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - xgmac_printf("PTP v1, UDP, Delay_req packet\n"); + mac_printf("PTP v1, UDP, Delay_req packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_OVER_IPV4_UDP | PTP_RX_OVER_IPV6_UDP | PTP_RX_EVNT | PTP_RX_MSTR); @@ -1398,7 +1524,7 @@ int xgmac_set_hwtstamp_settings(void *pdev, /* 802.AS1, Ethernet, any kind of event packet */ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - xgmac_printf("802.AS1, Ethernet, any kind of event packet\n"); + mac_printf("802.AS1, Ethernet, any kind of event packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ETH | PTP_RX_SNAP); @@ -1406,14 +1532,14 @@ int xgmac_set_hwtstamp_settings(void *pdev, /* 802.AS1, Ethernet, Sync packet */ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - xgmac_printf("802.AS1, Ethernet, Sync packet\n"); + mac_printf("802.AS1, Ethernet, Sync packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ETH | PTP_RX_EVNT); break; /* 802.AS1, Ethernet, Delay_req packet */ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - xgmac_printf("802.AS1, Ethernet, Delay_req packet\n"); + mac_printf("802.AS1, Ethernet, Delay_req packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ETH | PTP_RX_EVNT | PTP_RX_MSTR); @@ -1421,21 +1547,21 @@ int xgmac_set_hwtstamp_settings(void *pdev, /* PTP v2/802.AS1, any layer, any kind of event packet */ case HWTSTAMP_FILTER_PTP_V2_EVENT: - xgmac_printf("PTP v2/802.AS1,any layer,any kind of event pkt\n"); + mac_printf("PTP v2/802.AS1,any layer,any kind of event pkt\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ANY_LYR | PTP_RX_SNAP); break; /* PTP v2/802.AS1, any layer, Sync packet */ case HWTSTAMP_FILTER_PTP_V2_SYNC: - xgmac_printf("PTP v2/802.AS1, any layer, Sync packet\n"); + mac_printf("PTP v2/802.AS1, any layer, Sync packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ANY_LYR | PTP_RX_EVNT); break; /* PTP v2/802.AS1, any layer, Delay_req packet */ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - xgmac_printf("PTP v2/802.AS1, any layer, Delay_req packet\n"); + mac_printf("PTP v2/802.AS1, any layer, Delay_req packet\n"); pdata->ptp_flgs.ptp_rx_en |= (PTP_RX_V2 | PTP_RX_OVER_ANY_LYR | PTP_RX_EVNT | PTP_RX_MSTR); @@ -1446,65 +1572,65 @@ int xgmac_set_hwtstamp_settings(void *pdev, } if (pdata->ptp_flgs.ptp_rx_en != 0) { - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_V2) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA, 1); if (pdata->ptp_flgs.ptp_rx_en & (PTP_RX_OVER_ANY_LYR | PTP_RX_OVER_IPV4_UDP)) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA, 1); if (pdata->ptp_flgs.ptp_rx_en & (PTP_RX_OVER_ANY_LYR | PTP_RX_OVER_IPV6_UDP)) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_OVER_ETH) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, AV8021ASMEN, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, AV8021ASMEN, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_OVER_ANY_LYR) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPENA, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_EVNT) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_SNAP) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_MSTR) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA, 1); if (pdata->ptp_flgs.ptp_rx_en & PTP_RX_EN_ALL) - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENALL, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENALL, 1); } xgmac_config_tstamp(pdev, mac_tscr); -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ xgmac_config_timer_reg(pdev); #endif return 0; } -void xgmac_onestep_ptp_txtstamp_mode(void *pdev, - u32 snaptypesel, - u32 tsmstrena, - u32 tsevntena) +void xgmac_ptp_txtstamp_mode(void *pdev, + u32 snaptypesel, + u32 tsmstrena, + u32 tsevntena) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 mac_tscr = 0; memset(&pdata->ptp_flgs, 0, sizeof(pdata->ptp_flgs)); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA, 1); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPENA, 1); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA, 1); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA, 1); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL, snaptypesel); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA, tsmstrena); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA, tsevntena); - XGMAC_SET_BITS(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSVER2ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV4ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSIPV6ENA, 1); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, SNAPTYPSEL, snaptypesel); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSEVNTENA, tsevntena); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSMSTRENA, tsmstrena); + MAC_SET_VAL(mac_tscr, MAC_TSTAMP_CR, TSENA, 1); xgmac_config_tstamp(pdev, mac_tscr); } diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_main.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_main.c index 053dabee781a425b68476b88de633d600bafd4bf..192f1fb816db9234010e0f804e1220eb6a878a65 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_main.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_main.c @@ -39,11 +39,12 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" -#include "gswss_mac_api.h" -#include "xgmac_mdio.h" -#include "mac_cfg.h" -#include "lmac_api.h" + +#include <xgmac.h> +#include <gswss_mac_api.h> +#include <xgmac_mdio.h> +#include <mac_cfg.h> +#include <lmac_api.h> static void xgmac_menu(void); static void set_data(u8 *argv[], int i, u32 *start_arg, u32 idx); @@ -62,7 +63,7 @@ struct _xgmac_cfg { char help[1024]; }; -struct mac_prv_data prv_data[3]; +struct mac_prv_data prv_data[10]; struct mac_prv_data pdata; struct _xgmac_cfg xgmac_cfg_table[] = { @@ -128,8 +129,8 @@ struct _xgmac_cfg xgmac_cfg_table[] = { "ts_enable ", cli_set_tstamp_enable, 0, - 0, &pdata.ttse, &pdata.ostc, &pdata.ostc_avail, 0, - "<args 3: 1/0: ttse, 1/0: ostc, 1/0: ostc_vail>" + 0, 0, 0, 0, 0, + "Tx Timestamp Enable" }, { "ts_disable ", @@ -225,7 +226,7 @@ struct _xgmac_cfg xgmac_cfg_table[] = { { "int_en ", cli_set_int, - xgmac_get_int_sts, + xgmac_dbg_int_sts, 0, &pdata.enable_mtl_int, &pdata.enable_mac_int, 0, 0, "<MTL and MAC Interrupt Enable and get status>" }, @@ -345,21 +346,21 @@ struct _xgmac_cfg xgmac_cfg_table[] = { { "magic_pmt ", cli_set_pmt_magic, - xgmac_get_pmt, + xgmac_dbg_pmt, 0, &pdata.magic_pkt_en, 0, 0, 0, "<args 1: 1/0 MAGIC packet enable/disable for PMT>" }, { "rwk_pmt ", cli_set_pmt_rwk, - xgmac_get_pmt, + xgmac_dbg_pmt, 0, &pdata.rwk_pkt_en, 0, 0, 0, "<args 1: 1/0 Remote Wake Up packet enable/disable for PMT>" }, { "gucast_pmt ", cli_set_pmt_gucast, - xgmac_get_pmt, + xgmac_dbg_pmt, 0, &pdata.gucast, 0, 0, 0, "<args 1: 1/0 PMT Global Unicast ENABLE/DISABLE>" }, @@ -398,6 +399,20 @@ struct _xgmac_cfg xgmac_cfg_table[] = { 0, 0, 0, 0, 0, "<Get timestamp status>" }, + { + "txtstamp_cnt ", + 0, + xgmac_get_txtstamp_cnt, + 0, 0, 0, 0, 0, + "<Get txtstamp count>" + }, + { + "txtstamp_pktid ", + 0, + xgmac_get_txtstamp_pktid, + 0, 0, 0, 0, 0, + "<Get txtstamp pktid>" + }, { "linksts ", cli_set_linksts, @@ -553,21 +568,21 @@ void xgmac_menu(void) int num_of_elem = (sizeof(xgmac_cfg_table) / sizeof(struct _xgmac_cfg)); - xgmac_printf("\n MAC SET API's\n\n"); + mac_printf("\n MAC SET API's\n\n"); for (i = 0; i < num_of_elem; i++) { if (xgmac_cfg_table[i].set_func) - xgmac_printf("switch_cli xgmac <0/1/2/* MacIdx> %15s \t %s \n", - xgmac_cfg_table[i].name, - xgmac_cfg_table[i].help); + mac_printf("switch_cli xgmac <0/1/2/* MacIdx> %15s \t %s \n", + xgmac_cfg_table[i].name, + xgmac_cfg_table[i].help); } - xgmac_printf("\n MAC GET API's\n\n"); + mac_printf("\n MAC GET API's\n\n"); for (i = 0; i < num_of_elem; i++) { if (xgmac_cfg_table[i].get_func) - xgmac_printf("switch_cli xgmac <0/1/2/ MacIdx> get %s\n", - xgmac_cfg_table[i].name); + mac_printf("switch_cli xgmac <0/1/2/ MacIdx> get %s\n", + xgmac_cfg_table[i].name); } } @@ -575,8 +590,8 @@ void xgmac_wr_reg(void *pdev, u16 reg_off, u32 reg_val) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + reg_val); XGMAC_RGWR(pdata, reg_off, reg_val); } @@ -587,19 +602,19 @@ u32 xgmac_rd_reg(void *pdev, u16 reg_off) pdata->reg_val = XGMAC_RGRD(pdata, reg_off); - xgmac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, - pdata->reg_val); + mac_printf("\tREG offset: 0x%04x\n\tData: %08X\n", reg_off, + pdata->reg_val); return pdata->reg_val; } -u8 mac_addr2[6] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x02}; -u8 mac_addr3[6] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x04}; -u8 mac_addr4[6] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x06}; +u8 mac_addr[6] = {0x00, 0x00, 0x94, 0x00, 0x00, 0x08}; void xgmac_init_pdata(struct mac_prv_data *pdata, int idx) { +#ifdef __KERNEL__ memset(pdata, 0, sizeof(struct mac_prv_data)); +#endif if (idx == -1) pdata->mac_idx = (pdata - &prv_data[0]); @@ -617,12 +632,8 @@ void xgmac_init_pdata(struct mac_prv_data *pdata, int idx) pdata->rx_sf_mode = 0; pdata->rx_threshold = MTL_RX_THRESHOLD_64; - if (pdata->mac_idx == 0) - memcpy(pdata->mac_addr, mac_addr2, 6); - else if (pdata->mac_idx == 1) - memcpy(pdata->mac_addr, mac_addr3, 6); - else if (pdata->mac_idx == 2) - memcpy(pdata->mac_addr, mac_addr4, 6); + mac_addr[5] = pdata->mac_idx + 1; + memcpy(pdata->mac_addr, mac_addr, 6); pdata->tstamp_addend = 0; pdata->tx_tstamp = 0; @@ -651,11 +662,7 @@ void xgmac_init_pdata(struct mac_prv_data *pdata, int idx) pdata->fef = 1; pdata->mac_en = 1; pdata->ipg = 0; - pdata->enable_mac_int = MASK(MAC_IER, TSIE) | - MASK(MAC_IER, TXESIE) | - MASK(MAC_IER, RXESIE) | - MASK(MAC_IER, LPIIE) | - MASK(MAC_IER, PMTIE); + pdata->enable_mac_int = XGMAC_ALL_EVNT; pdata->enable_mtl_int = MASK(MTL_Q_IER, TXUIE) | MASK(MTL_Q_IER, ABPSIE) | MASK(MTL_Q_IER, RXOIE); @@ -667,6 +674,9 @@ void xgmac_init_pdata(struct mac_prv_data *pdata, int idx) pdata->one_nsec_accuracy = 0; pdata->ss_addr_base = adap_priv_data.ss_addr_base; pdata->lmac_addr_base = LEGACY_MAC_BASE; +#if defined(PC_UTILITY) || defined(CHIPTEST) + pdata->max_mac = MAX_MAC; +#endif } int xgmac_main(u32 argc, u8 *argv[]) @@ -674,6 +684,7 @@ int xgmac_main(u32 argc, u8 *argv[]) u32 i = 0, found = 0; u32 start_arg = 0; int idx = 0; + u32 max_mac; int num_of_elem = (sizeof(xgmac_cfg_table) / sizeof(struct _xgmac_cfg)); @@ -684,19 +695,8 @@ int xgmac_main(u32 argc, u8 *argv[]) prv_data[1].set_all = 0; prv_data[2].set_all = 0; -#if defined(KERNEL_MODE) && KERNEL_MODE start_arg++; start_arg++; -#endif - -#if defined(PC_UTILITY) || defined(CHIPTEST) - start_arg++; -#endif - - if (argc <= 2) { - xgmac_menu(); - goto end; - } #if defined(UPTIME) && UPTIME @@ -734,8 +734,8 @@ int xgmac_main(u32 argc, u8 *argv[]) days = 0; } - xgmac_printf("Uptime(d:h:m:s): %02d:%02d:%02d:%02d\n", - days, hr, min, sec); + mac_printf("Uptime(d:h:m:s): %02d:%02d:%02d:%02d\n", + days, hr, min, sec); goto end; } @@ -754,8 +754,9 @@ int xgmac_main(u32 argc, u8 *argv[]) if (!strcmp(argv[start_arg], "*")) { start_arg++; + max_mac = gsw_get_mac_subifcnt(0); - for (i = 0; i < 3; i++) { + for (i = 0; i < max_mac; i++) { prv_data[i].set_all = 1; ops = gsw_get_mac_ops(0, i); prv_data_k = GET_MAC_PDATA(ops); @@ -766,8 +767,10 @@ int xgmac_main(u32 argc, u8 *argv[]) idx = mac_nstrtoul(argv[start_arg], mac_nstrlen(argv[start_arg]), &start_arg); - if (idx > 2 || idx < 0) { - xgmac_printf("Give valid xgmac index 0/1/2/*\n"); + max_mac = gsw_get_mac_subifcnt(0); + + if ((idx > (max_mac - 1)) || (idx < 0)) { + mac_printf("Give valid xgmac index 0/1/2/*\n"); return -1; } @@ -779,14 +782,14 @@ int xgmac_main(u32 argc, u8 *argv[]) if (!strcmp(argv[start_arg], "r")) { start_arg++; found = 1; -#if defined(PC_UTILITY) || defined(KERNEL_MODE) +#if defined(PC_UTILITY) || defined(__KERNEL__) if ((strstr(argv[start_arg], "0x")) || (strstr(argv[start_arg], "0X"))) - xgmac_printf("matches with 0x\n"); + mac_printf("matches with 0x\n"); else - xgmac_printf("Please give the address with " - "0x firmat\n"); + mac_printf("Please give the address with " + "0x firmat\n"); #endif prv_data_k->reg_off = mac_nstrtoul(argv[start_arg], @@ -801,14 +804,14 @@ int xgmac_main(u32 argc, u8 *argv[]) start_arg++; found = 1; -#if defined(PC_UTILITY) || defined(KERNEL_MODE) +#if defined(PC_UTILITY) || defined(__KERNEL__) if ((strstr(argv[start_arg], "0x")) || (strstr(argv[start_arg], "0X"))) - xgmac_printf("matches with 0x\n"); + mac_printf("matches with 0x\n"); else - xgmac_printf("Please give the address with " - "0x format\n"); + mac_printf("Please give the address with " + "0x format\n"); #endif prv_data_k->reg_off = mac_nstrtoul(argv[start_arg], @@ -847,27 +850,16 @@ int xgmac_main(u32 argc, u8 *argv[]) if (!strcmp(xgmac_cfg_table[i].name, argv[start_arg])) { start_arg++; -#ifdef SWITCH_SERVER - - if (argc != xgmac_cfg_table[i].args - 1) { - xgmac_printf("[USAGE:]\n"); - xgmac_printf("xgmac <idx> %s %s\n", - xgmac_cfg_table[i].name, - xgmac_cfg_table[i].help); - return 0; - } - -#else if (argc != xgmac_cfg_table[i].args) { - xgmac_printf("[USAGE:]\n"); - xgmac_printf("xgmac <idx> %s %s\n", - xgmac_cfg_table[i].name, - xgmac_cfg_table[i].help); + mac_printf("[USAGE:]\n"); + mac_printf("xgmac <idx> %s %s\n", + xgmac_cfg_table[i].name, + xgmac_cfg_table[i].help); return 0; } -#endif + set_data(argv, i, &start_arg, idx); if (xgmac_cfg_table[i].set_func) @@ -881,8 +873,8 @@ int xgmac_main(u32 argc, u8 *argv[]) end: if (found == 0) - xgmac_printf("command entered is invalid, use help to " - "display the supported cmds\n"); + mac_printf("command entered is invalid, use help to " + "display the supported cmds\n"); return 0; } @@ -916,6 +908,7 @@ void set_all_pdata(u8 *arg, u32 *data, u32 *start_arg) u32 val; struct mac_ops *ops; struct mac_prv_data *mac_priv_data; + u32 max_mac = gsw_get_mac_subifcnt(0); if (data) { offset = (u8 *)(data) - (u8 *)&pdata; @@ -923,8 +916,8 @@ void set_all_pdata(u8 *arg, u32 *data, u32 *start_arg) *data = val; - for (j = 0; j < 3; j++) { -#if defined(KERNEL_MODE) && KERNEL_MODE + for (j = 0; j < max_mac; j++) { +#ifdef __KERNEL__ ops = gsw_get_mac_ops(0, j); if (ops) { @@ -953,7 +946,7 @@ void set_pdata(u8 *arg, u32 idx, u32 *data, u32 *start_arg) *data = val; -#if defined(KERNEL_MODE) && KERNEL_MODE +#ifdef __KERNEL__ ops = gsw_get_mac_ops(0, idx); if (ops) { @@ -974,11 +967,8 @@ void xgmac_cli_init(void) for (i = 0; i < num_of_elem; i++) { removeSpace(xgmac_cfg_table[i].name); -#if defined(KERNEL_MODE) && KERNEL_MODE + xgmac_cfg_table[i].args = 4; -#else - xgmac_cfg_table[i].args = 3; -#endif if (xgmac_cfg_table[i].data1) xgmac_cfg_table[i].args += 1; @@ -994,121 +984,6 @@ void xgmac_cli_init(void) } } -int xgmac_init(void *pdev) -{ - struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - -#if defined(PC_UTILITY) || defined(CHIPTEST) - xgmac_init_pdata(pdata, -1); -#endif - xgmac_cli_init(); - - xgmac_printf("XGMAC INIT for Module %d\n", pdata->mac_idx); - - /* Initialize MAC related features */ - - /* Program MAC Address */ - xgmac_set_mac_address(pdev, pdata->mac_addr); - - /* Program for Jumbo/Std settings */ - mac_set_mtu(pdev, pdata->mtu); - - /* Enable MAC interrupts */ - xgmac_set_mac_int(pdev, pdata->enable_mac_int); - - /* Configure RWK filter frames */ - populate_filter_frames(pdev); - - xgmac_set_extcfg(pdev, 1); - - /* Program Promisc mode and All multicast mode */ - xgmac_set_promiscuous_mode(pdev, pdata->promisc_mode); - - /* Program All multicast mode */ - xgmac_set_all_multicast_mode(pdev, pdata->all_mcast_mode); - - /* Configure MAC Speed to 10/2.5/1 G */ - mac_set_physpeed(pdev, pdata->phy_speed); - - /* Default enable flow control Rx and TX */ - mac_set_flowctrl(pdev, 3); - - /* Set the link status as UP */ - mac_set_linksts(pdev, GSW_PORT_LINK_UP); - - /* Set the Duplex as Full Duplex */ - mac_set_duplex(pdev, GSW_DUPLEX_FULL); - - /* Set LPI TX Automate and LPI Auto Timer Enable to - * overcome packet-drop issue - */ - xgmac_set_mac_lpitx(pdev, 1); - -#if defined(UPTIME) && UPTIME - - if (pdata->mac_idx == 0) - xgmac_set_hwtstamp_settings(pdev, 1, 1); - -#endif - /* POWER ON MAC Tx/Rx */ - xgmac_powerup(pdev); - - /* Filter pause frames from XGMAC */ - xgmac_pause_frame_filtering(pdev, 1); - - return 0; -} - -/* TRCSTS: MTL Tx Queue Read Controller Status - * This field indicates the state of the Tx Queue Read Controller: - * 00 Idle state - * 01 Read state (transferring data to the MAC transmitter) - * 10 Waiting for pending Tx Status from the MAC transmitter - * 11 Flushing the Tx queue because of the Packet Abort request from - * the MAC - * TXQSTS: MTL Tx Queue Not Empty Status - * if 1, it indicates that the MTL Tx Queue is not empty - * and some data is left for transmission. - * PRXQ: Number of Packets in Receive Queue - * This field indicates the current number of packets in the Rx Queue. The - * theoretical maximum value for this field is 256KB/16B = 16K Packets, - * that is, Max_Queue_Size/Min_Packet_Size. - * RXQSTS: MTL Rx Queue Fill-Level Status - * This field gives the status of the fill-level of the Rx Queue: - * 00 Rx Queue empty - * 01 Rx Queue fill-level below flow-control deactivate threshold - * 10 Rx Queue fill-level above flow-control activate threshold - * 11 Rx Queue full - */ -int xgmac_exit(void *pdev) -{ - u32 mtl_tx_debugq, trcsts, txqsts; - u32 mtl_rx_debugq, prxq, rxqsts; - struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - - mtl_tx_debugq = XGMAC_RGRD(pdata, MTL_Q_TQDG); - trcsts = XGMAC_GET_BITS(mtl_tx_debugq, MTL_Q_TQDG, TRCSTS); - txqsts = XGMAC_GET_BITS(mtl_tx_debugq, MTL_Q_TQDG, TXQSTS); - - if ((trcsts != 1) && (txqsts == 0)) { - xgmac_printf("XGMAC EXIT for Module %d\n", pdata->mac_idx); - /* POWER OFF MAC Tx/Rx */ - xgmac_powerdown(pdev); - } else - xgmac_printf("Can't Exit XGMAC %d now,data is left for txing\n", - pdata->mac_idx); - - mtl_rx_debugq = XGMAC_RGRD(pdata, MTL_Q_RQDG); - prxq = XGMAC_GET_BITS(mtl_tx_debugq, MTL_Q_RQDG, PRXQ); - rxqsts = XGMAC_GET_BITS(mtl_tx_debugq, MTL_Q_RQDG, RXQSTS); - - if ((prxq == 0) && (rxqsts == 0)) - xgmac_printf("All Data is transferred to system memory\n"); - else - xgmac_printf("ERROR: Data is still txing to system memory\n"); - - return 0; -} #if defined(PC_UTILITY) || defined(CHIPTEST) struct mac_ops *gsw_get_mac_ops(u32 devid, u32 mac_idx) @@ -1116,4 +991,8 @@ struct mac_ops *gsw_get_mac_ops(u32 devid, u32 mac_idx) return &(prv_data[mac_idx].ops); } +u32 gsw_get_mac_subifcnt(u32 devid) +{ + return MAX_MAC; +} #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.c index c295d1dfc9285f707951920c9b94400740b0673a..3fe77066b85c573cdaf1b3beb1d89c2fa53ee345 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.c @@ -39,8 +39,15 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac_mdio.h" -#include "xgmac.h" + +#include <xgmac_mdio.h> +#include <xgmac.h> +#ifdef __KERNEL__ +#include <linux/phy.h> +#include <linux/mdio.h> +#endif + +static void dump_phy_registers(void *pdev); /* SCAR: * DA @@ -89,18 +96,18 @@ int xgmac_mdio_single_rd(void *pdev, mdio_scar = XGMAC_RGRD(pdata, MDIO_SCAR); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, DA, dev_adr); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, PA, phy_id); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, RA, phy_reg); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, DA, dev_adr); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, PA, phy_id); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, RA, phy_reg); XGMAC_RGWR(pdata, MDIO_SCAR, mdio_scar); mdio_sccdr = XGMAC_RGRD(pdata, MDIO_SCCDR); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, BUSY, 1); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, SADDR, 0); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, CMD, 3); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, SDATA, 0); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, BUSY, 1); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, SADDR, 0); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, CMD, 3); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, SDATA, 0); XGMAC_RGWR(pdata, MDIO_SCCDR, mdio_sccdr); @@ -117,7 +124,7 @@ int xgmac_mdio_single_rd(void *pdev, /* read the data */ mdio_sccdr = XGMAC_RGRD(pdata, MDIO_SCCDR); - *phy_reg_data = XGMAC_GET_BITS(mdio_sccdr, MDIO_SCCDR, SDATA); + *phy_reg_data = MAC_GET_VAL(mdio_sccdr, MDIO_SCCDR, SDATA); return 0; } @@ -134,20 +141,20 @@ void print_mdio_rd_cnt(void *pdev, u32 i, phy_reg_data; clause = mdio_get_clause(pdata, phy_id); - xgmac_printf("OP \tCL \tDEVADR\tPHYID \tPHYREG\tDATA \n"); - xgmac_printf("============================================\n"); + mac_printf("OP \tCL \tDEVADR\tPHYID \tPHYREG\tDATA \n"); + mac_printf("============================================\n"); for (i = 0; i <= (phy_reg_end - phy_reg_st); i++) { xgmac_mdio_single_rd(pdev, dev_adr, phy_id, phy_reg_st + i, &phy_reg_data); - xgmac_printf("%s\t", "RD"); - xgmac_printf("%4s\t", clause ? "CL22" : "CL45"); - xgmac_printf("%6X\t", dev_adr); - xgmac_printf("%5X\t", phy_id); - xgmac_printf("%6X\t", phy_reg_st + i); - xgmac_printf("%4X\t", phy_reg_data); - xgmac_printf("\n"); + mac_printf("%s\t", "RD"); + mac_printf("%4s\t", clause ? "CL22" : "CL45"); + mac_printf("%6X\t", dev_adr); + mac_printf("%5X\t", phy_id); + mac_printf("%6X\t", phy_reg_st + i); + mac_printf("%4X\t", phy_reg_data); + mac_printf("\n"); } } @@ -162,16 +169,16 @@ void xgmac_print_mdio(void *pdev, int clause; clause = mdio_get_clause(pdev, phy_id); - xgmac_printf("OP \tCL \tDEVADR\tPHYID \tPHYREG\tDATA \n"); - xgmac_printf("============================================\n"); - - xgmac_printf("%6s\t", "RD"); - xgmac_printf("%6s\t", clause ? "CL22" : "CL45"); - xgmac_printf("%6X\t", dev_adr); - xgmac_printf("%6X\t", phy_id); - xgmac_printf("%6X\t", phy_reg); - xgmac_printf("%6X\t", phy_reg_data); - xgmac_printf("\n"); + mac_printf("OP \tCL \tDEVADR\tPHYID \tPHYREG\tDATA \n"); + mac_printf("============================================\n"); + + mac_printf("%6s\t", "RD"); + mac_printf("%6s\t", clause ? "CL22" : "CL45"); + mac_printf("%6X\t", dev_adr); + mac_printf("%6X\t", phy_id); + mac_printf("%6X\t", phy_reg); + mac_printf("%6X\t", phy_reg_data); + mac_printf("\n"); } /*brief This sequence is used to write into phy registers @@ -196,18 +203,18 @@ int xgmac_mdio_single_wr(void *pdev, mdio_scar = XGMAC_RGRD(pdata, MDIO_SCAR); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, DA, dev_adr); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, PA, phy_id); - XGMAC_SET_BITS(mdio_scar, MDIO_SCAR, RA, phy_reg); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, DA, dev_adr); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, PA, phy_id); + MAC_SET_VAL(mdio_scar, MDIO_SCAR, RA, phy_reg); XGMAC_RGWR(pdata, MDIO_SCAR, mdio_scar); mdio_sccdr = XGMAC_RGRD(pdata, MDIO_SCCDR); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, SDATA, phy_reg_data); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, BUSY, 1); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, SADDR, 0); - XGMAC_SET_BITS(mdio_sccdr, MDIO_SCCDR, CMD, 1); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, SDATA, phy_reg_data); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, BUSY, 1); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, SADDR, 0); + MAC_SET_VAL(mdio_sccdr, MDIO_SCCDR, CMD, 1); XGMAC_RGWR(pdata, MDIO_SCCDR, mdio_sccdr); @@ -238,8 +245,8 @@ int mdio_set_clause(void *pdev, u32 clause, u32 phy_id) SET_N_BITS(mdio_c22p, phy_id, MDIO_CL22P_PORT0_WIDTH, clause); - xgmac_printf("MDIO: phy id %d set to %s\n", phy_id, - clause ? "Clause 22" : "Clause 45"); + mac_printf("MDIO: portID %d set to %s\n", phy_id, + clause ? "Clause 22" : "Clause 45"); /* Select port 0, 1, 2 and 3 as Clause 22/45 ports */ XGMAC_RGWR(pdata, MDIO_C22P, mdio_c22p); @@ -266,46 +273,46 @@ int mdio_set_interrupt(void *pdev, u32 val) u32 mdio_ier = 0; if (val & MASK(MDIO_IER, CWCOMPIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, CWCOMPIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, CWCOMPIE, val); if (val & MASK(MDIO_IER, SNGLCOMPIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, SNGLCOMPIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, SNGLCOMPIE, val); if (val & MASK(MDIO_IER, PRT3ALIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT3ALIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT3ALIE, val); if (val & MASK(MDIO_IER, PRT2ALIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT2ALIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT2ALIE, val); if (val & MASK(MDIO_IER, PRT1ALIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT1ALIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT1ALIE, val); if (val & MASK(MDIO_IER, PRT0ALIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT0ALIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT0ALIE, val); if (val & MASK(MDIO_IER, PRT3LSIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT3LSIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT3LSIE, val); if (val & MASK(MDIO_IER, PRT2LSIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT2LSIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT2LSIE, val); if (val & MASK(MDIO_IER, PRT1LSIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT1LSIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT1LSIE, val); if (val & MASK(MDIO_IER, PRT0LSIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT0LSIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT0LSIE, val); if (val & MASK(MDIO_IER, PRT3CONIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT3CONIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT3CONIE, val); if (val & MASK(MDIO_IER, PRT2CONIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT2CONIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT2CONIE, val); if (val & MASK(MDIO_IER, PRT1CONIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT1CONIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT1CONIE, val); if (val & MASK(MDIO_IER, PRT0CONIE)) - XGMAC_SET_BITS(mdio_ier, MDIO_IER, PRT0CONIE, val); + MAC_SET_VAL(mdio_ier, MDIO_IER, PRT0CONIE, val); XGMAC_RGWR(pdata, MDIO_IER, mdio_ier); @@ -318,101 +325,352 @@ int xgmac_mdio_get_int_sts(void *pdev) u32 mdio_isr = XGMAC_RGRD(pdata, MDIO_ISR); u32 mdio_ier = XGMAC_RGRD(pdata, MDIO_IER); - xgmac_printf("XGMAC %d: MDIO Interrupt Status\n", pdata->mac_idx); - xgmac_printf("\tMDIO_IER interrupts %s %08x\n", - mdio_ier ? "ENABLED" : "DISABLED", mdio_ier); + mac_printf("XGMAC %d: MDIO Interrupt Status\n", pdata->mac_idx); + mac_printf("\tMDIO_IER interrupts %s %08x\n", + mdio_ier ? "ENABLED" : "DISABLED", mdio_ier); if (mdio_ier & MASK(MDIO_IER, CWCOMPIE)) - xgmac_printf("Continuous Write Completion Interrupt Enabled\n"); + mac_printf("Continuous Write Completion Interrupt Enabled\n"); if (mdio_ier & MASK(MDIO_IER, SNGLCOMPIE)) - xgmac_printf("Single Command Completion Interrupt Enabled\n"); + mac_printf("Single Command Completion Interrupt Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT3ALIE)) - xgmac_printf("Dev Present Sts Change Interrupt P3 Enabled\n"); + mac_printf("Dev Present Sts Change Interrupt P3 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT2ALIE)) - xgmac_printf("Dev Present Sts Change Interrupt P2 Enabled\n"); + mac_printf("Dev Present Sts Change Interrupt P2 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT1ALIE)) - xgmac_printf("Dev Present Sts Change Interrupt P1 Enabled\n"); + mac_printf("Dev Present Sts Change Interrupt P1 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT0ALIE)) - xgmac_printf("Dev Present Sts Change Interrupt P0 Enabled\n"); + mac_printf("Dev Present Sts Change Interrupt P0 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT3LSIE)) - xgmac_printf("Link Status Change Interrupt P3 Enabled\n"); + mac_printf("Link Status Change Interrupt P3 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT2LSIE)) - xgmac_printf("Link Status Change Interrupt P2 Enabled\n"); + mac_printf("Link Status Change Interrupt P2 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT1LSIE)) - xgmac_printf("Link Status Change Interrupt P1 Enabled\n"); + mac_printf("Link Status Change Interrupt P1 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT0LSIE)) - xgmac_printf("Link Status Change Interrupt P0 Enabled\n"); + mac_printf("Link Status Change Interrupt P0 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT3CONIE)) - xgmac_printf("Connect/Disconnect Event Interrupt P3 Enabled\n"); + mac_printf("Connect/Disconnect Event Interrupt P3 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT2CONIE)) - xgmac_printf("Connect/Disconnect Event Interrupt P2 Enabled\n"); + mac_printf("Connect/Disconnect Event Interrupt P2 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT1CONIE)) - xgmac_printf("Connect/Disconnect Event Interrupt P1 Enabled\n"); + mac_printf("Connect/Disconnect Event Interrupt P1 Enabled\n"); if (mdio_ier & MASK(MDIO_IER, PRT0CONIE)) - xgmac_printf("Connect/Disconnect Event Interrupt P0 Enabled\n"); + mac_printf("Connect/Disconnect Event Interrupt P0 Enabled\n"); if (!mdio_isr) { - xgmac_printf("\tNo MDIO interrupt status available %08x\n", - mdio_isr); + mac_printf("\tNo MDIO interrupt status available %08x\n", + mdio_isr); } else { - xgmac_printf("\tMDIO interrupt status available %08x\n", - mdio_isr); + mac_printf("\tMDIO interrupt status available %08x\n", + mdio_isr); if (mdio_isr & MASK(MDIO_ISR, CWCOMPINT)) - xgmac_printf("Continuous WR Completion Int Set\n"); + mac_printf("Continuous WR Completion Int Set\n"); if (mdio_isr & MASK(MDIO_ISR, SNGLCOMPINT)) - xgmac_printf("Single Cmd Completion Int Set\n"); + mac_printf("Single Cmd Completion Int Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT3ALINT)) - xgmac_printf("Dev Present Sts Change Int P3 Set\n"); + mac_printf("Dev Present Sts Change Int P3 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT2ALINT)) - xgmac_printf("Dev Present Sts Change Int P2 Set\n"); + mac_printf("Dev Present Sts Change Int P2 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT1ALINT)) - xgmac_printf("Dev Present Sts Change Int P1 Set\n"); + mac_printf("Dev Present Sts Change Int P1 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT0ALINT)) - xgmac_printf("Dev Present Sts Change Int P0 Set\n"); + mac_printf("Dev Present Sts Change Int P0 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT3LSINT)) - xgmac_printf("Link Sts Change Int P3 Set\n"); + mac_printf("Link Sts Change Int P3 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT2LSINT)) - xgmac_printf("Link Sts Change Int P2 Set\n"); + mac_printf("Link Sts Change Int P2 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT1LSINT)) - xgmac_printf("Link Sts Change Int P1 Set\n"); + mac_printf("Link Sts Change Int P1 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT0LSINT)) - xgmac_printf("Link Sts Change Int P0 Set\n"); + mac_printf("Link Sts Change Int P0 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT3CONINT)) - xgmac_printf("Connect/Disconnect Event Int P3 Set\n"); + mac_printf("Connect/Disconnect Event Int P3 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT2CONINT)) - xgmac_printf("Connect/Disconnect Event Int P2 Set\n"); + mac_printf("Connect/Disconnect Event Int P2 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT1CONINT)) - xgmac_printf("Connect/Disconnect Event Int P1 Set\n"); + mac_printf("Connect/Disconnect Event Int P1 Set\n"); if (mdio_isr & MASK(MDIO_ISR, PRT0CONINT)) - xgmac_printf("Connect/Disconnect Event Int P0 Set\n"); + mac_printf("Connect/Disconnect Event Int P0 Set\n"); } return 0; } +#ifdef __KERNEL__ +/* API to read MII PHY register +* \details This API is expected to write MII registers with the value being +* passed as the last argument which is done in write_phy_regs API +* called by this function. +* +* \param[in] bus - points to the mii_bus structure +* \param[in] phyadr - the phy address to write +* \param[in] phyreg - the phy register offset to write +* \param[in] phydata - the register value to write with +* +* \return 0 on success and -ve number on failure. +*/ +static int xgmac_mdio_read(struct mii_bus *bus, int phyadr, int phyreg) +{ + struct mac_ops *pdev = bus->priv; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int phydata; + + mac_printf("XGMAC %d: MDIO Read phyadr = %d, phyreg = %d\n", + pdata->mac_idx, phyadr, phyreg); + + xgmac_mdio_single_rd(pdev, 0, phyadr, phyreg, &phydata); + + mac_printf("XGMAC %d: MDIO Read phydata = %#x\n", + pdata->mac_idx, phydata); + + return phydata; +} + +/* API to write MII PHY register +* \details This API is expected to write MII registers with the value being +* passed as the last argument which is done in write_phy_regs API +* called by this function. +* +* \param[in] bus - points to the mii_bus structure +* \param[in] phyadr - the phy address to write +* \param[in] phyreg - the phy register offset to write +* \param[in] phydata - the register value to write with +* +* \return 0 on success and -ve number on failure. +*/ + +static int xgmac_mdio_write(struct mii_bus *bus, int phyadr, int phyreg, + u16 phydata) +{ + struct mac_ops *pdev = bus->priv; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int ret = 0; + + xgmac_mdio_single_wr(pdev, 0, phyadr, phyreg, phydata); + + mac_printf("XGMAC %d: MDIO Write" + "phyadr %x phyreg %x phydata %x Completed\n", + pdata->mac_idx, phyadr, phyreg, phydata); + + return ret; +} + + +/* API to reset PHY + */ +static int xgmac_mdio_reset(struct mii_bus *bus) +{ + struct mac_ops *pdev = bus->priv; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + int phydata; + + mac_printf("XGMAC %d: MDIO Reset phyadr : %d\n", pdata->mac_idx, + pdata->phyadr); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_BMCR, + &phydata); + + if (phydata < 0) + return 0; + + /* issue soft reset to PHY */ + phydata |= BMCR_RESET; + xgmac_mdio_single_wr(pdev, 0, pdata->phyadr, MII_BMCR, phydata); + + /* wait until software reset completes */ + do { + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_BMCR, + &phydata); + } while ((phydata >= 0) && (phydata & BMCR_RESET)); + + mac_printf("XGMAC %d: MDIO Reset Completed\n", + pdata->mac_idx); + + return 0; +} + +/* API to register mdio. + */ +int xgmac_mdio_register(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + struct mii_bus *new_bus = NULL; + int phyadr = 0; + unsigned short phy_detected = 0; + int ret = 0; + int phy_reg_read_status, mii_status; + + mac_printf("XGMAC %d: mdio register\n", pdata->mac_idx); + + /* find the phy ID or phy address which is connected to our MAC */ + for (phyadr = 0; phyadr < 32; phyadr++) { + + phy_reg_read_status = + xgmac_mdio_single_rd(&pdata->ops, 0, phyadr, MII_BMSR, + &mii_status); + + if (phy_reg_read_status == 0) { + if (mii_status != 0x0000 && mii_status != 0xffff) { + pr_err("Phy detected at"\ + " ID/ADDR %d\n", phyadr); + phy_detected = 1; + break; + } + } else if (phy_reg_read_status < 0) { + pr_err("Error reading the phy register"\ + " MII_BMSR for phy ID/ADDR %d\n", phyadr); + } + } + + if (!phy_detected) { + mac_printf("XGMAC %d: No phy could be detected\n", + pdata->mac_idx); + return -ENOLINK; + } + + pdata->phyadr = phyadr; + pdata->bus_id = 0x1; + + dump_phy_registers(pdev); + + new_bus = mdiobus_alloc(); + + if (new_bus == NULL) { + mac_printf("XGMAC %d: Unable to allocate mdio bus\n", + pdata->mac_idx); + return -ENOMEM; + } + + new_bus->name = "xgmac_phy"; + new_bus->read = xgmac_mdio_read; + new_bus->write = xgmac_mdio_write; + new_bus->reset = xgmac_mdio_reset; + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", new_bus->name, + pdata->bus_id); + new_bus->priv = pdev; + new_bus->phy_mask = 0; + new_bus->parent = pdata->dev; + ret = mdiobus_register(new_bus); + + if (ret != 0) { + pr_err("%s: Cannot register as MDIO bus\n", + new_bus->name); + mdiobus_free(new_bus); + return ret; + } + + pdata->mii = new_bus; + + mac_printf("XGMAC %d: MDIO register Successfull\n", pdata->mac_idx); + + return ret; +} + +/* API to unregister mdio. + */ +void xgmac_mdio_unregister(void *pdev) +{ + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + mac_printf("XGMAC %d: mdio unregister\n", pdata->mac_idx); + + if (pdata->phydev) { + phy_stop(pdata->phydev); + phy_disconnect(pdata->phydev); + pdata->phydev = NULL; + } + + mdiobus_unregister(pdata->mii); + pdata->mii->priv = NULL; + mdiobus_free(pdata->mii); + pdata->mii = NULL; + + mac_printf("XGMAC %d: mdio_unregister Successfull\n", pdata->mac_idx); +} + +static void dump_phy_registers(void *pdev) +{ + u32 phydata = 0; + struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); + + mac_printf( + "\n************* PHY Reg dump *************************\n"); + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_BMCR, &phydata); + mac_printf( + "Phy Control Reg(Basic Mode Control Reg) (%#x) = %#x\n", + MII_BMCR, phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_BMSR, &phydata); + mac_printf("Phy Status Reg(Basic Mode Status Reg) (%#x) = %#x\n", + MII_BMSR, phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_PHYSID1, &phydata); + mac_printf("Phy Id (PHYS ID 1) (%#x)= %#x\n", MII_PHYSID1, + phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_PHYSID2, + &phydata); + mac_printf("Phy Id (PHYS ID 2) (%#x)= %#x\n", MII_PHYSID2, + phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_ADVERTISE, + &phydata); + mac_printf("Auto-nego Adv (Advertisement Control Reg)"\ + " (%#x) = %#x\n", MII_ADVERTISE, phydata); + + /* read Phy Control Reg */ + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_LPA, + &phydata); + mac_printf("Auto-nego Lap (Link Partner Ability Reg)"\ + " (%#x)= %#x\n", MII_LPA, phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_EXPANSION, + &phydata); + mac_printf("Auto-nego Exp (Extension Reg)"\ + "(%#x) = %#x\n", MII_EXPANSION, phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_ESTATUS, + &phydata); + mac_printf("Extended Status Reg (%#x) = %#x\n", MII_ESTATUS, + phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_CTRL1000, + &phydata); + mac_printf("1000 Ctl Reg (1000BASE-T Control Reg)"\ + "(%#x) = %#x\n", MII_CTRL1000, phydata); + + xgmac_mdio_single_rd(pdev, 0, pdata->phyadr, MII_STAT1000, &phydata); + mac_printf("1000 Sts Reg (1000BASE-T Status)(%#x) = %#x\n", + MII_STAT1000, phydata); + + mac_printf( + "\n****************************************************\n"); +} +#endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.h b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.h index 2b6670994320295c8e2a0ee1cb4de5db3cdb8823..3b82a22ce986cbd42530289390e12ad8946ddf9f 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mdio.h @@ -42,7 +42,7 @@ #ifndef __XGMAC_MDIO_H__ #define __XGMAC_MDIO_H__ -#include "xgmac_common.h" +#include <xgmac_common.h> #define MDIO_C_45 0 #define MDIO_C_22 1 @@ -250,4 +250,9 @@ void xgmac_print_mdio(void *pdev, u32 phy_reg, u32 phy_reg_data); +#ifdef __KERNEL__ +int xgmac_mdio_register(void *pdev); +void xgmac_mdio_unregister(void *pdev); +#endif + #endif diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mtl_api.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mtl_api.c index 7814ef21a1cb875578268dec4accb459b09ef3b7..2b843c12c61b66610c8e25031297742a32bcf1df 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mtl_api.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_mtl_api.c @@ -39,7 +39,8 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" + +#include <xgmac.h> /* RSF: Receive Q store and forward * if 1, XGMAC reads packet from Rx Q after the complete packet has been @@ -53,11 +54,11 @@ int xgmac_set_mtl_rx_mode(void *pdev, u32 rx_mode) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_RQOMR); - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQOMR, RSF) != rx_mode) { - xgmac_printf("XGMAC %d: Setting MTL RX mode to: %s\n", - pdata->mac_idx, - rx_mode ? "Store and Forward" : "Threshold"); - XGMAC_SET_BITS(reg_val, MTL_Q_RQOMR, RSF, rx_mode); + if (MAC_GET_VAL(reg_val, MTL_Q_RQOMR, RSF) != rx_mode) { + mac_printf("XGMAC %d: Setting MTL RX mode to: %s\n", + pdata->mac_idx, + rx_mode ? "Store and Forward" : "Threshold"); + MAC_SET_VAL(reg_val, MTL_Q_RQOMR, RSF, rx_mode); XGMAC_RGWR(pdata, MTL_Q_RQOMR, reg_val); } @@ -69,10 +70,10 @@ int xgmac_set_mtl_rx_thresh(void *pdev, u32 rx_thresh) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_RQOMR); - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQOMR, RTC) != rx_thresh) { - xgmac_printf("XGMAC %d: Setting MTL RX threshold to: %d\n", - pdata->mac_idx, rx_thresh); - XGMAC_SET_BITS(reg_val, MTL_Q_RQOMR, RTC, rx_thresh); + if (MAC_GET_VAL(reg_val, MTL_Q_RQOMR, RTC) != rx_thresh) { + mac_printf("XGMAC %d: Setting MTL RX threshold to: %d\n", + pdata->mac_idx, rx_thresh); + MAC_SET_VAL(reg_val, MTL_Q_RQOMR, RTC, rx_thresh); XGMAC_RGWR(pdata, MTL_Q_RQOMR, reg_val); } @@ -91,11 +92,11 @@ int xgmac_set_mtl_tx_mode(void *pdev, u32 tx_mode) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_TQOMR); - if (XGMAC_GET_BITS(reg_val, MTL_Q_TQOMR, TSF) != tx_mode) { - xgmac_printf("XGMAC %d: Setting MTL TX mode to: %s\n", - pdata->mac_idx, - tx_mode ? "Store and Forward" : "Threshold"); - XGMAC_SET_BITS(reg_val, MTL_Q_TQOMR, TSF, tx_mode); + if (MAC_GET_VAL(reg_val, MTL_Q_TQOMR, TSF) != tx_mode) { + mac_printf("XGMAC %d: Setting MTL TX mode to: %s\n", + pdata->mac_idx, + tx_mode ? "Store and Forward" : "Threshold"); + MAC_SET_VAL(reg_val, MTL_Q_TQOMR, TSF, tx_mode); XGMAC_RGWR(pdata, MTL_Q_TQOMR, reg_val); } @@ -107,10 +108,10 @@ int xgmac_set_mtl_tx_thresh(void *pdev, u32 tx_thresh) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_TQOMR); - if (XGMAC_GET_BITS(reg_val, MTL_Q_TQOMR, TTC) != tx_thresh) { - xgmac_printf("XGMAC %d: Setting MTL TX threshold to: %d\n", - pdata->mac_idx, tx_thresh); - XGMAC_SET_BITS(reg_val, MTL_Q_TQOMR, TTC, tx_thresh); + if (MAC_GET_VAL(reg_val, MTL_Q_TQOMR, TTC) != tx_thresh) { + mac_printf("XGMAC %d: Setting MTL TX threshold to: %d\n", + pdata->mac_idx, tx_thresh); + MAC_SET_VAL(reg_val, MTL_Q_TQOMR, TTC, tx_thresh); XGMAC_RGWR(pdata, MTL_Q_TQOMR, reg_val); } @@ -118,13 +119,32 @@ int xgmac_set_mtl_tx_thresh(void *pdev, u32 tx_thresh) } /* Clear all the MTL Q interrupts */ -int xgmac_clear_mtl_int(void *pdev) +int xgmac_clear_mtl_int(void *pdev, u32 event) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - u32 mtl_q_isr; + u32 mtl_q_isr = XGMAC_RGRD(pdata, MTL_Q_ISR); + + if ((event & XGMAC_TXQ_OVFW_EVNT) && + (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, TXUNFIS))) { + mac_printf("XGMAC: %d Clearing MTL Q TXUNFIS" + "Interrupt Status\n", pdata->mac_idx); + MAC_SET_VAL(mtl_q_isr, MTL_Q_ISR, TXUNFIS, 1); + } + + if ((event & XGMAC_RXQ_OVFW_EVNT) && + (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, ABPSIS))) { + mac_printf("XGMAC: %d Clearing MTL Q ABPSIS" + "Interrupt Status\n", pdata->mac_idx); + MAC_SET_VAL(mtl_q_isr, MTL_Q_ISR, ABPSIS, 1); + } + + if ((event & XGMAC_AVG_BPS_EVNT) && + (MAC_GET_VAL(mtl_q_isr, MTL_Q_ISR, RXOVFIS))) { + mac_printf("XGMAC: %d Clearing MTL Q RXOVFIS" + "Interrupt Status\n", pdata->mac_idx); + MAC_SET_VAL(mtl_q_isr, MTL_Q_ISR, RXOVFIS, 1); + } - /* Clear all the interrupts which are set */ - mtl_q_isr = XGMAC_RGRD(pdata, MTL_Q_ISR); XGMAC_RGWR(pdata, MTL_Q_ISR, mtl_q_isr); return 0; @@ -140,15 +160,15 @@ int xgmac_set_mtl_int(void *pdev, u32 val) /* Tx Q Overflow Interrupt Enable */ if (val & MASK(MTL_Q_IER, TXUIE)) - XGMAC_SET_BITS(mtl_q_isr, MTL_Q_IER, TXUIE, val); + MAC_SET_VAL(mtl_q_isr, MTL_Q_IER, TXUIE, val); /* Average bits per slot interrupt enable */ if (val & MASK(MTL_Q_IER, ABPSIE)) - XGMAC_SET_BITS(mtl_q_isr, MTL_Q_IER, ABPSIE, val); + MAC_SET_VAL(mtl_q_isr, MTL_Q_IER, ABPSIE, val); /* Rx Q Overflow Interrupt Enable */ if (val & MASK(MTL_Q_IER, RXOIE)) - XGMAC_SET_BITS(mtl_q_isr, MTL_Q_IER, RXOIE, val); + MAC_SET_VAL(mtl_q_isr, MTL_Q_IER, RXOIE, val); XGMAC_RGWR(pdata, MTL_Q_IER, mtl_q_isr); return 0; @@ -171,7 +191,7 @@ int xgmac_flush_tx_queues(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - xgmac_printf("XGMAC %d: Flushing TX Q\n", pdata->mac_idx); + mac_printf("XGMAC %d: Flushing TX Q\n", pdata->mac_idx); XGMAC_RGWR_BITS(pdata, MTL_Q_TQOMR, FTQ, 1); @@ -200,17 +220,17 @@ int xgmac_set_flow_control_threshold(void *pdev, u32 rfa, u32 rfd) u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_RQFCR); /* Activate flow control when less than 4k left in fifo */ - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQFCR, RFA) != rfa) { - xgmac_printf("XGMAC %d: Set Thresh for activate Flow Ctrl %d\n", - pdata->mac_idx, rfa); - XGMAC_SET_BITS(reg_val, MTL_Q_RQFCR, RFA, rfa); + if (MAC_GET_VAL(reg_val, MTL_Q_RQFCR, RFA) != rfa) { + mac_printf("XGMAC %d: Set Thresh for activate Flow Ctrl %d\n", + pdata->mac_idx, rfa); + MAC_SET_VAL(reg_val, MTL_Q_RQFCR, RFA, rfa); } /* De-activate flow control when more than 6k left in fifo */ - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQFCR, RFD) != rfd) { - xgmac_printf("XGMAC %d: Set Thresh for deact Flow Ctrl as %d\n", - pdata->mac_idx, rfd); - XGMAC_SET_BITS(reg_val, MTL_Q_RQFCR, RFD, rfd); + if (MAC_GET_VAL(reg_val, MTL_Q_RQFCR, RFD) != rfd) { + mac_printf("XGMAC %d: Set Thresh for deact Flow Ctrl as %d\n", + pdata->mac_idx, rfd); + MAC_SET_VAL(reg_val, MTL_Q_RQFCR, RFD, rfd); } XGMAC_RGWR(pdata, MTL_Q_RQFCR, reg_val); @@ -238,10 +258,10 @@ int xgmac_set_mmc(void *pdev) u32 reg_val = XGMAC_RGRD(pdata, MMC_CR); /* Set counters to reset on read */ - if (XGMAC_GET_BITS(reg_val, MMC_CR, ROR) != 0) { - xgmac_printf("XGMAC %d: reset on read %s\n", - pdata->mac_idx, "DISABLED"); - XGMAC_SET_BITS(reg_val, MMC_CR, ROR, 0); + if (MAC_GET_VAL(reg_val, MMC_CR, ROR) != 0) { + mac_printf("XGMAC %d: reset on read %s\n", + pdata->mac_idx, "DISABLED"); + MAC_SET_VAL(reg_val, MMC_CR, ROR, 0); XGMAC_RGWR(pdata, MMC_CR, reg_val); } @@ -254,8 +274,8 @@ int xgmac_clear_rmon(void *pdev, u32 rmon_reset) /* Reset the counters */ if (rmon_reset) { - xgmac_printf("XGMAC %d: Resetting the counters\n", - pdata->mac_idx); + mac_printf("XGMAC %d: Resetting the counters\n", + pdata->mac_idx); XGMAC_RGWR_BITS(pdata, MMC_CR, CR, 1); memset(&prv_data[pdata->mac_idx].mmc_stats, 0, sizeof(struct xgmac_mmc_stats)); @@ -415,15 +435,15 @@ int xgmac_set_debug_ctl(void *pdev, u32 dbg_en, u32 dbg_mode) if (enable) { if (mode) { /* Debug Mode */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FDBGEN, enable); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, DBGMOD, enable); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FDBGEN, enable); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, DBGMOD, enable); } else { /* Slave Mode */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FDBGEN, enable); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, DBGMOD, 0); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FDBGEN, enable); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, DBGMOD, 0); } } else { - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FDBGEN, 0); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, DBGMOD, 0); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FDBGEN, 0); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, DBGMOD, 0); } XGMAC_RGWR(pdata, MTL_DBG_CTL, dbg_ctl); @@ -443,15 +463,15 @@ int xgmac_tx_debug_data(void *pdev, u32 dbg_pktstate) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, PKTSTATE, dbg_pktstate); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, PKTSTATE, dbg_pktstate); /* Set Fifo Sel to TX FIFO */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FIFOSEL, 0); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FIFOSEL, 0); /* Enables write on TX FIFO */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FIFOWREN, 1); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FIFOWREN, 1); if (dbg_pktstate == TX_EOP_DATA) - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, BYTEEN, 3); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, BYTEEN, 3); XGMAC_RGWR(pdata, MTL_DBG_CTL, dbg_ctl); @@ -464,9 +484,9 @@ int xgmac_rx_debug_data(void *pdev, u32 *dbg_pktstate, u32 *dbg_byteen) u32 dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); /* Set Fifo Sel to RX FIFO */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FIFOSEL, 3); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FIFOSEL, 3); /* Enables write on RX FIFO */ - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, FIFORDEN, 1); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, FIFORDEN, 1); XGMAC_RGWR(pdata, MTL_DBG_CTL, dbg_ctl); @@ -474,7 +494,7 @@ int xgmac_rx_debug_data(void *pdev, u32 *dbg_pktstate, u32 *dbg_byteen) dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); - *dbg_pktstate = XGMAC_GET_BITS(dbg_ctl, MTL_DBG_CTL, PKTSTATE); + *dbg_pktstate = MAC_GET_VAL(dbg_ctl, MTL_DBG_CTL, PKTSTATE); if (*dbg_pktstate == RX_EOP_DATA) *dbg_byteen = XGMAC_RGRD_BITS(pdata, MTL_DBG_STS, BYTEEN); @@ -495,8 +515,8 @@ int xgmac_set_fifo_reset(void *pdev, u32 dbg_rst_sel, u32 dbg_rst_all) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 dbg_ctl = XGMAC_RGRD(pdata, MTL_DBG_CTL); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, RSTSEL, dbg_rst_sel); - XGMAC_SET_BITS(dbg_ctl, MTL_DBG_CTL, RSTALL, dbg_rst_all); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, RSTSEL, dbg_rst_sel); + MAC_SET_VAL(dbg_ctl, MTL_DBG_CTL, RSTALL, dbg_rst_all); XGMAC_RGWR(pdata, MTL_DBG_CTL, dbg_ctl); return 0; @@ -552,16 +572,16 @@ int xgmac_forward_fup_fep_pkt(void *pdev, u32 fup, u32 fef) struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); u32 reg_val = XGMAC_RGRD(pdata, MTL_Q_RQOMR); - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQOMR, FUP) != fup) { - xgmac_printf("XGMAC %d: Set Forward Undersized Good Packets\n", - pdata->mac_idx); - XGMAC_SET_BITS(reg_val, MTL_Q_RQOMR, FUP, fup); + if (MAC_GET_VAL(reg_val, MTL_Q_RQOMR, FUP) != fup) { + mac_printf("XGMAC %d: Set Forward Undersized Good Packets\n", + pdata->mac_idx); + MAC_SET_VAL(reg_val, MTL_Q_RQOMR, FUP, fup); } - if (XGMAC_GET_BITS(reg_val, MTL_Q_RQOMR, FEF) != fef) { - xgmac_printf("XGMAC %d: Set Forward Error Packets\n", - pdata->mac_idx); - XGMAC_SET_BITS(reg_val, MTL_Q_RQOMR, FEF, fef); + if (MAC_GET_VAL(reg_val, MTL_Q_RQOMR, FEF) != fef) { + mac_printf("XGMAC %d: Set Forward Error Packets\n", + pdata->mac_idx); + MAC_SET_VAL(reg_val, MTL_Q_RQOMR, FEF, fef); } XGMAC_RGWR(pdata, MTL_Q_RQOMR, reg_val); diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.c b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.c index 3e26c8e063c3c0b775d26bfac602bfa44607a969..85b167cb39a99b8b94a1081d5212f60438f0673c 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.c +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.c @@ -39,8 +39,9 @@ * DAMAGE. * ========================================================================= */ -#include "xgmac.h" -#include "xgmac_ptp.h" + +#include <xgmac.h> +#include <xgmac_ptp.h> static int xgmac_adj_freq(struct ptp_clock_info *ptp, s32 ppb); static int xgmac_adj_time(struct ptp_clock_info *ptp, s64 delta); @@ -87,7 +88,7 @@ static int xgmac_adj_freq(struct ptp_clock_info *ptp, s32 ppb) struct mac_prv_data *pdata = container_of(ptp, struct mac_prv_data, ptp_clk_info); struct mac_ops *hw_if = &pdata->ops; - unsigned long flags; + u64 adj; u32 diff, addend; int neg_adj = 0; @@ -108,11 +109,11 @@ static int xgmac_adj_freq(struct ptp_clock_info *ptp, s32 ppb) diff = div_u64(adj, NSEC_TO_SEC); addend = neg_adj ? (addend - diff) : (addend + diff); - spin_lock_irqsave(&pdata->ptp_lock, flags); + spin_lock_bh(&pdata->ptp_lock); hw_if->config_addend(pdata, addend); - spin_unlock_irqrestore(&pdata->ptp_lock, flags); + spin_unlock_bh(&pdata->ptp_lock); return 0; } @@ -126,7 +127,7 @@ static int xgmac_adj_time(struct ptp_clock_info *ptp, s64 delta) struct mac_prv_data *pdata = container_of(ptp, struct mac_prv_data, ptp_clk_info); struct mac_ops *hw_if = &pdata->ops; - unsigned long flags; + u32 sec, nsec; u32 quotient, reminder; int neg_adj = 0; @@ -142,12 +143,12 @@ static int xgmac_adj_time(struct ptp_clock_info *ptp, s64 delta) sec = quotient; nsec = reminder; - spin_lock_irqsave(&pdata->ptp_lock, flags); + spin_lock_bh(&pdata->ptp_lock); hw_if->adjust_systime(pdata, sec, nsec, neg_adj, pdata->one_nsec_accuracy); - spin_unlock_irqrestore(&pdata->ptp_lock, flags); + spin_unlock_bh(&pdata->ptp_lock); return 0; } @@ -163,13 +164,13 @@ static int xgmac_get_time(struct ptp_clock_info *ptp, struct mac_ops *hw_if = &pdata->ops; u64 ns; u32 reminder; - unsigned long flags; - spin_lock_irqsave(&pdata->ptp_lock, flags); + + spin_lock_bh(&pdata->ptp_lock); ns = hw_if->get_systime(pdata); - spin_unlock_irqrestore(&pdata->ptp_lock, flags); + spin_unlock_bh(&pdata->ptp_lock); ts->tv_sec = div_u64_rem(ns, NSEC_TO_SEC, &reminder); ts->tv_nsec = reminder; @@ -189,16 +190,16 @@ static int xgmac_set_time(struct ptp_clock_info *ptp, struct mac_prv_data *pdata = container_of(ptp, struct mac_prv_data, ptp_clk_info); struct mac_ops *hw_if = &pdata->ops; - unsigned long flags; + pr_info("set_time: ts->tv_sec = %lld, ts->tv_nsec = %lld\n", (u64)ts->tv_sec, (u64)ts->tv_nsec); - spin_lock_irqsave(&pdata->ptp_lock, flags); + spin_lock_bh(&pdata->ptp_lock); hw_if->init_systime(pdata, ts->tv_sec, ts->tv_nsec); - spin_unlock_irqrestore(&pdata->ptp_lock, flags); + spin_unlock_bh(&pdata->ptp_lock); return 0; } @@ -317,6 +318,10 @@ static void *parse_ptp_packet(struct sk_buff *skb, u16 *eth_type) * Network stack sets the SKBTX_HW_TSTAMP in skb since socket is * marked for SO_TIMESTAMPING. */ +/* TODO: From Pmac Header OneStep bit indicates oneStep or TwoStep + * If 2 step use record id to enable TTSE/OSTC/OSTC_AVAIL + * to store the transmit timestamp + */ int xgmac_tx_hwts(void *pdev, struct sk_buff *skb) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); @@ -535,42 +540,33 @@ int xgmac_config_hwts(void *pdev, struct ifreq *ifr) -EFAULT : 0; } -#if 0 -/* Need to move this to MAC driver - * This api is common for all interrupt in XGMAC as there is only 1 - * Interrupt line from top GSWIPSS_IR pin 45 - * So other MAC interrupt status should also be checked here - */ -static irqreturn_t xgmac_isr_hdlr(int irq, void *pdev) +int xgmac_ptp_isr_hdlr(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); - - u32 mac_isr, txtsc; + u32 txtsc; struct mac_ops *hw_if = &pdata->ops; u64 tstamp; + int ret = -1; + + /* Clear/Acknowledge interrupt by reading TXTSC */ + txtsc = XGMAC_RGRD_BITS(pdata, MAC_TSTAMP_STSR, TXTSC); - mac_isr = XGMAC_RGRD(pdata, MAC_ISR); - - if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) { - /* Clear/Acknowledge interrupt by reading TXTSC */ - txtsc = XGMAC_RGRD_BITS(pdata, MAC_TSTAMP_STSR, TXTSC); - - if (txtsc) { - /* If One step timestamp no need to schedule work */ - if (pdata->two_step == 1) { - schedule_work(&pdata->ptp_tx_work); - } else { - /* Read the TxTimestamp Seconds register - * to clear the TXTSC bit - */ - tstamp = hw_if->get_tx_tstamp(pdata); - } + if (txtsc) { + /* If One step timestamp no need to schedule work */ + if (pdata->two_step == 1) { + schedule_work(&pdata->ptp_tx_work); + } else { + /* Read the TxTimestamp Seconds register + * to clear the TXTSC bit + */ + tstamp = hw_if->get_tx_tstamp(pdata); } + + ret = 0; } - return IRQ_HANDLED; + return ret; } -#endif /* This API performs the required steps for enabling PTP support. * This api will be called by MAC driver when initializing MAC @@ -612,7 +608,6 @@ int xgmac_ptp_init(void *pdev) return ret; } -// TODO: Need to find out how to get Device for PTP static int xgmac_ptp_register(void *pdev) { struct mac_prv_data *pdata = GET_MAC_PDATA(pdev); diff --git a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.h b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.h index 884a764ae80e3c23679d677ebaa45e32fbecbc1b..054294c83aa25ebf60d1b63ad3655e4e99810637 100644 --- a/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.h +++ b/drivers/net/ethernet/lantiq/switch-api/mac/xgmac_ptp.h @@ -68,4 +68,5 @@ void xgmac_ptp_remove(void *pdev); void xgmac_config_timer_reg(void *pdev); int xgmac_ptp_tx_work(struct work_struct *work); + #endif diff --git a/include/net/switch_api/adap_ops.h b/include/net/switch_api/adap_ops.h index a1691c0db2a720e04367e4c402d3d573e96ea8c7..6c379683f3197d683de267dc608b94f0b87f0669 100644 --- a/include/net/switch_api/adap_ops.h +++ b/include/net/switch_api/adap_ops.h @@ -10,106 +10,116 @@ #ifndef _ADAP_OPS_H_ #define _ADAP_OPS_H_ - -#include <linux/types.h> +#include "gsw_types.h" struct adap_ops { /* This function does the whole GSWIP Subsystem Reset. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * return OUT 0: Reset Succesfully * return OUT !0: GSWIP Subsystem Reset Error */ int(*ss_hwreset)(void *); - /* This function Sets the Master Time Source for REF_TIME, DIG_TIME, BIN_TIME, PPS_SEL. - * param[in/out] IN: ops Adaption ops Structure registered. - * param[in/out] IN: ref_time Selects the Master for Ref Time. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master - * param[in/out] IN: dig_time Adaption Operation Structure registered. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master - * param[in/out] IN: bin_time Adaption Operation Structure registered. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master - * param[in/out] IN: pps_sel Adaption Operation Structure registered. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master - * return OUT 0: Master Set Succesfully - * return OUT !0: Error in Setting Master Time Source + /* This function Sets the Master Time Source for REF_TIME, DIG_TIME, + * BIN_TIME, PPS_SEL. + * param[in/out] IN: ops Adaption ops Struct registered. + * param[in/out] IN: ref_time Selects the Master + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * param[in/out] IN: dig_time + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * param[in/out] IN: bin_time + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * param[in/out] IN: pps_sel + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * return OUT 0: Master Set Succesfully + * return OUT !0:Error in Setting Master Time Source */ int(*ss_set_cfg0_1588)(void *, u32, u32, u32, u32); - /* This function Sets the Master Time Source for REF_TIME, DIG_TIME, BIN_TIME, PPS_SEL. - * param[in/out] IN: ops Adaption ops Structure registered. + /* This function Sets the Master Time Source for REF_TIME, DIG_TIME, + * BIN_TIME, PPS_SEL. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] OUT: ref_time Gets the Master for REF_TIME. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master * param[in/out] OUT: dig_time Gets the Master for DIG_TIME. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master * param[in/out] OUT: bin_time Gets the Master for BIN_TIME. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master * param[in/out] OUT: pps_sel Gets the Master for PPS_SEL. - * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, 2 - PCIE1 is the master - * 3 - XGMAC2 is the master, 4 - XGMAC3 is the master, 5 - XGMAC4 is the master - * return OUT 0: Master Got Succesfully - * return OUT !0: Error in Getting Master Time Source + * 0 - PON_PCS is the MASTER, 1 - PCIE0 is the master, + * 2 - PCIE1 is the master 3 - XGMAC2 is the master, + * 4 - XGMAC3 is the master, 5 - XGMAC4 is the master + * return OUT 0: Master Got Succesfully + * return OUT !0:Error in Getting Master Time Source */ int(*ss_get_cfg0_1588)(void *, u32 *, u32 *, u32 *, u32 *); /* This function Sets the GSWIP Clock Mode to NC01, NCO2 or Auto Mode. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] IN: Clk Mode Selects the Clock Mode. - * 0 - NCO1 - default 666 Mhz, 1 - NCO2 - default 450 Mhz, 2 - Auto Mode (666/450) Mhz - * 3 - Auto Mode (666/450) Mhz + * 0 - NCO1 - default 666 Mhz, 1 - NCO2 - default 450 Mhz, + * 2 - Auto Mode (666/450) Mhz, 3 - Auto Mode (666/450) Mhz * return OUT 0: Clock Mode Set Succesfully * return OUT !0: Error in Setting Clock Mode */ int(*ss_set_clkmode)(void *, u32); /* This function Gets the GSWIP Clock Mode. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * return OUT: Clk Mode Gets the Clock Mode. - * 0 - NCO1 - default 666 Mhz, 1 - NCO2 - default 450 Mhz, 2 - Auto Mode (666/450) Mhz - * 3 - Auto Mode (666/450) Mhz + * 0 - NCO1 - default 666 Mhz, 1 - NCO2 - default 450 Mhz, + * 2 - Auto Mode (666/450) Mhz, 3 - Auto Mode (666/450) Mhz * return OUT -1: Error in Getting Clock Mode */ u32(*ss_get_clkmode)(void *); /* This function does the Switch Core Enable/Disable. - * param[in/out] IN: ops Adaption ops Structure registered. - * param[in/out] IN: Core Enable Selects the Core Enable 1 - Enable, 0 - Disable. + * param[in/out] IN: ops Adaption ops Struct registered. + * param[in/out] IN: Core Enable Selects the Core Enable + * 1 - Enable, 0 - Disable. * return OUT 0: Switch Core Enable/Disable Successfully * return OUT !0:Switch Core Enable/Disable Error */ int(*ss_core_en)(void *, u32); /* This function Sets MACSEC to a Mac Module Attachment. - * param[in/out] IN: ops Adaption ops Structure registered. - * param[in/out] IN: Mac Index 0 - MAC2 is attached to MACSEC, + * param[in/out]IN: ops Adaption ops Struct registered. + * param[in/out]IN: Mac Index 0 - MAC2 is attached to MACSEC, * 1 - MAC3 is attached to MACSEC, * 2 - MAC4 is attached to MACSEC. - * param[in/out] IN: Enable 1 - Enable the MACSEC to MAC Mapping, - * 0 - Disable the MACSEC to MAC Mapping, - * return OUT 0: MACSEC to a Mac Module Attachment done Successfully - * return OUT !0: MACSEC to a Mac Module Attachment Error + * param[in/out]IN: Enable 1 - Enable MACSEC to MAC Mapping + * 0 - Disable MACSEC to MAC Mapping, + * return OUT 0: MACSEC to Mac Module Attachment done + * return OUT !0:Error in MACSEC to Mac Module Attachment */ int(*ss_set_macsec_mac)(void *, u32, u32); /* This function Gets MACSEC to a Mac Module mapping. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * \return OUT: 0 - Disabled MACSEC to MAC mapping, * 2 - MAC2 is attached to MACSEC, * 3 - MAC3 is attached to MACSEC, * 4 - MAC4 is attached to MACSEC - * return OUT -1:Error in Getting MACSEC to a Mac Module Attachment + * return OUT -1:Error in MACSEC to Mac Module Attachment */ int(*ss_get_macsec_mac)(void *); /* This function does MACsec Hardware Reset. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] IN: 0 OFF reset is off * 1 ON reset is active - * return OUT 0: MACsec Hardware Reset done Successfully + * return OUT 0: MACsec Hardware Reset done * return OUT !0: MACsec Hardware Reset Error */ int(*ss_reset_macsec)(void *, u32); /* This function Sets NCO value. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] IN: val NCO value to set * IN: nco idx NCO Index to set (0/1/2/3/4) * return OUT 0: NCO value Set Successfully @@ -117,51 +127,54 @@ struct adap_ops { */ int(*ss_set_nco)(void *, u32, u32); /* This function Gets NCO value. - * param[in/out] IN: ops Adaption ops Structure registered. - * param[in/out] IN: nco idx NCO Value to Get from which Index (0/1/2/3/4) + * param[in/out] IN: ops Adaption ops Struct registered. + * param[in/out] IN: nco idx NCO Value to Get from which + * Index (0/1/2/3/4) * return OUT 0: NCO value Configured * return OUT -1:NCO value Get Error */ u32(*ss_get_nco)(void *, u32); /* This function Enables/Disbales Interrupt Enable Register. - * param[in/out] IN: ops Adaption ops Structure registered. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] IN: module 0 - XGMAC * 4 - LINK - * param[in/out] IN: idx XGMAC Index to be enabled/disabled + * param[in/out] IN: idx XGMAC Index enabled/disabled * param[in/out] IN: enable 1 - Enable, 0 - Disable - * return OUT 0: Interrupt Enable Register Set Successfully - * return OUT !0: Interrupt Enable Register Set Error + * return OUT 0: Interrupt Enable Register Set + * Successfully + * return OUT !0: Interrupt Enable Register Set + * Error */ int(*ss_set_inten)(void *, u32, u32, u32); - /* This function Gets the Interrupt Status Register. - * param[in/out] IN: ops Adaption ops Structure registered. + /* This function Gets the Interrupt Sts Register. + * param[in/out] IN: ops Adaption ops Struct registered. * param[in/out] IN: module 0 - XGMAC * 4 - LINK - * param[in/out] IN: idx XGMAC Index to Get Status - * return OUT val: Interrupt Status + * param[in/out] IN: idx XGMAC Index to Get Sts + * return OUT val: Interrupt Sts * 0 - no interrupt pending * 1 - interrupt is pending - * return OUT !0: Interrupt Status Register Get Error + * return OUT !0: Interrupt Sts Register Get Error */ - int(*ss_get_intstat)(void *, u32, u32); + int(*ss_get_intstat)(void *, u32); /* This sequence is Read Adaption register * param[in/out]IN: ops Adap ops Struct registered * param[in/out]IN: off Adap Register offset. * return OUT reg_val:Register value will be returned */ - u32(*ss_rg_rd)(void *, u32); + u32(*ss_rg_rd)(void *, u32); /* This sequence is Write Adaption register * param[in/out]IN: ops Adap ops Struct registered. * param[in/out]IN: off Adap Register offset. * param[in/out]IN: val Adap Register Value to be written. */ - void(*ss_rg_wr)(void *, u32, u32); + void(*ss_rg_wr)(void *, u32, u32); /* This sequence is used for GSWSS Cli implementation * param[in/out]IN: argc - Number of args. * param[in/out]IN: argv - Argument value. * return OUT -1: Exit GSWSS Error */ - int(*ss_cli)(u32, u8 **); + int(*ss_cli)(u32, u8 **); }; #endif diff --git a/include/net/switch_api/gsw_dev.h b/include/net/switch_api/gsw_dev.h index 152ecf07b79a8421410ccba40d6661e30c161c7b..429282b3b935b23ac3a4ae3944535d63a964b784 100644 --- a/include/net/switch_api/gsw_dev.h +++ b/include/net/switch_api/gsw_dev.h @@ -72,7 +72,7 @@ struct core_ops *gsw_get_swcore_ops(u32 devid); * Depends on mac_subdev_cnt * OUT: mac_ops MAC operations Func Pointer Structure * return NULL: No MAC operations registered - * return !NULL: Returns adaption operations registered + * return !NULL: Returns MAC operations registered */ struct mac_ops *gsw_get_mac_ops(u32 devid, u32 mac_idx); diff --git a/include/net/switch_api/gsw_flow_ops.h b/include/net/switch_api/gsw_flow_ops.h index e0b4028c5dfa1c15dbbc74afabc36704e1e818d3..cb75ecbe0b20599692ffde4a0fd49c2c2cbd4152 100644 --- a/include/net/switch_api/gsw_flow_ops.h +++ b/include/net/switch_api/gsw_flow_ops.h @@ -9,479 +9,480 @@ this software module. #ifndef _GSW_FLOW_OPS_H_ #define _GSW_FLOW_OPS_H_ -#include <linux/types.h> +#include "gsw_types.h" #include "lantiq_gsw_api.h" +#include "gsw_irq.h" /*RMON operation*/ struct rmon_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_RMON_PORT_GET ; Index: 0x01 */ - GSW_return_t (*RMON_Port_Get) (void *, GSW_RMON_Port_cnt_t *); + GSW_return_t (*RMON_Port_Get)(void *, GSW_RMON_Port_cnt_t *); /* Command: GSW_RMON_MODE_SET ; Index: 0x02 */ - GSW_return_t (*RMON_Mode_Set) (void *, GSW_RMON_mode_t *); + GSW_return_t (*RMON_Mode_Set)(void *, GSW_RMON_mode_t *); /* Command: GSW_RMON_METER_GET ; Index: 0x03 */ - GSW_return_t (*RMON_Meter_Get) (void *, GSW_RMON_Meter_cnt_t *); + GSW_return_t (*RMON_Meter_Get)(void *, GSW_RMON_Meter_cnt_t *); /* Command: GSW_RMON_REDIRECT_GET ; Index: 0x04 */ - GSW_return_t (*RMON_Redirect_Get) (void *, GSW_RMON_Redirect_cnt_t *); + GSW_return_t (*RMON_Redirect_Get)(void *, GSW_RMON_Redirect_cnt_t *); /* Command: GSW_RMON_IF_GET ; Index: 0x05 */ - GSW_return_t (*RMON_If_Get) (void *, GSW_RMON_If_cnt_t *); + GSW_return_t (*RMON_If_Get)(void *, GSW_RMON_If_cnt_t *); /* Command: GSW_RMON_ROUTE_GET ; Index: 0x06 */ - GSW_return_t (*RMON_Route_Get) (void *, GSW_RMON_Route_cnt_t *); + GSW_return_t (*RMON_Route_Get)(void *, GSW_RMON_Route_cnt_t *); /* Command: GSW_RMON_CLEAR ; Index: 0x07 */ - GSW_return_t (*RMON_Clear) (void *, GSW_RMON_clear_t *); + GSW_return_t (*RMON_Clear)(void *, GSW_RMON_clear_t *); /* Command: GSW_RMON_EXTEND_GET ; Index: 0x08 */ - GSW_return_t (*RMON_ExtendGet) (void *, GSW_RMON_extendGet_t *); + GSW_return_t (*RMON_ExtendGet)(void *, GSW_RMON_extendGet_t *); /* Command: GSW_RMON_FLOW_GET ; Index: 0x09 */ - GSW_return_t (*RMON_TflowGet) (void *, GSW_RMON_flowGet_t *); + GSW_return_t (*RMON_TflowGet)(void *, GSW_RMON_flowGet_t *); /* Command: GSW_RMON_TFLOW_CLEAR ; Index: 0x0A */ - GSW_return_t (*RMON_TflowClear) (void *, GSW_RMON_flowGet_t *); + GSW_return_t (*RMON_TflowClear)(void *, GSW_RMON_flowGet_t *); /* Command: GSW_TFLOW_COUNT_MODE_SET ; Index: 0x0B */ - GSW_return_t (*RMON_TflowCountModeSet) (void *, GSW_TflowCmodeConf_t *); + GSW_return_t (*RMON_TflowCountModeSet)(void *, GSW_TflowCmodeConf_t *); /* Command: GSW_TFLOW_COUNT_MODE_GET ; Index: 0x0C */ - GSW_return_t (*RMON_TflowCountModeGet) (void *, GSW_TflowCmodeConf_t *); + GSW_return_t (*RMON_TflowCountModeGet)(void *, GSW_TflowCmodeConf_t *); }; /*Switch MAc operations*/ struct swmac_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_MAC_TABLE_CLEAR ; Index: 0x01 */ - GSW_return_t (*MAC_TableClear) (void *); + GSW_return_t (*MAC_TableClear)(void *); /* Command: GSW_MAC_TABLE_ENTRY_ADD ; Index: 0x02 */ - GSW_return_t (*MAC_TableEntryAdd) (void *,GSW_MAC_tableAdd_t *); + GSW_return_t (*MAC_TableEntryAdd)(void *, GSW_MAC_tableAdd_t *); /* Command: GSW_MAC_TABLE_ENTRY_READ ; Index: 0x03 */ - GSW_return_t (*MAC_TableEntryRead) (void *,GSW_MAC_tableRead_t *); + GSW_return_t (*MAC_TableEntryRead)(void *, GSW_MAC_tableRead_t *); /* Command: GSW_MAC_TABLE_ENTRY_QUERY ; Index: 0x04 */ - GSW_return_t (*MAC_TableEntryQuery)(void *,GSW_MAC_tableQuery_t *); + GSW_return_t (*MAC_TableEntryQuery)(void *, GSW_MAC_tableQuery_t *); /* Command: GSW_MAC_TABLE_ENTRY_REMOVE ; Index: 0x05 */ - GSW_return_t (*MAC_TableEntryRemove) (void *,GSW_MAC_tableRemove_t *); + GSW_return_t (*MAC_TableEntryRemove)(void *, GSW_MAC_tableRemove_t *); /* Command: GSW_DEFAUL_MAC_FILTER_SET ; Index: 0x06 */ - GSW_return_t (*MAC_DefaultFilterSet) (void *, GSW_MACFILTER_default_t *); + GSW_return_t (*MAC_DefaultFilterSet)(void *, GSW_MACFILTER_default_t *); /* Command: GSW_DEFAUL_MAC_FILTER_GET ; Index: 0x07 */ - GSW_return_t (*MAC_DefaultFilterGet) (void *, GSW_MACFILTER_default_t *); + GSW_return_t (*MAC_DefaultFilterGet)(void *, GSW_MACFILTER_default_t *); }; /*Extended Vlan operations*/ struct extvlan_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_EXTENDEDVLAN_ALLOC ; Index: 0x01 */ - GSW_return_t (*ExtendedVlan_Alloc) (void *, GSW_EXTENDEDVLAN_alloc_t *); + GSW_return_t (*ExtendedVlan_Alloc)(void *, GSW_EXTENDEDVLAN_alloc_t *); /* Command: GSW_EXTENDEDVLAN_SET ; Index: 0x02 */ - GSW_return_t (*ExtendedVlan_Set) (void *, GSW_EXTENDEDVLAN_config_t *); + GSW_return_t (*ExtendedVlan_Set)(void *, GSW_EXTENDEDVLAN_config_t *); /* Command: GSW_EXTENDEDVLAN_GET ; Index: 0x03 */ - GSW_return_t (*ExtendedVlan_Get) (void *, GSW_EXTENDEDVLAN_config_t *); + GSW_return_t (*ExtendedVlan_Get)(void *, GSW_EXTENDEDVLAN_config_t *); /* Command: GSW_EXTENDEDVLAN_FREE ; Index: 0x04 */ - GSW_return_t (*ExtendedVlan_Free) (void *, GSW_EXTENDEDVLAN_alloc_t *); + GSW_return_t (*ExtendedVlan_Free)(void *, GSW_EXTENDEDVLAN_alloc_t *); }; /*Vlan Filter operations*/ struct vlanfilter_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_VLANFILTER_ALLOC ; Index: 0x01 */ - GSW_return_t (*VlanFilter_Alloc) (void *, GSW_VLANFILTER_alloc_t *); + GSW_return_t (*VlanFilter_Alloc)(void *, GSW_VLANFILTER_alloc_t *); /* Command: GSW_VLANFILTER_SET ; Index: 0x02 */ - GSW_return_t (*VlanFilter_Set) (void *, GSW_VLANFILTER_config_t *); + GSW_return_t (*VlanFilter_Set)(void *, GSW_VLANFILTER_config_t *); /* Command: GSW_VLANFILTER_GET ; Index: 0x03 */ - GSW_return_t (*VlanFilter_Get) (void *, GSW_VLANFILTER_config_t *); + GSW_return_t (*VlanFilter_Get)(void *, GSW_VLANFILTER_config_t *); /* Command: GSW_VLANFILTER_FREE ; Index: 0x04 */ - GSW_return_t (*VlanFilter_Free) (void *, GSW_VLANFILTER_alloc_t *); + GSW_return_t (*VlanFilter_Free)(void *, GSW_VLANFILTER_alloc_t *); }; /*CTP operations*/ struct ctp_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_CTP_PORT_ASSIGNMENT_ALLOC ; Index: 0x01 */ - GSW_return_t (*CTP_PortAssignmentAlloc) (void *, GSW_CTP_portAssignment_t *); + GSW_return_t (*CTP_PortAssignmentAlloc)(void *, GSW_CTP_portAssignment_t *); /* Command: GSW_CTP_PORT_ASSIGNMENT_FREE ; Index: 0x02 */ - GSW_return_t (*CTP_PortAssignmentFree) (void *, GSW_CTP_portAssignment_t *); + GSW_return_t (*CTP_PortAssignmentFree)(void *, GSW_CTP_portAssignment_t *); /* Command: GSW_CTP_PORT_ASSIGNMENT_SET ; Index: 0x03 */ - GSW_return_t (*CTP_PortAssignmentSet) (void *, GSW_CTP_portAssignment_t *); + GSW_return_t (*CTP_PortAssignmentSet)(void *, GSW_CTP_portAssignment_t *); /* Command: GSW_CTP_PORT_ASSIGNMENT_GET ; Index: 0x04 */ - GSW_return_t (*CTP_PortAssignmentGet) (void *, GSW_CTP_portAssignment_t *); + GSW_return_t (*CTP_PortAssignmentGet)(void *, GSW_CTP_portAssignment_t *); /* Command: GSW_CTP_PORT_CONFIG_SET ; Index: 0x05 */ - GSW_return_t (*CTP_PortConfigSet) (void *, GSW_CTP_portConfig_t *); + GSW_return_t (*CTP_PortConfigSet)(void *, GSW_CTP_portConfig_t *); /* Command: GSW_CTP_PORT_CONFIG_GET ; Index: 0x06 */ GSW_return_t (*CTP_PortConfigGet)(void *, GSW_CTP_portConfig_t *); /* Command: GSW_CTP_PORT_CONFIG_RESET ; Index: 0x07 */ - GSW_return_t (*CTP_PortConfigReset) (void *, GSW_CTP_portConfig_t *); + GSW_return_t (*CTP_PortConfigReset)(void *, GSW_CTP_portConfig_t *); }; /*Bridge Port operations*/ struct brdgport_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_BRIDGE_PORT_ALLOC ; Index: 0x01 */ - GSW_return_t (*BridgePort_Alloc) (void *, GSW_BRIDGE_portAlloc_t *); + GSW_return_t (*BridgePort_Alloc)(void *, GSW_BRIDGE_portAlloc_t *); /* Command: GSW_BRIDGE_PORT_CONFIG_SET ; Index: 0x02 */ - GSW_return_t (*BridgePort_ConfigSet) (void *, GSW_BRIDGE_portConfig_t *); + GSW_return_t (*BridgePort_ConfigSet)(void *, GSW_BRIDGE_portConfig_t *); /* Command: GSW_BRIDGE_PORT_CONFIG_GET ; Index: 0x03 */ - GSW_return_t (*BridgePort_ConfigGet) (void *, GSW_BRIDGE_portConfig_t *); + GSW_return_t (*BridgePort_ConfigGet)(void *, GSW_BRIDGE_portConfig_t *); /* Command: GSW_BRIDGE_PORT_FREE ; Index: 0x04 */ - GSW_return_t (*BridgePort_Free) (void *, GSW_BRIDGE_portAlloc_t *); + GSW_return_t (*BridgePort_Free)(void *, GSW_BRIDGE_portAlloc_t *); }; /*Bridge Operations*/ struct brdg_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_BRIDGE_ALLOC ; Index: 0x01 */ - GSW_return_t (*Bridge_Alloc) (void *, GSW_BRIDGE_alloc_t *); + GSW_return_t (*Bridge_Alloc)(void *, GSW_BRIDGE_alloc_t *); /* Command: GSW_BRIDGE_CONFIG_SET ; Index: 0x02 */ - GSW_return_t (*Bridge_ConfigSet) (void *, GSW_BRIDGE_config_t *); + GSW_return_t (*Bridge_ConfigSet)(void *, GSW_BRIDGE_config_t *); /* Command: GSW_BRIDGE_CONFIG_GET ; Index: 0x03 */ - GSW_return_t (*Bridge_ConfigGet) (void *, GSW_BRIDGE_config_t *); + GSW_return_t (*Bridge_ConfigGet)(void *, GSW_BRIDGE_config_t *); /* Command: GSW_BRIDGE_FREE ; Index: 0x04 */ - GSW_return_t (*Bridge_Free) (void *, GSW_BRIDGE_alloc_t *); + GSW_return_t (*Bridge_Free)(void *, GSW_BRIDGE_alloc_t *); }; /*TFlow operations*/ struct tflow_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_PCE_RULE_DELETE ; Index: 0x01 */ - GSW_return_t (*TFLOW_PceRuleDelete) (void *, GSW_PCE_ruleDelete_t *); + GSW_return_t (*TFLOW_PceRuleDelete)(void *, GSW_PCE_ruleDelete_t *); /* Command: GSW_PCE_RULE_READ ; Index: 0x02 */ - GSW_return_t (*TFLOW_PceRuleRead) (void *, GSW_PCE_rule_t *); + GSW_return_t (*TFLOW_PceRuleRead)(void *, GSW_PCE_rule_t *); /* Command: GSW_PCE_RULE_WRITE ; Index: 0x03 */ - GSW_return_t (*TFLOW_PceRuleWrite) (void *, GSW_PCE_rule_t *); + GSW_return_t (*TFLOW_PceRuleWrite)(void *, GSW_PCE_rule_t *); }; /*QOS operations*/ struct qos_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_QOS_METER_CFG_GET ; Index: 0x01 */ - GSW_return_t (*QoS_MeterCfgGet) (void *,GSW_QoS_meterCfg_t *); + GSW_return_t (*QoS_MeterCfgGet)(void *, GSW_QoS_meterCfg_t *); /* Command: GSW_QOS_METER_CFG_SET ; Index: 0x02 */ - GSW_return_t (*QoS_MeterCfgSet) (void *,GSW_QoS_meterCfg_t *); + GSW_return_t (*QoS_MeterCfgSet)(void *, GSW_QoS_meterCfg_t *); /* Command: GSW_QOS_METER_PORT_ASSIGN ; Index: 0x03 */ - GSW_return_t (*QoS_MeterPortAssign) (void *,GSW_QoS_meterPort_t *); + GSW_return_t (*QoS_MeterPortAssign)(void *, GSW_QoS_meterPort_t *); /* Command: GSW_QOS_METER_PORT_DEASSIGN ; Index: 0x04 */ - GSW_return_t (*QoS_MeterPortDeassign) (void *,GSW_QoS_meterPort_t *); + GSW_return_t (*QoS_MeterPortDeassign)(void *, GSW_QoS_meterPort_t *); /* Command: GSW_QOS_METER_PORT_GET ; Index: 0x05 */ - GSW_return_t (*QoS_MeterPortGet) (void *,GSW_QoS_meterPortGet_t *); + GSW_return_t (*QoS_MeterPortGet)(void *, GSW_QoS_meterPortGet_t *); /* Command: GSW_QOS_DSCP_CLASS_GET ; Index: 0x06 */ - GSW_return_t (*QoS_DSCP_ClassGet) (void *,GSW_QoS_DSCP_ClassCfg_t *); + GSW_return_t (*QoS_DSCP_ClassGet)(void *, GSW_QoS_DSCP_ClassCfg_t *); /* Command: GSW_QOS_DSCP_CLASS_SET ; Index: 0x07 */ - GSW_return_t (*QoS_DSCP_ClassSet) (void *,GSW_QoS_DSCP_ClassCfg_t *); + GSW_return_t (*QoS_DSCP_ClassSet)(void *, GSW_QoS_DSCP_ClassCfg_t *); /* Command: GSW_QOS_CLASS_DSCP_GET ; Index: 0x08 */ - GSW_return_t (*QoS_ClassDSCP_Get) (void *,GSW_QoS_ClassDSCP_Cfg_t *); + GSW_return_t (*QoS_ClassDSCP_Get)(void *, GSW_QoS_ClassDSCP_Cfg_t *); /* Command: GSW_QOS_CLASS_DSCP_SET ; Index: 0x09 */ - GSW_return_t (*QoS_ClassDSCP_Set) (void *,GSW_QoS_ClassDSCP_Cfg_t *); + GSW_return_t (*QoS_ClassDSCP_Set)(void *, GSW_QoS_ClassDSCP_Cfg_t *); /* Command: GSW_QOS_DSCP_DROP_PRECEDENCE_CFG_GET ; Index: 0x0A */ - GSW_return_t (*QoS_DSCP_DropPrecedenceCfgGet) (void *,GSW_QoS_DSCP_DropPrecedenceCfg_t *); + GSW_return_t (*QoS_DSCP_DropPrecedenceCfgGet)(void *, GSW_QoS_DSCP_DropPrecedenceCfg_t *); /* Command: GSW_QOS_DSCP_DROP_PRECEDENCE_CFG_SET ; Index: 0x0B */ - GSW_return_t (*QoS_DSCP_DropPrecedenceCfgSet) (void *,GSW_QoS_DSCP_DropPrecedenceCfg_t *); + GSW_return_t (*QoS_DSCP_DropPrecedenceCfgSet)(void *, GSW_QoS_DSCP_DropPrecedenceCfg_t *); /* Command: GSW_QOS_PORT_REMARKING_CFG_GET ; Index: 0x0C */ - GSW_return_t (*QoS_PortRemarkingCfgGet) (void *,GSW_QoS_portRemarkingCfg_t *); + GSW_return_t (*QoS_PortRemarkingCfgGet)(void *, GSW_QoS_portRemarkingCfg_t *); /* Command: GSW_QOS_PORT_REMARKING_CFG_SET ; Index: 0x0D */ - GSW_return_t (*QoS_PortRemarkingCfgSet) (void *,GSW_QoS_portRemarkingCfg_t *); + GSW_return_t (*QoS_PortRemarkingCfgSet)(void *, GSW_QoS_portRemarkingCfg_t *); /* Command: GSW_QOS_CLASS_PCP_GET ; Index: 0x0E*/ - GSW_return_t (*QoS_ClassPCP_Get) (void *,GSW_QoS_ClassPCP_Cfg_t *); + GSW_return_t (*QoS_ClassPCP_Get)(void *, GSW_QoS_ClassPCP_Cfg_t *); /* Command: GSW_QOS_CLASS_PCP_SET ; Index: 0x0F */ - GSW_return_t (*QoS_ClassPCP_Set) (void *,GSW_QoS_ClassPCP_Cfg_t *); + GSW_return_t (*QoS_ClassPCP_Set)(void *, GSW_QoS_ClassPCP_Cfg_t *); /* Command: GSW_QOS_PCP_CLASS_GET ; Index: 0x10 */ - GSW_return_t (*QoS_PCP_ClassGet) (void *,GSW_QoS_PCP_ClassCfg_t *); + GSW_return_t (*QoS_PCP_ClassGet)(void *, GSW_QoS_PCP_ClassCfg_t *); /* Command: GSW_QOS_PCP_CLASS_SET ; Index: 0x11 */ - GSW_return_t (*QoS_PCP_ClassSet) (void *,GSW_QoS_PCP_ClassCfg_t *); + GSW_return_t (*QoS_PCP_ClassSet)(void *, GSW_QoS_PCP_ClassCfg_t *); /* Command: GSW_QOS_PORT_CFG_GET ; Index: 0x12 */ - GSW_return_t (*QoS_PortCfgGet) (void *,GSW_QoS_portCfg_t *); + GSW_return_t (*QoS_PortCfgGet)(void *, GSW_QoS_portCfg_t *); /* Command: GSW_QOS_PORT_CFG_SET ; Index: 0x13 */ - GSW_return_t (*QoS_PortCfgSet) (void *,GSW_QoS_portCfg_t *); + GSW_return_t (*QoS_PortCfgSet)(void *, GSW_QoS_portCfg_t *); /* Command: GSW_QOS_QUEUE_PORT_GET ; Index: 0x14 */ - GSW_return_t (*QoS_QueuePortGet) (void *,GSW_QoS_queuePort_t *); + GSW_return_t (*QoS_QueuePortGet)(void *, GSW_QoS_queuePort_t *); /* Command: GSW_QOS_QUEUE_PORT_SET ; Index: 0x15 */ - GSW_return_t (*QoS_QueuePortSet) (void *,GSW_QoS_queuePort_t *); + GSW_return_t (*QoS_QueuePortSet)(void *, GSW_QoS_queuePort_t *); /* Command: GSW_QOS_SCHEDULER_CFG_GET ; Index: 0x16 */ - GSW_return_t (*QoS_SchedulerCfgGet) (void *,GSW_QoS_schedulerCfg_t *); + GSW_return_t (*QoS_SchedulerCfgGet)(void *, GSW_QoS_schedulerCfg_t *); /* Command: GSW_QOS_SCHEDULER_CFG_SET ; Index: 0x17 */ - GSW_return_t (*QoS_SchedulerCfgSet) (void *,GSW_QoS_schedulerCfg_t *); + GSW_return_t (*QoS_SchedulerCfgSet)(void *, GSW_QoS_schedulerCfg_t *); /* Command: GSW_QOS_SHAPER_CFG_GET ; Index: 0x18 */ - GSW_return_t (*QoS_ShaperCfgGet) (void *,GSW_QoS_ShaperCfg_t *); + GSW_return_t (*QoS_ShaperCfgGet)(void *, GSW_QoS_ShaperCfg_t *); /* Command: GSW_QOS_SHAPER_CFG_SET ; Index: 0x19 */ - GSW_return_t (*QoS_ShaperCfgSet) (void *,GSW_QoS_ShaperCfg_t *); + GSW_return_t (*QoS_ShaperCfgSet)(void *, GSW_QoS_ShaperCfg_t *); /* Command: GSW_QOS_SHAPER_QUEUE_ASSIGN ; Index: 0x1A */ - GSW_return_t (*QoS_ShaperQueueAssign) (void *,GSW_QoS_ShaperQueue_t *); + GSW_return_t (*QoS_ShaperQueueAssign)(void *, GSW_QoS_ShaperQueue_t *); /* Command: GSW_QOS_SHAPER_QUEUE_DEASSIGN ; Index: 0x1B */ - GSW_return_t (*QoS_ShaperQueueDeassign) (void *,GSW_QoS_ShaperQueue_t *); + GSW_return_t (*QoS_ShaperQueueDeassign)(void *, GSW_QoS_ShaperQueue_t *); /* Command: GSW_QOS_SHAPER_QUEUE_GET ; Index: 0x1C */ - GSW_return_t (*QoS_ShaperQueueGet) (void *,GSW_QoS_ShaperQueueGet_t *); + GSW_return_t (*QoS_ShaperQueueGet)(void *, GSW_QoS_ShaperQueueGet_t *); /* Command: GSW_QOS_STORM_CFG_SET ; Index: 0x1D */ - GSW_return_t (*QoS_StormCfgSet) (void *,GSW_QoS_stormCfg_t *); + GSW_return_t (*QoS_StormCfgSet)(void *, GSW_QoS_stormCfg_t *); /* Command: GSW_QOS_STORM_CFG_GET ; Index: 0x1E */ - GSW_return_t (*QoS_StormCfgGet) (void *,GSW_QoS_stormCfg_t *); + GSW_return_t (*QoS_StormCfgGet)(void *, GSW_QoS_stormCfg_t *); /* Command: GSW_QOS_WRED_CFG_GET ; Index: 0x1F */ - GSW_return_t (*QoS_WredCfgGet) (void *,GSW_QoS_WRED_Cfg_t *); + GSW_return_t (*QoS_WredCfgGet)(void *, GSW_QoS_WRED_Cfg_t *); /* Command: GSW_QOS_WRED_CFG_SET ; Index: 0x20 */ - GSW_return_t (*QoS_WredCfgSet) (void *,GSW_QoS_WRED_Cfg_t *); + GSW_return_t (*QoS_WredCfgSet)(void *, GSW_QoS_WRED_Cfg_t *); /* Command: GSW_QOS_WRED_QUEUE_CFG_GET ; Index: 0x21 */ - GSW_return_t (*QoS_WredQueueCfgGet) (void *,GSW_QoS_WRED_QueueCfg_t *); + GSW_return_t (*QoS_WredQueueCfgGet)(void *, GSW_QoS_WRED_QueueCfg_t *); /* Command: GSW_QOS_WRED_QUEUE_CFG_SET ; Index: 0x22 */ - GSW_return_t (*QoS_WredQueueCfgSet) (void *,GSW_QoS_WRED_QueueCfg_t *); + GSW_return_t (*QoS_WredQueueCfgSet)(void *, GSW_QoS_WRED_QueueCfg_t *); /* Command: GSW_QOS_WRED_PORT_CFG_GET ; Index: 0x23 */ - GSW_return_t (*QoS_WredPortCfgGet) (void *,GSW_QoS_WRED_PortCfg_t *); + GSW_return_t (*QoS_WredPortCfgGet)(void *, GSW_QoS_WRED_PortCfg_t *); /* Command: GSW_QOS_WRED_PORT_CFG_SET ; Index: 0x24 */ - GSW_return_t (*QoS_WredPortCfgSet) (void *,GSW_QoS_WRED_PortCfg_t *); + GSW_return_t (*QoS_WredPortCfgSet)(void *, GSW_QoS_WRED_PortCfg_t *); /* Command: GSW_QOS_FLOWCTRL_CFG_GET ; Index: 0x25 */ - GSW_return_t (*QoS_FlowctrlCfgGet) (void *,GSW_QoS_FlowCtrlCfg_t *); + GSW_return_t (*QoS_FlowctrlCfgGet)(void *, GSW_QoS_FlowCtrlCfg_t *); /* Command: GSW_QOS_FLOWCTRL_CFG_SET ; Index: 0x26 */ - GSW_return_t (*QoS_FlowctrlCfgSet) (void *,GSW_QoS_FlowCtrlCfg_t *); + GSW_return_t (*QoS_FlowctrlCfgSet)(void *, GSW_QoS_FlowCtrlCfg_t *); /* Command: GSW_QOS_FLOWCTRL_PORT_CFG_GET ; Index: 0x27 */ - GSW_return_t (*QoS_FlowctrlPortCfgGet) (void *,GSW_QoS_FlowCtrlPortCfg_t *); + GSW_return_t (*QoS_FlowctrlPortCfgGet)(void *, GSW_QoS_FlowCtrlPortCfg_t *); /* Command: GSW_QOS_FLOWCTRL_PORT_CFG_SET ; Index: 0x28 */ - GSW_return_t (*QoS_FlowctrlPortCfgSet) (void *,GSW_QoS_FlowCtrlPortCfg_t *); + GSW_return_t (*QoS_FlowctrlPortCfgSet)(void *, GSW_QoS_FlowCtrlPortCfg_t *); /* Command: GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET ; Index: 0x29 */ - GSW_return_t (*QoS_QueueBufferReserveCfgGet) (void *,GSW_QoS_QueueBufferReserveCfg_t *); + GSW_return_t (*QoS_QueueBufferReserveCfgGet)(void *, GSW_QoS_QueueBufferReserveCfg_t *); /* Command: GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_SET ; Index: 0x2A */ - GSW_return_t (*QoS_QueueBufferReserveCfgSet) (void *,GSW_QoS_QueueBufferReserveCfg_t *); + GSW_return_t (*QoS_QueueBufferReserveCfgSet)(void *, GSW_QoS_QueueBufferReserveCfg_t *); /* Command: GSW_QOS_METER_ACT ; Index: 0x2B */ - GSW_return_t (*QoS_Meter_Act) (void *,GSW_QoS_mtrAction_t *); + GSW_return_t (*QoS_Meter_Act)(void *, GSW_QoS_mtrAction_t *); /* Command: GSW_QOS_COLOR_MARKING_TABLE_SET ; Index: 0x2C */ - GSW_return_t (*QOS_ColorMarkingTableGet) (void *, GSW_QoS_colorMarkingEntry_t *); + GSW_return_t (*QOS_ColorMarkingTableGet)(void *, GSW_QoS_colorMarkingEntry_t *); /* Command: GSW_QOS_COLOR_MARKING_TABLE_GET ; Index: 0x2D */ - GSW_return_t (*QOS_ColorMarkingTableSet) (void *, GSW_QoS_colorMarkingEntry_t *); + GSW_return_t (*QOS_ColorMarkingTableSet)(void *, GSW_QoS_colorMarkingEntry_t *); /* Command: GSW_QOS_COLOR_REMARKING_TABLE_SET ; Index: 0x2E */ - GSW_return_t (*QOS_ColorReMarkingTableSet) (void *, GSW_QoS_colorRemarkingEntry_t *); + GSW_return_t (*QOS_ColorReMarkingTableSet)(void *, GSW_QoS_colorRemarkingEntry_t *); /* Command: GSW_QOS_COLOR_REMARKING_TABLE_GET ; Index: 0x2F */ - GSW_return_t (*QOS_ColorReMarkingTableGet) (void *, GSW_QoS_colorRemarkingEntry_t *); + GSW_return_t (*QOS_ColorReMarkingTableGet)(void *, GSW_QoS_colorRemarkingEntry_t *); /* Command: GSW_QOS_METER_ALLOC ; Index: 0x30 */ - GSW_return_t (*QOS_MeterAlloc) (void *, GSW_QoS_meterCfg_t *param); + GSW_return_t (*QOS_MeterAlloc)(void *, GSW_QoS_meterCfg_t *param); /* Command: GSW_QOS_METER_FREE ; Index: 0x31 */ - GSW_return_t (*QOS_MeterFree) (void *, GSW_QoS_meterCfg_t *param); + GSW_return_t (*QOS_MeterFree)(void *, GSW_QoS_meterCfg_t *param); /* Command: GSW_DSCP2PCP_MAP_SET ; Index: 0x32 */ - GSW_return_t (*QOS_Dscp2PcpTableSet) (void *, GSW_DSCP2PCP_map_t *); + GSW_return_t (*QOS_Dscp2PcpTableSet)(void *, GSW_DSCP2PCP_map_t *); /* Command: GSW_DSCP2PCP_MAP_GET ; Index: 0x33 */ - GSW_return_t (*QOS_Dscp2PcpTableGet) (void *, GSW_DSCP2PCP_map_t *); + GSW_return_t (*QOS_Dscp2PcpTableGet)(void *, GSW_DSCP2PCP_map_t *); /* Command: GSW_PMAPPER_SET ; Index: 0x34 */ - GSW_return_t (*QOS_PmapperTableSet) (void *, GSW_PMAPPER_t *); + GSW_return_t (*QOS_PmapperTableSet)(void *, GSW_PMAPPER_t *); /* Command: GSW_PMAPPER_GET ; Index: 0x35 */ - GSW_return_t (*QOS_PmapperTableGet) (void *, GSW_PMAPPER_t *); + GSW_return_t (*QOS_PmapperTableGet)(void *, GSW_PMAPPER_t *); /* Command: GSW_QOS_SVLAN_CLASS_PCP_PORT_GET ; Index: 0x36 */ - GSW_return_t (*QoS_SVLAN_ClassPCP_PortGet) (void *,GSW_QoS_SVLAN_ClassPCP_PortCfg_t *); + GSW_return_t (*QoS_SVLAN_ClassPCP_PortGet)(void *, GSW_QoS_SVLAN_ClassPCP_PortCfg_t *); /* Command: GSW_QOS_SVLAN_CLASS_PCP_PORT_SET ; Index: 0x37 */ - GSW_return_t (*QoS_SVLAN_ClassPCP_PortSet) (void *,GSW_QoS_SVLAN_ClassPCP_PortCfg_t *); + GSW_return_t (*QoS_SVLAN_ClassPCP_PortSet)(void *, GSW_QoS_SVLAN_ClassPCP_PortCfg_t *); /* Command: GSW_QOS_SVLAN_PCP_CLASS_GET ; Index: 0x38 */ - GSW_return_t (*QoS_SVLAN_PCP_ClassGet) (void *,GSW_QoS_SVLAN_PCP_ClassCfg_t *); + GSW_return_t (*QoS_SVLAN_PCP_ClassGet)(void *, GSW_QoS_SVLAN_PCP_ClassCfg_t *); /* Command: GSW_QOS_SVLAN_PCP_CLASS_SET ; Index: 0x39 */ - GSW_return_t (*QoS_SVLAN_PCP_ClassSet) (void *,GSW_QoS_SVLAN_PCP_ClassCfg_t *); + GSW_return_t (*QoS_SVLAN_PCP_ClassSet)(void *, GSW_QoS_SVLAN_PCP_ClassCfg_t *); }; /*STP operations*/ struct stp_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_STP_BPDU_RULE_GET ; Index: 0x01 */ - GSW_return_t (*STP_BPDU_RuleGet) (void *,GSW_STP_BPDU_Rule_t *); + GSW_return_t (*STP_BPDU_RuleGet)(void *, GSW_STP_BPDU_Rule_t *); /* Command: GSW_STP_BPDU_RULE_SET ; Index: 0x02 */ - GSW_return_t (*STP_BPDU_RuleSet) (void *,GSW_STP_BPDU_Rule_t *); + GSW_return_t (*STP_BPDU_RuleSet)(void *, GSW_STP_BPDU_Rule_t *); /* Command: GSW_STP_PORT_CFG_GET ; Index: 0x03 */ - GSW_return_t (*STP_PortCfgGet) (void *, GSW_STP_portCfg_t *); + GSW_return_t (*STP_PortCfgGet)(void *, GSW_STP_portCfg_t *); /* Command: GSW_STP_PORT_CFG_SET ; Index: 0x04 */ - GSW_return_t (*STP_PortCfgSet) (void *, GSW_STP_portCfg_t *); + GSW_return_t (*STP_PortCfgSet)(void *, GSW_STP_portCfg_t *); }; /*8021x operations*/ struct eapol_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_8021X_EAPOL_RULE_GET ; Index: 0x01 */ - GSW_return_t (*EAPOL_RuleGet) (void *, GSW_8021X_EAPOL_Rule_t *); + GSW_return_t (*EAPOL_RuleGet)(void *, GSW_8021X_EAPOL_Rule_t *); /* Command: GSW_8021X_EAPOL_RULE_SET ; Index: 0x02 */ - GSW_return_t (*EAPOL_RuleGet_RuleSet) (void *, GSW_8021X_EAPOL_Rule_t *); + GSW_return_t (*EAPOL_RuleGet_RuleSet)(void *, GSW_8021X_EAPOL_Rule_t *); /* Command: GSW_8021X_PORT_CFG_GET ; Index: 0x03 */ - GSW_return_t (*EAPOL_RuleGet_PortCfgGet) (void *, GSW_8021X_portCfg_t *); + GSW_return_t (*EAPOL_RuleGet_PortCfgGet)(void *, GSW_8021X_portCfg_t *); /* Command: GSW_8021X_PORT_CFG_SET ; Index: 0x04 */ - GSW_return_t (*EAPOL_RuleGet_PortCfgSet) (void *, GSW_8021X_portCfg_t *); + GSW_return_t (*EAPOL_RuleGet_PortCfgSet)(void *, GSW_8021X_portCfg_t *); }; /*multicast operations*/ struct multicast_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_MULTICAST_ROUTER_PORT_ADD ; Index: 0x01 */ - GSW_return_t (*Multicast_RouterPortAdd) (void *,GSW_multicastRouter_t *); + GSW_return_t (*Multicast_RouterPortAdd)(void *, GSW_multicastRouter_t *); /* Command: GSW_MULTICAST_ROUTER_PORT_READ ; Index: 0x02 */ - GSW_return_t (*Multicast_RouterPortRead) (void *,GSW_multicastRouterRead_t *); + GSW_return_t (*Multicast_RouterPortRead)(void *, GSW_multicastRouterRead_t *); /* Command: GSW_MULTICAST_ROUTER_PORT_REMOVE ; Index: 0x03 */ - GSW_return_t (*Multicast_RouterPortRemove) (void *,GSW_multicastRouter_t *); + GSW_return_t (*Multicast_RouterPortRemove)(void *, GSW_multicastRouter_t *); /* Command: GSW_MULTICAST_SNOOP_CFG_GET ; Index: 0x04 */ - GSW_return_t (*Multicast_SnoopCfgGet) (void *,GSW_multicastSnoopCfg_t *); + GSW_return_t (*Multicast_SnoopCfgGet)(void *, GSW_multicastSnoopCfg_t *); /* Command: GSW_MULTICAST_SNOOP_CFG_SET ; Index: 0x05 */ - GSW_return_t (*Multicast_SnoopCfgSet) (void *,GSW_multicastSnoopCfg_t *); + GSW_return_t (*Multicast_SnoopCfgSet)(void *, GSW_multicastSnoopCfg_t *); /* Command: GSW_MULTICAST_TABLE_ENTRY_ADD ; Index: 0x06 */ - GSW_return_t (*Multicast_TableEntryAdd) (void *,GSW_multicastTable_t *); + GSW_return_t (*Multicast_TableEntryAdd)(void *, GSW_multicastTable_t *); /* Command: GSW_MULTICAST_TABLE_ENTRY_READ ; Index: 0x07 */ - GSW_return_t (*Multicast_TableEntryRead) (void *,GSW_multicastTableRead_t *); + GSW_return_t (*Multicast_TableEntryRead)(void *, GSW_multicastTableRead_t *); /* Command: GSW_MULTICAST_TABLE_ENTRY_REMOVE ; Index: 0x08 */ - GSW_return_t (*Multicast_TableEntryRemove) (void *,GSW_multicastTable_t *); + GSW_return_t (*Multicast_TableEntryRemove)(void *, GSW_multicastTable_t *); }; /*Trunking operations*/ struct trunking_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_TRUNKING_CFG_GET ; Index: 0x01 */ GSW_return_t (*Trunking_CfgGet)(void *, GSW_trunkingCfg_t *); /* Command: GSW_TRUNKING_CFG_SET ; Index: 0x02 */ - GSW_return_t (*Trunking_CfgSet) (void *,GSW_trunkingCfg_t *); + GSW_return_t (*Trunking_CfgSet)(void *, GSW_trunkingCfg_t *); /* Command: GSW_TRUNKING_PORT_CFG_GET ; Index: 0x03 */ - GSW_return_t (*Trunking_PortCfgGet) (void *,GSW_trunkingPortCfg_t *); + GSW_return_t (*Trunking_PortCfgGet)(void *, GSW_trunkingPortCfg_t *); /* Command: GSW_TRUNKING_PORT_CFG_SET ; Index: 0x04 */ - GSW_return_t (*Trunking_PortCfgSet) (void *,GSW_trunkingPortCfg_t *); + GSW_return_t (*Trunking_PortCfgSet)(void *, GSW_trunkingPortCfg_t *); }; /*WOL operations*/ struct wol_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_WOL_CFG_GET ; Index: 0x01 */ - GSW_return_t (*WoL_CfgGet) (void *, GSW_WoL_Cfg_t *); + GSW_return_t (*WoL_CfgGet)(void *, GSW_WoL_Cfg_t *); /* Command: GSW_WOL_CFG_SET ; Index: 0x02 */ - GSW_return_t (*WoL_CfgSet) (void *, GSW_WoL_Cfg_t *); + GSW_return_t (*WoL_CfgSet)(void *, GSW_WoL_Cfg_t *); /* Command: GSW_WOL_PORT_CFG_GET ; Index: 0x03 */ - GSW_return_t (*WoL_PortCfgGet) (void *, GSW_WoL_PortCfg_t *); + GSW_return_t (*WoL_PortCfgGet)(void *, GSW_WoL_PortCfg_t *); /* Command: GSW_WOL_PORT_CFG_SET ; Index: 0x04 */ - GSW_return_t (*WoL_PortCfgSet) (void *, GSW_WoL_PortCfg_t *); + GSW_return_t (*WoL_PortCfgSet)(void *, GSW_WoL_PortCfg_t *); }; /*Common switch operations*/ struct common_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_REGISTER_GET ; Index: 0x01 */ - GSW_return_t (*RegisterGet) (void *, GSW_register_t *); + GSW_return_t (*RegisterGet)(void *, GSW_register_t *); /* Command: GSW_REGISTER_SET ; Index: 0x02 */ - GSW_return_t (*RegisterSet) (void *, GSW_register_t *); + GSW_return_t (*RegisterSet)(void *, GSW_register_t *); /* Command: GSW_IRQ_GET ; Index: 0x03 */ - GSW_return_t (*IrqGet) (void *, GSW_irq_t *); + GSW_return_t (*IrqGet)(void *, GSW_irq_t *); /* Command: GSW_IRQ_MASK_GET ; Index: 0x04 */ - GSW_return_t (*IrqMaskGet) (void *, GSW_irq_t *); + GSW_return_t (*IrqMaskGet)(void *, GSW_irq_t *); /* Command: GSW_IRQ_MASK_SET ; Index: 0x05 */ - GSW_return_t (*IrqMaskSet) (void *, GSW_irq_t *); + GSW_return_t (*IrqMaskSet)(void *, GSW_irq_t *); /* Command: GSW_IRQ_STATUS_CLEAR ; Index: 0x06 */ - GSW_return_t (*IrqStatusClear) (void *, GSW_irq_t *); + GSW_return_t (*IrqStatusClear)(void *, GSW_irq_t *); /* Command: GSW_ENABLE ; Index: 0x07 */ - GSW_return_t (*Enable) (void *); + GSW_return_t (*Enable)(void *); /* Command: GSW_RESET ; Index: 0x08 */ - GSW_return_t (*Reset) (void *, GSW_reset_t *); + GSW_return_t (*Reset)(void *, GSW_reset_t *); /* Command: GSW_DISABLE ; Index: 0x09 */ - GSW_return_t (*Disable) (void *); + GSW_return_t (*Disable)(void *); /* Command: GSW_VERSION_GET ; Index: 0x0A */ - GSW_return_t (*VersionGet) (void *, GSW_version_t *); + GSW_return_t (*VersionGet)(void *, GSW_version_t *); /* Command: GSW_CAP_GET ; Index: 0x0B */ - GSW_return_t (*CapGet) (void *, GSW_cap_t *); + GSW_return_t (*CapGet)(void *, GSW_cap_t *); /* Command: GSW_CFG_GET ; Index: 0x0C */ - GSW_return_t (*CfgGet) (void *, GSW_cfg_t *); + GSW_return_t (*CfgGet)(void *, GSW_cfg_t *); /* Command: GSW_CFG_SET ; Index: 0x0D */ - GSW_return_t (*CfgSet) (void *, GSW_cfg_t *); + GSW_return_t (*CfgSet)(void *, GSW_cfg_t *); /* Command: GSW_HW_INIT ; Index: 0x0E */ - GSW_return_t (*HW_Init) (void *, GSW_HW_Init_t *); + GSW_return_t (*HW_Init)(void *, GSW_HW_Init_t *); /* Command: GSW_PORT_LINK_CFG_GET ; Index: 0x0F */ - GSW_return_t (*PortLinkCfgGet) (void *, GSW_portLinkCfg_t *); + GSW_return_t (*PortLinkCfgGet)(void *, GSW_portLinkCfg_t *); /* Command: GSW_PORT_LINK_CFG_SET ; Index: 0x10 */ - GSW_return_t (*PortLinkCfgSet) (void *, GSW_portLinkCfg_t *); + GSW_return_t (*PortLinkCfgSet)(void *, GSW_portLinkCfg_t *); /* Command: GSW_PORT_PHY_ADDR_GET ; Index: 0x11 */ - GSW_return_t (*PortPHY_AddrGet) (void *, GSW_portPHY_Addr_t *); + GSW_return_t (*PortPHY_AddrGet)(void *, GSW_portPHY_Addr_t *); /* Command: GSW_PORT_PHY_QUERY ; Index: 0x12 */ - GSW_return_t (*PortPHY_Query) (void *, GSW_portPHY_Query_t *); + GSW_return_t (*PortPHY_Query)(void *, GSW_portPHY_Query_t *); /* Command: GSW_PORT_RGMII_CLK_CFG_GET ; Index: 0x13 */ - GSW_return_t (*PortRGMII_ClkCfgGet) (void *, GSW_portRGMII_ClkCfg_t *); + GSW_return_t (*PortRGMII_ClkCfgGet)(void *, GSW_portRGMII_ClkCfg_t *); /* Command: GSW_PORT_RGMII_CLK_CFG_SET ; Index: 0x14 */ - GSW_return_t (*PortRGMII_ClkCfgSet) (void *, GSW_portRGMII_ClkCfg_t *); + GSW_return_t (*PortRGMII_ClkCfgSet)(void *, GSW_portRGMII_ClkCfg_t *); /* Command: GSW_PORT_REDIRECT_GET ; Index: 0x15 */ - GSW_return_t (*PortRedirectGet) (void *, GSW_portRedirectCfg_t *); + GSW_return_t (*PortRedirectGet)(void *, GSW_portRedirectCfg_t *); /* Command: GSW_PORT_REDIRECT_SET ; Index: 0x16 */ - GSW_return_t (*PortRedirectSet) (void *, GSW_portRedirectCfg_t *); + GSW_return_t (*PortRedirectSet)(void *, GSW_portRedirectCfg_t *); /* Command: GSW_CPU_PORT_CFG_GET ; Index: 0x17 */ - GSW_return_t (*CPU_PortCfgGet) (void *, GSW_CPU_PortCfg_t *); + GSW_return_t (*CPU_PortCfgGet)(void *, GSW_CPU_PortCfg_t *); /* Command: GSW_CPU_PORT_CFG_SET ; Index: 0x18 */ - GSW_return_t (*CPU_PortCfgSet) (void *, GSW_CPU_PortCfg_t *); + GSW_return_t (*CPU_PortCfgSet)(void *, GSW_CPU_PortCfg_t *); /* Command: GSW_CPU_PORT_EXTEND_CFG_GET ; Index: 0x19 */ - GSW_return_t (*CPU_PortExtendCfgGet) (void *, GSW_CPU_PortExtendCfg_t *); + GSW_return_t (*CPU_PortExtendCfgGet)(void *, GSW_CPU_PortExtendCfg_t *); /* Command: GSW_CPU_PORT_EXTEND_CFG_SET ; Index: 0x1A */ - GSW_return_t (*CPU_PortExtendCfgSet) (void *, GSW_CPU_PortExtendCfg_t *); + GSW_return_t (*CPU_PortExtendCfgSet)(void *, GSW_CPU_PortExtendCfg_t *); /* Command: GSW_MONITOR_PORT_CFG_GET ; Index: 0x1B */ - GSW_return_t (*MonitorPortCfgGet) (void *, GSW_monitorPortCfg_t *); + GSW_return_t (*MonitorPortCfgGet)(void *, GSW_monitorPortCfg_t *); /* Command: GSW_MONITOR_PORT_CFG_SET ; Index: 0x1C */ - GSW_return_t (*MonitorPortCfgSet) (void *, GSW_monitorPortCfg_t *); + GSW_return_t (*MonitorPortCfgSet)(void *, GSW_monitorPortCfg_t *); /* Command: GSW_TIMESTAMP_TIMER_SET ; Index: 0x1D */ - GSW_return_t (*Timestamp_TimerSet) (void *, GSW_TIMESTAMP_Timer_t *); + GSW_return_t (*Timestamp_TimerSet)(void *, GSW_TIMESTAMP_Timer_t *); /* Command: GSW_TIMESTAMP_TIMER_GET ; Index: 0x1E */ - GSW_return_t (*Timestamp_TimerGet) (void *,GSW_TIMESTAMP_Timer_t *); + GSW_return_t (*Timestamp_TimerGet)(void *, GSW_TIMESTAMP_Timer_t *); /* Command: GSW_TIMESTAMP_PORT_READ ; Index: 0x1F */ - GSW_return_t (*Timestamp_PortRead) (void *,GSW_TIMESTAMP_PortRead_t *); + GSW_return_t (*Timestamp_PortRead)(void *, GSW_TIMESTAMP_PortRead_t *); /* Command: GSW_PORT_CFG_GET ; Index: 0x20 */ - GSW_return_t (*PortCfgGet) (void *, GSW_portCfg_t *); + GSW_return_t (*PortCfgGet)(void *, GSW_portCfg_t *); /* Command: GSW_PORT_CFG_SET ; Index: 0x21 */ - GSW_return_t (*PortCfgSet) (void *, GSW_portCfg_t *); + GSW_return_t (*PortCfgSet)(void *, GSW_portCfg_t *); /* Command: GSW_MDIO_CFG_GET ; Index: 0x22 */ - GSW_return_t (*MDIO_CfgGet) (void *, GSW_MDIO_cfg_t *); + GSW_return_t (*MDIO_CfgGet)(void *, GSW_MDIO_cfg_t *); /* Command: GSW_MDIO_CFG_SET ; Index: 0x23 */ - GSW_return_t (*MDIO_CfgSet) (void *, GSW_MDIO_cfg_t *); + GSW_return_t (*MDIO_CfgSet)(void *, GSW_MDIO_cfg_t *); /* Command: GSW_MDIO_DATA_READ ; Index: 0x24 */ - GSW_return_t (*MDIO_DataRead) (void *, GSW_MDIO_data_t *); + GSW_return_t (*MDIO_DataRead)(void *, GSW_MDIO_data_t *); /* Command: GSW_MDIO_DATA_WRITE ; Index: 0x25 */ - GSW_return_t (*MDIO_DataWrite) (void *, GSW_MDIO_data_t *); + GSW_return_t (*MDIO_DataWrite)(void *, GSW_MDIO_data_t *); /* Command: GSW_MMD_DATA_READ ; Index: 0x26 */ - GSW_return_t (*MmdDataRead) (void *, GSW_MMD_data_t *); + GSW_return_t (*MmdDataRead)(void *, GSW_MMD_data_t *); /* Command: GSW_MMD_DATA_WRITE ; Index: 0x27 */ - GSW_return_t (*MmdDataWrite) (void *, GSW_MMD_data_t *); + GSW_return_t (*MmdDataWrite)(void *, GSW_MMD_data_t *); }; struct vlan_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_VLAN_MEMBER_INIT ; Index: 0x01 */ - GSW_return_t (*VLAN_Member_Init) (void *,GSW_VLAN_memberInit_t *); + GSW_return_t (*VLAN_Member_Init)(void *, GSW_VLAN_memberInit_t *); /* Command: GSW_VLAN_ID_CREATE ; Index: 0x02 */ - GSW_return_t (*VLAN_IdCreate) (void *,GSW_VLAN_IdCreate_t *); + GSW_return_t (*VLAN_IdCreate)(void *, GSW_VLAN_IdCreate_t *); /* Command: GSW_VLAN_ID_DELETE ; Index: 0x03 */ - GSW_return_t (*VLAN_IdDelete) (void *,GSW_VLAN_IdDelete_t *); + GSW_return_t (*VLAN_IdDelete)(void *, GSW_VLAN_IdDelete_t *); /* Command: GSW_VLAN_ID_GET ; Index: 0x04 */ - GSW_return_t (*VLAN_IdGet) (void *, GSW_VLAN_IdGet_t *); + GSW_return_t (*VLAN_IdGet)(void *, GSW_VLAN_IdGet_t *); /* Command: GSW_VLAN_PORT_CFG_GET ; Index: 0x05 */ - GSW_return_t (*VLAN_PortCfgGet) (void *,GSW_VLAN_portCfg_t *); + GSW_return_t (*VLAN_PortCfgGet)(void *, GSW_VLAN_portCfg_t *); /* Command: GSW_VLAN_PORT_CFG_SET ; Index: 0x06 */ - GSW_return_t (*VLAN_PortCfgSet) (void *,GSW_VLAN_portCfg_t *); + GSW_return_t (*VLAN_PortCfgSet)(void *, GSW_VLAN_portCfg_t *); /* Command: GSW_VLAN_PORT_MEMBER_ADD ; Index: 0x07 */ - GSW_return_t (*VLAN_PortMemberAdd) (void *,GSW_VLAN_portMemberAdd_t *); + GSW_return_t (*VLAN_PortMemberAdd)(void *, GSW_VLAN_portMemberAdd_t *); /* Command: GSW_VLAN_PORT_MEMBER_READ ; Index: 0x08 */ - GSW_return_t (*VLAN_PortMemberRead) (void *,GSW_VLAN_portMemberRead_t *); + GSW_return_t (*VLAN_PortMemberRead)(void *, GSW_VLAN_portMemberRead_t *); /* Command: GSW_VLAN_PORT_MEMBER_REMOVE ; Index: 0x09 */ - GSW_return_t (*VLAN_PortMemberRemove) (void *,GSW_VLAN_portMemberRemove_t *); + GSW_return_t (*VLAN_PortMemberRemove)(void *, GSW_VLAN_portMemberRemove_t *); /* Command: GSW_VLAN_RESERVED_ADD ; Index: 0x0A */ - GSW_return_t (*VLAN_ReservedAdd) (void *,GSW_VLAN_reserved_t *); + GSW_return_t (*VLAN_ReservedAdd)(void *, GSW_VLAN_reserved_t *); /* Command: GSW_VLAN_RESERVED_REMOVE ; Index: 0x0B */ - GSW_return_t (*VLAN_ReservedRemove) (void *,GSW_VLAN_reserved_t *); + GSW_return_t (*VLAN_ReservedRemove)(void *, GSW_VLAN_reserved_t *); /* Command: GSW_PCE_EG_VLAN_CFG_SET ; Index: 0x0C */ - GSW_return_t (*VLAN_PCE_EG_CfgSet) (void *,GSW_PCE_EgVLAN_Cfg_t *); + GSW_return_t (*VLAN_PCE_EG_CfgSet)(void *, GSW_PCE_EgVLAN_Cfg_t *); /* Command: GSW_PCE_EG_VLAN_CFG_GET ; Index: 0x0D */ - GSW_return_t (*VLAN_PCE_EG_CfgGet) (void *,GSW_PCE_EgVLAN_Cfg_t *); + GSW_return_t (*VLAN_PCE_EG_CfgGet)(void *, GSW_PCE_EgVLAN_Cfg_t *); /* Command: GSW_PCE_EG_VLAN_ENTRY_WRITE ; Index: 0x0E */ - GSW_return_t (*VLAN_PCE_EG_EntryWrite) (void *,GSW_PCE_EgVLAN_Entry_t *); + GSW_return_t (*VLAN_PCE_EG_EntryWrite)(void *, GSW_PCE_EgVLAN_Entry_t *); /* Command: GSW_PCE_EG_VLAN_ENTRY_READ ; Index: 0x0F */ - GSW_return_t (*VLAN_PCE_EG_EntryRead) (void *,GSW_PCE_EgVLAN_Entry_t *); + GSW_return_t (*VLAN_PCE_EG_EntryRead)(void *, GSW_PCE_EgVLAN_Entry_t *); /* Command: GSW_SVLAN_CFG_GET ; Index: 0x10 */ - GSW_return_t (*SVLAN_CfgGet) (void *,GSW_SVLAN_cfg_t *); + GSW_return_t (*SVLAN_CfgGet)(void *, GSW_SVLAN_cfg_t *); /* Command: GSW_SVLAN_CFG_SET ; Index: 0x11 */ - GSW_return_t (*SVLAN_CfgSet) (void *,GSW_SVLAN_cfg_t *); + GSW_return_t (*SVLAN_CfgSet)(void *, GSW_SVLAN_cfg_t *); /* Command: GSW_SVLAN_PORT_CFG_GET ; Index: 0x12 */ - GSW_return_t (*SVLAN_PortCfgGet) (void *,GSW_SVLAN_portCfg_t *); + GSW_return_t (*SVLAN_PortCfgGet)(void *, GSW_SVLAN_portCfg_t *); /* Command: GSW_SVLAN_PORT_CFG_SET ; Index: 0x13 */ - GSW_return_t (*SVLAN_PortCfgSet) (void *,GSW_SVLAN_portCfg_t *); + GSW_return_t (*SVLAN_PortCfgSet)(void *, GSW_SVLAN_portCfg_t *); }; /*PMAC operation*/ struct pmac_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_PMAC_COUNT_GET ; Index: 0x01 */ - int (*Pmac_CountGet) (void *, GSW_PMAC_Cnt_t *); + int (*Pmac_CountGet)(void *, GSW_PMAC_Cnt_t *); /* Command: GSW_PMAC_GLBL_CFG_SET ; Index: 0x02 */ int (*Pmac_Gbl_CfgSet)(void *, GSW_PMAC_Glbl_Cfg_t *); /* Command: GSW_PMAC_GLBL_CFG_GET ; Index: 0x03 */ @@ -505,72 +506,93 @@ struct pmac_ops { /*PAE operation*/ struct pae_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_ROUTE_ENTRY_ADD ; Index: 0x01 */ - int (*ROUTE_SessionEntryAdd) (void *, GSW_ROUTE_Entry_t *); + int (*ROUTE_SessionEntryAdd)(void *, GSW_ROUTE_Entry_t *); /* Command: GSW_ROUTE_ENTRY_DELETE ; Index: 0x02 */ - int (*ROUTE_SessionEntryDel) (void *, GSW_ROUTE_Entry_t *); + int (*ROUTE_SessionEntryDel)(void *, GSW_ROUTE_Entry_t *); /* Command: GSW_ROUTE_ENTRY_READ ; Index: 0x03 */ - int (*ROUTE_SessionEntryRead) (void *,GSW_ROUTE_Entry_t *); + int (*ROUTE_SessionEntryRead)(void *, GSW_ROUTE_Entry_t *); /* Command: GSW_ROUTE_TUNNEL_ENTRY_ADD ; Index: 0x04 */ - int (*ROUTE_TunnelEntryAdd) (void *,GSW_ROUTE_Tunnel_Entry_t *); + int (*ROUTE_TunnelEntryAdd)(void *, GSW_ROUTE_Tunnel_Entry_t *); /* Command: GSW_ROUTE_TUNNEL_ENTRY_READ ; Index: 0x05 */ - int (*ROUTE_TunnelEntryRead) (void *,GSW_ROUTE_Tunnel_Entry_t *); + int (*ROUTE_TunnelEntryRead)(void *, GSW_ROUTE_Tunnel_Entry_t *); /* Command: GSW_ROUTE_TUNNEL_ENTRY_DELETE ; Index: 0x06 */ - int (*ROUTE_TunnelEntryDel) (void *,GSW_ROUTE_Tunnel_Entry_t *); + int (*ROUTE_TunnelEntryDel)(void *, GSW_ROUTE_Tunnel_Entry_t *); /* Command: GSW_ROUTE_L2NAT_CFG_WRITE ; Index: 0x07 */ - int (*ROUTE_L2NATCfgWrite) (void *,GSW_ROUTE_EgPort_L2NAT_Cfg_t *); + int (*ROUTE_L2NATCfgWrite)(void *, GSW_ROUTE_EgPort_L2NAT_Cfg_t *); /* Command: GSW_ROUTE_L2NAT_CFG_READ ; Index: 0x08 */ - int (*ROUTE_L2NATCfgRead) (void *,GSW_ROUTE_EgPort_L2NAT_Cfg_t *); + int (*ROUTE_L2NATCfgRead)(void *, GSW_ROUTE_EgPort_L2NAT_Cfg_t *); /* Command: GSW_ROUTE_SESSION_HIT_OP ; Index: 0x09 */ - int (*ROUTE_SessHitOp) (void *,GSW_ROUTE_Session_Hit_t *); + int (*ROUTE_SessHitOp)(void *, GSW_ROUTE_Session_Hit_t *); /* Command: GSW_ROUTE_SESSION_DEST_MOD ; Index: 0x0A */ - int (*ROUTE_SessDestModify) (void *,GSW_ROUTE_Session_Dest_t *); + int (*ROUTE_SessDestModify)(void *, GSW_ROUTE_Session_Dest_t *); }; struct debug_ops { /* Command: (NULL); Index: 0x00 */ - GSW_return_t (*null) (void); + GSW_return_t (*null)(void); /* Command: GSW_DEBUG_CTPTABLE_STATUS ; Index: 0x01 */ - GSW_return_t (*DEBUG_CtpTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_CtpTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_BRDGPORTTABLE_STATUS ; Index: 0x02 */ - GSW_return_t (*DEBUG_BrgPortTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_BrgPortTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_BRDGTABLE_STATUS ; Index: 0x03 */ - GSW_return_t (*DEBUG_BrgTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_BrgTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_EXVLANTABLE_STATUS ; Index: 0x04 */ - GSW_return_t (*DEBUG_ExvlanTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_ExvlanTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_VLANFILTERTABLE_STATUS ; Index: 0x05 */ - GSW_return_t (*DEBUG_VlanFilterTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_VlanFilterTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_METERTABLE_STATUS ; Index: 0x06 */ - GSW_return_t (*DEBUG_MeterTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_MeterTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_DSCP2PCPTABLE_STATUS ; Index: 0x07 */ - GSW_return_t (*DEBUG_Dscp2PcpTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_Dscp2PcpTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_PMAPPER_STATUS ; Index: 0x08 */ - GSW_return_t (*DEBUG_PmapperTableStatus) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_PmapperTableStatus)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_PMAC_EG ; Index: 0x09 */ - GSW_return_t (*DEBUG_PmacEg) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_PmacEg)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_PMAC_IG ; Index: 0x0A */ - GSW_return_t (*DEBUG_PmacIg) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_PmacIg)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_DEF_QMAP ; Index: 0x0B */ - GSW_return_t (*DEBUG_Def_PceQmap) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_Def_PceQmap)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_DEF_BYP_QMAP ; Index: 0x0C */ - GSW_return_t (*DEBUG_Def_PceBypQmap) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_Def_PceBypQmap)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_PMAC_BP ; Index: 0x0D */ - GSW_return_t (*DEBUG_PmacBp) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_PmacBp)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_LP_STATISTICS ; Index: 0x0E */ - GSW_return_t (*DEBUG_GetLpStatistics) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_GetLpStatistics)(void *, GSW_debug_t *); /* Command: GSW_DEBUG_CTP_STATISTICS ; Index: 0x0F */ - GSW_return_t (*DEBUG_GetCtpStatistics) (void *, GSW_debug_t *); + GSW_return_t (*DEBUG_GetCtpStatistics)(void *, GSW_debug_t *); /* Command: GSW_XGMAC_CFG ; Index: 0x10 */ - GSW_return_t (*Xgmac) (void *, GSW_MAC_cfg_t *); + GSW_return_t (*Xgmac)(void *, GSW_MAC_cfg_t *); /* Command: GSW_GSWSS_CFG ; Index: 0x11 */ - GSW_return_t (*Gswss) (void *, GSW_MAC_cfg_t *); + GSW_return_t (*Gswss)(void *, GSW_MAC_cfg_t *); /* Command: GSW_LMAC_CFG ; Index: 0x12 */ - GSW_return_t (*Lmac) (void *, GSW_MAC_cfg_t *); + GSW_return_t (*Lmac)(void *, GSW_MAC_cfg_t *); + /* Command: GSW_MACSEC_CFG ; Index: 0x13 */ + GSW_return_t (*Macsec)(void *, GSW_MAC_cfg_t *); + /* Command: GSW_DUMP_MEM ; Index: 0x14 */ + GSW_return_t (*DumpMem)(void *, GSW_table_t *); + /* Command: GSW_DEBUG_PRINT_PCEIRQ_LIST ; Index: 0x15 */ + GSW_return_t (*DEBUG_PrintPceIrqList)(void *); + /* Command: GSW_DEBUG_RMON_PORT_GET ; Index: 0x16 */ + GSW_return_t (*DEBUG_RMON_Port_Get)(void *, GSW_Debug_RMON_Port_cnt_t *); +}; +struct irq_ops { + /* Command: (NULL); Index: 0x00 */ + GSW_return_t (*null)(void); + /* Command: GSW_IRQ_REGISTER ; Index: 0x01 */ + GSW_return_t (*IRQ_Register)(void *, GSW_Irq_Op_t *); + /* Command: GSW_IRQ_UNREGISTER ; Index: 0x02 */ + GSW_return_t (*IRQ_UnRegister)(void *, GSW_Irq_Op_t *); + /* Command: GSW_IRQ_ENABLE ; Index: 0x03 */ + GSW_return_t (*IRQ_Enable)(void *, GSW_Irq_Op_t *); + /* Command: GSW_IRQ_DISABLE ; Index: 0x04 */ + GSW_return_t (*IRQ_Disable)(void *, GSW_Irq_Op_t *); }; + struct core_ops { /**Switch Opertations**/ /*RMON Counters GET opertations for Port/Meter/TFlow/Redirect @@ -578,106 +600,108 @@ struct core_ops { RMON Counters CLEAR operations NOTE: Applicable for GSWIP 3.1 and GSWIP 3.0*/ - struct rmon_ops gsw_rmon_ops; + struct rmon_ops gsw_rmon_ops; /*Switch MAC table ADD/READ/QUERY/CLEAR/REMOVE operations NOTE: Applicable for GSWIP 3.1/GSWIP 3.0/GSWIP 2.2 - + Switch Defaul MAC filter SET/GET operations NOTE: Applicable for GSWIP 3.1 only*/ - struct swmac_ops gsw_swmac_ops; + struct swmac_ops gsw_swmac_ops; /*Extended VLAN Block ALLOC/SET/GET/FREE operations NOTE: Applicable for GSWIP 3.1 only*/ - struct extvlan_ops gsw_extvlan_ops; - + struct extvlan_ops gsw_extvlan_ops; + /*VLAN Filter Block ALLOC/SET/GET/FREE operations NOTE: Applicable for GSWIP 3.1 only*/ - struct vlanfilter_ops gsw_vlanfilter_ops; + struct vlanfilter_ops gsw_vlanfilter_ops; /*CTP Port ALLOC/FREE operations CTP Port Configuration SET/GET/RESET operations NOTE: Applicable for GSWIP 3.1 only*/ - - struct ctp_ops gsw_ctp_ops; + + struct ctp_ops gsw_ctp_ops; /*Bridge Port ALLOC/FREE operations Bridge Port Configuration SET/GET operations NOTE: Applicable for GSWIP 3.1 only*/ - - struct brdgport_ops gsw_brdgport_ops; - + + struct brdgport_ops gsw_brdgport_ops; + /*Bridge ALLOC/FREE operations Bridge Configuration SET/GET operations NOTE: Applicable for GSWIP 3.1 only*/ - - struct brdg_ops gsw_brdg_ops; - + + struct brdg_ops gsw_brdg_ops; + /*TFLOW PCE Rule Read/Write/Delete operations NOTE: Applicable for GSWIP 3.1/GSWIP 3.0/GSWIP 2.2*/ - - struct tflow_ops gsw_tflow_ops; + + struct tflow_ops gsw_tflow_ops; /*QOS related operations NOTE: Applicable for GSWIP 3.1/GSWIP 3.0/GSWIP 2.2*/ - - struct qos_ops gsw_qos_ops; - - /*Spanning Tree Protocol opertaions - NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct stp_ops gsw_stp_ops; - - /*Extensible Authentication Protocol opertaions + + struct qos_ops gsw_qos_ops; + + /*Spanning Tree Protocol opertaions NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct eapol_ops gsw_8021x_ops; - /*Multicast related opertaions + struct stp_ops gsw_stp_ops; + + /*Extensible Authentication Protocol opertaions NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct multicast_ops gsw_multicast_ops; - - /*Port Trunking opertaions + + struct eapol_ops gsw_8021x_ops; + + /*Multicast related opertaions NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct trunking_ops gsw_trunking_ops; - /*Wake On Lan opertaions + struct multicast_ops gsw_multicast_ops; + + /*Port Trunking opertaions NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct wol_ops gsw_wol_ops; - /*VLAN/SVLAN related opertaions - NOTE: Applicable Only for GSWIP 3.0 and below*/ - - struct vlan_ops gsw_vlan_ops; + struct trunking_ops gsw_trunking_ops; - /*PMAC related opertaions + /*Wake On Lan opertaions NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ - - struct pmac_ops gsw_pmac_ops; - - /*PAE related opertaions*/ - struct pae_ops gsw_pae_ops; - - /*Common Purpose Switch operations like - Switch REG read/write - Irq mask set/get/status clear - Switch enable/disable/reset/init - Port monitor set/get - Port link get/set - Port redirect - Time stamp,version get - Switch capablity get ..etc - NOTE: Applicable for GSWIP 3.1/GSWIP 3.0/GSWIP 2.2*/ - - struct common_ops gsw_common_ops; - /*Debug Purpose for GSWIP 3.1*/ - struct debug_ops gsw_debug_ops; + + struct wol_ops gsw_wol_ops; + + /*VLAN/SVLAN related opertaions + NOTE: Applicable Only for GSWIP 3.0 and below*/ + + struct vlan_ops gsw_vlan_ops; + + /*PMAC related opertaions + NOTE: Applicable for GSWIP 3.1/GSWIP 3.0*/ + + struct pmac_ops gsw_pmac_ops; + + /*PAE related opertaions*/ + struct pae_ops gsw_pae_ops; + + /*Common Purpose Switch operations like + Switch REG read/write + Irq mask set/get/status clear + Switch enable/disable/reset/init + Port monitor set/get + Port link get/set + Port redirect + Time stamp,version get + Switch capablity get ..etc + NOTE: Applicable for GSWIP 3.1/GSWIP 3.0/GSWIP 2.2*/ + + struct common_ops gsw_common_ops; + /*Debug Purpose for GSWIP 3.1*/ + struct debug_ops gsw_debug_ops; + + struct irq_ops gsw_irq_ops; }; diff --git a/include/net/switch_api/gsw_ioctlcmd_type.h b/include/net/switch_api/gsw_ioctlcmd_type.h index 33d1130f7b23c165ba3128cd9fc8f9c9e1447ba5..a41af3f435c1c6d244933124568f6c61c927e9f1 100644 --- a/include/net/switch_api/gsw_ioctlcmd_type.h +++ b/include/net/switch_api/gsw_ioctlcmd_type.h @@ -54,7 +54,8 @@ this software module. #define GSW_FLOW_MAGIC ('W') /* IOCTL DEBUG */ #define GSW_DEBUG_MAGIC ('V') - +/* IRQ */ +#define GSW_IRQ_MAGIC ('T') #endif diff --git a/include/net/switch_api/gsw_irq.h b/include/net/switch_api/gsw_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..900f7eb45761c5534d05f676fc3857efb0541165 --- /dev/null +++ b/include/net/switch_api/gsw_irq.h @@ -0,0 +1,80 @@ +/****************************************************************************** + Copyright (c) 2016, 2017 Intel Corporation + +For licensing information, see the file 'LICENSE' in the root folder of +this software module. +******************************************************************************/ + + +#ifndef _GSW_IRQ_H_ +#define _GSW_IRQ_H_ + +typedef struct { + unsigned int blk; + unsigned int event; + unsigned int portid; + void *call_back; + void *param; +} GSW_Irq_Op_t; + +typedef enum { + BM = 0, + SDMA = 1, + FDMA = 2, + PCE = 3, + PMAC = 4 +} GSWIP_IRQ_BLK; + +typedef enum { + PCE_INVALID_EVENT_IERQ = 0xFE, + PCE_INVALID_PORT_IERQ = 0xFF +} GSWIP_PCE_INVALID_IERQ; + +typedef enum { + PCE_MAC_TABLE_FULL = 0, + PCE_IGMP_TABLE_FULL = 1, + PCE_PARSER_READY = 2, + PCE_CLASSIFICATION_PHASE_0 = 3, + PCE_CLASSIFICATION_PHASE_1 = 4, + PCE_CLASSIFICATION_PHASE_2 = 5, + PCE_FLOW_TABLE_RULE_MATCHED = 6, + PCE_MAC_TABLE_CHANGE = 7, +} GSWIP_PCE_EVENT; + + +typedef enum { + XGMAC_BLK = 0, + LMAC_BLK = 1, +} MAC_IRQ_BLK; + +typedef enum { + XGMAC_TSTAMP_EVNT = 0, + XGMAC_LPI_EVNT, + XGMAC_TXERR_STS_EVNT, + XGMAC_RXERR_STS_EVNT, + XGMAC_PMT_EVNT, + XGMAC_TXQ_OVFW_EVNT, + XGMAC_RXQ_OVFW_EVNT, + XGMAC_AVG_BPS_EVNT, + LMAC_PHYERR_EVNT, + LMAC_ALIGN_EVNT, + LMAC_SPEED_EVNT, + LMAC_FDUP_EVNT, + LMAC_RXPAUEN_EVNT, + LMAC_TXPAUEN_EVNT, + LMAC_LPIOFF_EVNT, + LMAC_LPION_EVNT, + LMAC_JAM_EVNT, + LMAC_FCSERR_EVNT, + LMAC_TXPAU_EVNT, + LMAC_RXPAU_EVNT, + MAX_IRQ_EVNT, + XGMAC_ALL_EVNT, + LMAC_ALL_EVNT +} MAC_IRQ_ENT; + + +// TODO: MACSec IRq Events need to add +#define MACSEC_MAX_IRQ_EVENT 10 + +#endif \ No newline at end of file diff --git a/include/net/switch_api/gsw_tbl_rw.h b/include/net/switch_api/gsw_tbl_rw.h new file mode 100644 index 0000000000000000000000000000000000000000..3438d1e0223f6ab2abf405fcd9ce60ba68ebc56c --- /dev/null +++ b/include/net/switch_api/gsw_tbl_rw.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * Copyright (c) 2016, 2017 Intel Corporation + * + * + * For licensing information, see the file 'LICENSE' in the root folder of + * this software module. + * + ******************************************************************************/ + +#ifndef _GSW_TBL_RW_H_ +#define _GSW_TBL_RW_H_ + +#include "gsw_types.h" + +/* GSWIP PCE Table Programming structure */ +typedef struct { + u16 key[34]; + u16 mask[4]; + u16 val[31]; + u16 table; + u16 pcindex; + u16 op_mode: 2; + u16 extop: 1; + u16 kformat: 1; + u16 type: 1; + u16 valid: 1; + u16 group: 4; +} pctbl_prog_t; + +/* GSWIP BM Table ID to access different tables */ +typedef enum { + CTP_PORT_RX_RMON = 0x00, + CTP_PORT_TX_RMON = 0x01, + BRIDGE_PORT_RX_RMON = 0x02, + BRIDGE_PORT_TX_RMON = 0x03, + CTP_PORT_PCE_BYPASS_TX_RMON = 0x04, + FLOW_RX_RMON = 0x05, + FLOW_TX_RMON = 0x06, + WFQ_PARAM = 0x08, + PQM_THRESHOLD = 0x09, + PQM_PACKET_PTR = 0x0A, + SSL_NEXT_PTR_MEM = 0x0B, + SSL_HEADER_DES_MEM1 = 0x0C, + SSL_HEADER_DES_MEM2 = 0x0D, + BUF_MGR_Q_MAP_TABLE = 0x0E, + METER_RMON_COUNTER = 0x19, + ROUTING_RMON_COUNTER = 0x1B, + PMAC_RMON_COUNTER = 0x1C, +} BM_Table_ID; + +/* GSWIP BM Table Address */ +typedef union { + u16 raw; +#if CONFIG_CPU_BIG_ENDIAN + struct { + u16 b15: 1, b14: 1, b13: 1, b12: 1, b11: 1, b10: 1, b9: 1, b8: 1, + b7: 1, b6: 1, b5: 1, b4: 1, b3: 1, b2: 1, b1: 1, b0: 1; + } bits; + struct { + u16 portOffset: 10, counterOffset: 6; + } rmon; + struct { + u16 reserved0: 10, nQueueId: 6; + } wfq; + struct { + u16 reserved1: 7, nQueueId: 6, mode: 1, color_or_submode: 2; + } pqmThr; + struct { + u16 reserved2: 5, ptr: 11; + } pqmPtr; + struct { + u16 reserved3: 6, ptr: 10; + } ssl; + struct { + u16 reserved4: 10, nQueueId: 6; + } qMapTbl; + struct { + u16 reserved6: 6, color: 2, reserved5: 1, meterNo: 7; + } meterRmon; + struct { + u16 reserved7: 8, counterType: 4, portNo: 4 ; + } routingRmon; + struct { + u16 reserved8: 5, pmacNo: 3, count: 3, channel_or_port: 5; + } pmacRmon; +#else + struct { + u16 b0: 1, b1: 1, b2: 1, b3: 1, b4: 1, b5: 1, b6: 1, b7: 1, + b8: 1, b9: 1, b10: 1, b11: 1, b12: 1, b13: 1, b14: 1, b15: 1; + } bits; + struct { + u16 counterOffset: 6, portOffset: 10; + } rmon; + struct { + u16 nQueueId: 6, reserved0: 10; + } wfq; + struct { + u16 color_or_submode: 2, mode: 1, nQueueId: 6, reserved1: 7; + } pqmThr; + struct { + u16 ptr: 11, reserved2: 5; + } pqmPtr; + struct { + u16 ptr: 10, reserved3: 6; + } ssl; + struct { + u16 nQueueId: 6, reserved4: 10; + } qMapTbl; + struct { + u16 meterNo: 7, reserved5: 1, color: 2, reserved6: 6; + } meterRmon; + struct { + u16 portNo: 4, counterType: 4, reserved7: 8; + } routingRmon; + struct { + u16 channel_or_port: 5, count: 3, pmacNo: 3, reserved8: 5; + } pmacRmon; +#endif + +} BM_Table_Address ; + +/* GSWIP BM Table programming structure */ +typedef struct { + BM_Table_ID tableID; + BM_Table_Address adr; + u32 value[10]; + ltq_bool_t b64bitMode; + u32 numValues; +} bmtbl_prog_t; + +/* GSWIP PMAC Table programming structure */ +typedef struct { + u16 val[8]; + u16 ptaddr; + u16 ptcaddr; + u16 op_mode; + u16 pmacId; + /* u16 valid:1; */ +} pmtbl_prog_t; + +/* GSWIP Table structure to access all tables */ +typedef struct { + u8 tbl_entry; + /** Start offset mem dump purpose */ + u32 tbl_addr; + u32 tbl_id; + u32 bm_numValues; + pctbl_prog_t ptdata; + bmtbl_prog_t bmtable; + pmtbl_prog_t pmactable; +} GSW_table_t; + +int gsw_pce_table_write(void *cdev, pctbl_prog_t *ptdata); +int gsw_pce_table_read(void *cdev, pctbl_prog_t *ptdata); +int xwayflow_pmac_table_read(void *cdev, pmtbl_prog_t *ptdata); +int xwayflow_pmac_table_write(void *cdev, pmtbl_prog_t *ptdata); +int route_table_read(void *cdev, pctbl_prog_t *rdata); +int route_table_write(void *cdev, pctbl_prog_t *rdata); +GSW_return_t gsw_bm_table_read(void *cdev, bmtbl_prog_t *ptdata); +GSW_return_t gsw_bm_table_write(void *cdev, bmtbl_prog_t *ptdata); +u32 pmac_addr_off(u32 off, u32 id); + +#endif + diff --git a/include/net/switch_api/gsw_types.h b/include/net/switch_api/gsw_types.h index 880432325adef233c3f29994033794dfb95cea54..713562f7f3f01945336e7ca544d701cdc10c1452 100644 --- a/include/net/switch_api/gsw_types.h +++ b/include/net/switch_api/gsw_types.h @@ -18,11 +18,11 @@ #define GSW_MAC_ADDR_LEN 6 /** \brief Instantiated tables entries name string length. The user can supply a name and get in return an id from Switch API. */ -#define GSW_NAME_LEN 32 +#define GSW_NAME_LEN 32 /** \brief This is the unsigned 64-bit datatype. */ typedef unsigned long long u64; /** \brief This is the unsigned 32-bit datatype. */ -typedef unsigned int u32; +typedef unsigned int u32; /** \brief This is the unsigned 8-bit datatype. */ typedef unsigned char u8; /** \brief This is the unsigned 16-bit datatype. */ @@ -33,15 +33,6 @@ typedef short i16; typedef char i8; /** \brief This is the signed 32-bit datatype. */ typedef long i32; -#if 0 -/** \brief This enumeration type has two operation states, disable and enable. */ -typedef enum { - /** Disable Operation. */ - LTQ_DISABLE = 0, - /** Enable Operation. */ - LTQ_ENABLE = 1 -} ltq_enDis_t; -#endif /** \brief This enumeration type defines two boolean states: False and True. */ typedef enum { @@ -52,28 +43,26 @@ typedef enum { } ltq_bool_t; /** \brief This is a union to describe the IPv4 and IPv6 Address in numeric representation. Used by multiple Structures and APIs. The member selection would be based upon \ref GSW_IP_Select_t */ -typedef union -{ - /** Describe the IPv4 address. - Only used if the IPv4 address should be read or configured. - Cannot be used together with the IPv6 address fields. */ - u32 nIPv4; - /** Describe the IPv6 address. - Only used if the IPv6 address should be read or configured. - Cannot be used together with the IPv4 address fields. */ - u16 nIPv6[8]; +typedef union { + /** Describe the IPv4 address. + Only used if the IPv4 address should be read or configured. + Cannot be used together with the IPv6 address fields. */ + u32 nIPv4; + /** Describe the IPv6 address. + Only used if the IPv6 address should be read or configured. + Cannot be used together with the IPv4 address fields. */ + u16 nIPv6[8]; } GSW_IP_t; /** \brief Selection to use IPv4 or IPv6. Used along with \ref GSW_IP_t to denote which union member to be accessed. */ -typedef enum -{ - /** IPv4 Type */ - GSW_IP_SELECT_IPV4 = 0, - /** IPv6 Type */ - GSW_IP_SELECT_IPV6 = 1 +typedef enum { + /** IPv4 Type */ + GSW_IP_SELECT_IPV4 = 0, + /** IPv6 Type */ + GSW_IP_SELECT_IPV6 = 1 } GSW_IP_Select_t; -#endif +#endif diff --git a/include/net/switch_api/lantiq_gsw.h b/include/net/switch_api/lantiq_gsw.h index c54fceb89ecabf3f21b52e60682890f576da84df..63625790607e87f47ad48b530c6a38bcd9d912d6 100644 --- a/include/net/switch_api/lantiq_gsw.h +++ b/include/net/switch_api/lantiq_gsw.h @@ -21,9 +21,9 @@ /* ============================= */ /* Local Macros & Definitions */ /* ============================= */ - #include "gsw_types.h" + /** \defgroup GSW_GROUP GSWIP Functional APIs \brief This chapter describes the entire interface for accessing and configuring the different services of the Ethernet Switch module. The prefix GSW (Gigabit Switch) is used for all data structures and APIs pertaining to GSWIP. */ @@ -73,379 +73,376 @@ /*@{*/ /** \brief MAC Table Entry to be read. Used by \ref GSW_MAC_TABLE_ENTRY_READ. */ -typedef struct -{ - /** Restart the get operation from the beginning of the table. Otherwise - return the next table entry (next to the entry that was returned - during the previous get operation). This boolean parameter is set by the - calling application. */ - ltq_bool_t bInitial; - /** Indicates that the read operation got all last valid entries of the - table. This boolean parameter is set by the switch API - when the Switch API is called after the last valid one was returned already. */ - ltq_bool_t bLast; - /** Get the MAC table entry belonging to the given Filtering Identifier - (not supported by all switches). */ - u32 nFId; - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. - - \remarks - In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB - bit is set. In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. - From GSWIP3.1, if MSB is set, other bits in this field are ignored. - array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ - u32 nPortId; - /** Bridge Port Map - to support GSWIP-3.1, following field is added - for port map in static entry. It's valid only when MSB of - \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge - port. */ - u16 nPortMap[16]; - /** Aging Time, given in multiples of 1 second in a range from 1 s to 1,000,000 s. - The value read back in a GET command might differ slightly from the value - given in the SET command due to limited hardware timing resolution. - Filled out by the switch API implementation. */ - int nAgeTimer; - /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ - u16 nSVLAN_Id; - /** Static Entry (value will be aged out after 'nAgeTimer' if the entry - is not set to static). */ - ltq_bool_t bStaticEntry; - /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). */ - u16 nSubIfId; - /** MAC Address. Filled out by the switch API implementation. */ - u8 nMAC[GSW_MAC_ADDR_LEN]; - /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) - Value 0 - not filter, 1 - source address filter, - 2 - destination address filter, 3 - both source and destination filter. - - \remarks - Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 - "Source MAC Address Filtering and Destination MAC Address Filtering" - for more detail. */ - u8 nFilterFlag; - /** Packet is marked as IGMP controlled if destination MAC address matches - MAC in this entry. (GSWIP-3.1 only) */ - ltq_bool_t bIgmpControlled; +typedef struct { + /** Restart the get operation from the beginning of the table. Otherwise + return the next table entry (next to the entry that was returned + during the previous get operation). This boolean parameter is set by the + calling application. */ + ltq_bool_t bInitial; + /** Indicates that the read operation got all last valid entries of the + table. This boolean parameter is set by the switch API + when the Switch API is called after the last valid one was returned already. */ + ltq_bool_t bLast; + /** Get the MAC table entry belonging to the given Filtering Identifier + (not supported by all switches). */ + u32 nFId; + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. + + \remarks + In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB + bit is set. In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. + From GSWIP3.1, if MSB is set, other bits in this field are ignored. + array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ + u32 nPortId; + /** Bridge Port Map - to support GSWIP-3.1, following field is added + for port map in static entry. It's valid only when MSB of + \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge + port. */ + u16 nPortMap[16]; + /** Aging Time, given in multiples of 1 second in a range from 1 s to 1,000,000 s. + The value read back in a GET command might differ slightly from the value + given in the SET command due to limited hardware timing resolution. + Filled out by the switch API implementation. */ + int nAgeTimer; + /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ + u16 nSVLAN_Id; + /** Static Entry (value will be aged out after 'nAgeTimer' if the entry + is not set to static). */ + ltq_bool_t bStaticEntry; + /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). */ + u16 nSubIfId; + /** MAC Address. Filled out by the switch API implementation. */ + u8 nMAC[GSW_MAC_ADDR_LEN]; + /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) + Value 0 - not filter, 1 - source address filter, + 2 - destination address filter, 3 - both source and destination filter. + + \remarks + Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 + "Source MAC Address Filtering and Destination MAC Address Filtering" + for more detail. */ + u8 nFilterFlag; + /** Packet is marked as IGMP controlled if destination MAC address matches + MAC in this entry. (GSWIP-3.1 only) */ + ltq_bool_t bIgmpControlled; + + /** Changed + � 0: the entry is not changed + � 1: the entry is changed and not accessed yet */ + + ltq_bool_t bEntryChanged; } GSW_MAC_tableRead_t; /** \brief Search for a MAC address entry in the address table. Used by \ref GSW_MAC_TABLE_ENTRY_QUERY. */ -typedef struct -{ - /** MAC Address. This parameter needs to be provided for the search operation. - This is an input parameter. */ - u8 nMAC[GSW_MAC_ADDR_LEN]; - /** Get the MAC table entry belonging to the given Filtering Identifier - (not supported by all switches). - This is an input parameter. */ - u32 nFId; - /** MAC Address Found. Switch API sets this boolean variable in case - the requested MAC address 'nMAC' is found inside the address table, - otherwise it is set to FALSE. - This is an output parameter. */ - ltq_bool_t bFound; - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge port ID. The valid range is hardware - dependent. - - \remarks - In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB - bit is set. In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. - From GSWIP3.1, if MSB is set, other bits in this field are ignored. - array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ - u32 nPortId; - /** Bridge Port Map - to support GSWIP-3.1, following field is added - for port map in static entry. It's valid only when MSB of - \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge - port. */ - u16 nPortMap[16]; - /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). */ - u16 nSubIfId; - /** Aging Time, given in multiples of 1 second in a range from 1 s to 1,000,000 s. - The value read back in a GET command might differ slightly from the value - given in the SET command due to limited hardware timing resolution. - Filled out by the switch API implementation. - This is an output parameter. */ - int nAgeTimer; - /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ - u16 nSVLAN_Id; - /** Static Entry (value will be aged out after 'nAgeTimer' if the entry - is not set to static). - This is an output parameter. */ - ltq_bool_t bStaticEntry; - /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) - Value 0 - not filter, 1 - source address filter, - 2 - destination address filter, 3 - both source and destination filter. - - \remarks - Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 - "Source MAC Address Filtering and Destination MAC Address Filtering" - for more detail. */ - u8 nFilterFlag; - - /** Packet is marked as IGMP controlled if destination MAC address matches - MAC in this entry. (GSWIP-3.1 only) */ - ltq_bool_t bIgmpControlled; - +typedef struct { + /** MAC Address. This parameter needs to be provided for the search operation. + This is an input parameter. */ + u8 nMAC[GSW_MAC_ADDR_LEN]; + /** Get the MAC table entry belonging to the given Filtering Identifier + (not supported by all switches). + This is an input parameter. */ + u32 nFId; + /** MAC Address Found. Switch API sets this boolean variable in case + the requested MAC address 'nMAC' is found inside the address table, + otherwise it is set to FALSE. + This is an output parameter. */ + ltq_bool_t bFound; + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge port ID. The valid range is hardware + dependent. + + \remarks + In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB + bit is set. In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. + From GSWIP3.1, if MSB is set, other bits in this field are ignored. + array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ + u32 nPortId; + /** Bridge Port Map - to support GSWIP-3.1, following field is added + for port map in static entry. It's valid only when MSB of + \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge + port. */ + u16 nPortMap[16]; + /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). */ + u16 nSubIfId; + /** Aging Time, given in multiples of 1 second in a range from 1 s to 1,000,000 s. + The value read back in a GET command might differ slightly from the value + given in the SET command due to limited hardware timing resolution. + Filled out by the switch API implementation. + This is an output parameter. */ + int nAgeTimer; + /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ + u16 nSVLAN_Id; + /** Static Entry (value will be aged out after 'nAgeTimer' if the entry + is not set to static). + This is an output parameter. */ + ltq_bool_t bStaticEntry; + /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) + Value 0 - not filter, 1 - source address filter, + 2 - destination address filter, 3 - both source and destination filter. + + \remarks + Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 + "Source MAC Address Filtering and Destination MAC Address Filtering" + for more detail. */ + u8 nFilterFlag; + + /** Packet is marked as IGMP controlled if destination MAC address matches + MAC in this entry. (GSWIP-3.1 only) */ + ltq_bool_t bIgmpControlled; + + /** Changed + � 0: the entry is not changed + � 1: the entry is changed and not accessed yet */ + ltq_bool_t bEntryChanged; } GSW_MAC_tableQuery_t; /** \brief MAC Table Entry to be added. Used by \ref GSW_MAC_TABLE_ENTRY_ADD. */ -typedef struct -{ - /** Filtering Identifier (FID) (not supported by all switches) */ - u32 nFId; - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. - - \remarks - In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB - bit is set. In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. - From GSWIP3.1, if MSB is set, other bits in this field are ignored. - array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ - u32 nPortId; - /** Bridge Port Map - to support GSWIP-3.1, following field is added - for port map in static entry. It's valid only when MSB of - \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge - port. */ - u16 nPortMap[16]; - /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). - - \remarks - In GSWIP-3.1, this field is sub interface ID for WLAN logical port. For - Other types, either outer VLAN ID if Nto1Vlan enabled or 0. */ - u16 nSubIfId; - /** Aging Time, given in multiples of 1 second in a range - from 1 s to 1,000,000 s. - The configured value might be rounded that it fits to the given hardware platform. */ - int nAgeTimer; - /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ - u16 nSVLAN_Id; - /** Static Entry (value will be aged out if the entry is not set to static). The - switch API implementation uses the maximum age timer in case the entry - is not static. */ - ltq_bool_t bStaticEntry; - /** Egress queue traffic class. - The queue index starts counting from zero. */ - u8 nTrafficClass; - /** MAC Address to add to the table. */ - u8 nMAC[GSW_MAC_ADDR_LEN]; - /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) - Value 0 - not filter, 1 - source address filter, - 2 - destination address filter, 3 - both source and destination filter. - - \remarks - Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 - "Source MAC Address Filtering and Destination MAC Address Filtering" - for more detail. */ - u8 nFilterFlag; - /** Packet is marked as IGMP controlled if destination MAC address matches - MAC in this entry. (GSWIP-3.1 only) */ - ltq_bool_t bIgmpControlled; +typedef struct { + /** Filtering Identifier (FID) (not supported by all switches) */ + u32 nFId; + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. + + \remarks + In GSWIP-2.1/2.2/3.0, this field is used as portmap field, when the MSB + bit is set. In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. + From GSWIP3.1, if MSB is set, other bits in this field are ignored. + array \ref GSW_MAC_tableRead_t::nPortMap is used for bit map. */ + u32 nPortId; + /** Bridge Port Map - to support GSWIP-3.1, following field is added + for port map in static entry. It's valid only when MSB of + \ref GSW_MAC_tableRead_t::nPortId is set. Each bit stands for 1 bridge + port. */ + u16 nPortMap[16]; + /** Sub-Interface Identifier Destination (supported in GSWIP-3.0/3.1 only). + + \remarks + In GSWIP-3.1, this field is sub interface ID for WLAN logical port. For + Other types, either outer VLAN ID if Nto1Vlan enabled or 0. */ + u16 nSubIfId; + /** Aging Time, given in multiples of 1 second in a range + from 1 s to 1,000,000 s. + The configured value might be rounded that it fits to the given hardware platform. */ + int nAgeTimer; + /** STAG VLAN Id. Only applicable in case SVLAN support is enabled on the device. */ + u16 nSVLAN_Id; + /** Static Entry (value will be aged out if the entry is not set to static). The + switch API implementation uses the maximum age timer in case the entry + is not static. */ + ltq_bool_t bStaticEntry; + /** Egress queue traffic class. + The queue index starts counting from zero. */ + u8 nTrafficClass; + /** MAC Address to add to the table. */ + u8 nMAC[GSW_MAC_ADDR_LEN]; + /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) + Value 0 - not filter, 1 - source address filter, + 2 - destination address filter, 3 - both source and destination filter. + + \remarks + Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 + "Source MAC Address Filtering and Destination MAC Address Filtering" + for more detail. */ + u8 nFilterFlag; + /** Packet is marked as IGMP controlled if destination MAC address matches + MAC in this entry. (GSWIP-3.1 only) */ + ltq_bool_t bIgmpControlled; } GSW_MAC_tableAdd_t; /** \brief MAC Table Entry to be removed. Used by \ref GSW_MAC_TABLE_ENTRY_REMOVE. */ -typedef struct -{ - /** Filtering Identifier (FID) (not supported by all switches) */ - u32 nFId; - /** MAC Address to be removed from the table. */ - u8 nMAC[GSW_MAC_ADDR_LEN]; - /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) - Value 0 - not filter, 1 - source address filter, - 2 - destination address filter, 3 - both source and destination filter. - - \remarks - Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 - "Source MAC Address Filtering and Destination MAC Address Filtering" - for more detail. */ - u8 nFilterFlag; +typedef struct { + /** Filtering Identifier (FID) (not supported by all switches) */ + u32 nFId; + /** MAC Address to be removed from the table. */ + u8 nMAC[GSW_MAC_ADDR_LEN]; + /** Source/Destination MAC address filtering flag (GSWIP-3.1 only) + Value 0 - not filter, 1 - source address filter, + 2 - destination address filter, 3 - both source and destination filter. + + \remarks + Please refer to "GSWIP Hardware Architecture Spec" chapter 3.4.4.6 + "Source MAC Address Filtering and Destination MAC Address Filtering" + for more detail. */ + u8 nFilterFlag; } GSW_MAC_tableRemove_t; /** \brief Packet forwarding. Used by \ref GSW_STP_BPDU_Rule_t and \ref GSW_multicastSnoopCfg_t and \ref GSW_8021X_EAPOL_Rule_t. */ -typedef enum -{ - /** Default; portmap is determined by the forwarding classification. */ - GSW_PORT_FORWARD_DEFAULT = 0, - /** Discard; discard packets. */ - GSW_PORT_FORWARD_DISCARD = 1, - /** Forward to the CPU port. This requires that the CPU port is previously - set by calling \ref GSW_CPU_PORT_CFG_SET. */ - GSW_PORT_FORWARD_CPU = 2, - /** Forward to a port, selected by the parameter 'nForwardPortId'. - Please note that this feature is not supported by all - hardware platforms. */ - GSW_PORT_FORWARD_PORT = 3 +typedef enum { + /** Default; portmap is determined by the forwarding classification. */ + GSW_PORT_FORWARD_DEFAULT = 0, + /** Discard; discard packets. */ + GSW_PORT_FORWARD_DISCARD = 1, + /** Forward to the CPU port. This requires that the CPU port is previously + set by calling \ref GSW_CPU_PORT_CFG_SET. */ + GSW_PORT_FORWARD_CPU = 2, + /** Forward to a port, selected by the parameter 'nForwardPortId'. + Please note that this feature is not supported by all + hardware platforms. */ + GSW_PORT_FORWARD_PORT = 3 } GSW_portForward_t; /** \brief Spanning Tree Protocol port states. Used by \ref GSW_STP_portCfg_t. */ -typedef enum -{ - /** Forwarding state. The port is allowed to transmit and receive - all packets. Address Learning is allowed. */ - GSW_STP_PORT_STATE_FORWARD = 0, - /** Disabled/Discarding state. The port entity will not transmit - and receive any packets. Learning is disabled in this state. */ - GSW_STP_PORT_STATE_DISABLE = 1, - /** Learning state. The port entity will only transmit and receive - Spanning Tree Protocol packets (BPDU). All other packets are discarded. - MAC table address learning is enabled for all good frames. */ - GSW_STP_PORT_STATE_LEARNING = 2, - /** Blocking/Listening. Only the Spanning Tree Protocol packets will - be received and transmitted. All other packets are discarded by - the port entity. MAC table address learning is disabled in this - state. */ - GSW_STP_PORT_STATE_BLOCKING = 3 +typedef enum { + /** Forwarding state. The port is allowed to transmit and receive + all packets. Address Learning is allowed. */ + GSW_STP_PORT_STATE_FORWARD = 0, + /** Disabled/Discarding state. The port entity will not transmit + and receive any packets. Learning is disabled in this state. */ + GSW_STP_PORT_STATE_DISABLE = 1, + /** Learning state. The port entity will only transmit and receive + Spanning Tree Protocol packets (BPDU). All other packets are discarded. + MAC table address learning is enabled for all good frames. */ + GSW_STP_PORT_STATE_LEARNING = 2, + /** Blocking/Listening. Only the Spanning Tree Protocol packets will + be received and transmitted. All other packets are discarded by + the port entity. MAC table address learning is disabled in this + state. */ + GSW_STP_PORT_STATE_BLOCKING = 3 } GSW_STP_PortState_t; /** \brief Configures the Spanning Tree Protocol state of an Ethernet port. Used by \ref GSW_STP_PORT_CFG_SET and \ref GSW_STP_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u32 nPortId; - /** Filtering Identifier (FID) (not supported by all switches). - The FID allows to keep multiple STP states per physical Ethernet port. - Multiple CTAG VLAN groups could be a assigned to one FID and therefore - share the same STP port state. Switch API ignores the FID value - in case the switch device does not support it or switch CTAG VLAN - awareness is disabled. */ - u32 nFId; - /** Spanning Tree Protocol state of the port. */ - GSW_STP_PortState_t ePortState; +typedef struct { + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u32 nPortId; + /** Filtering Identifier (FID) (not supported by all switches). + The FID allows to keep multiple STP states per physical Ethernet port. + Multiple CTAG VLAN groups could be a assigned to one FID and therefore + share the same STP port state. Switch API ignores the FID value + in case the switch device does not support it or switch CTAG VLAN + awareness is disabled. */ + u32 nFId; + /** Spanning Tree Protocol state of the port. */ + GSW_STP_PortState_t ePortState; } GSW_STP_portCfg_t; /** \brief Spanning tree packet detection and forwarding. Used by \ref GSW_STP_BPDU_RULE_SET and \ref GSW_STP_BPDU_RULE_GET. */ -typedef struct -{ - /** Filter spanning tree packets and forward them, discard them or - disable the filter. */ - GSW_portForward_t eForwardPort; - /** Target (bridge) port for forwarded packets; only used if selected by - 'eForwardPort'. Forwarding is done - if 'eForwardPort = GSW_PORT_FORWARD_PORT'. */ - u8 nForwardPortId; +typedef struct { + /** Filter spanning tree packets and forward them, discard them or + disable the filter. */ + GSW_portForward_t eForwardPort; + /** Target (bridge) port for forwarded packets; only used if selected by + 'eForwardPort'. Forwarding is done + if 'eForwardPort = GSW_PORT_FORWARD_PORT'. */ + u8 nForwardPortId; } GSW_STP_BPDU_Rule_t; /** \brief Describes the 802.1x port state. Used by \ref GSW_8021X_portCfg_t. */ -typedef enum -{ - /** Receive and transmit direction are authorized. The port is allowed to - transmit and receive all packets and the address learning process is - also allowed. */ - GSW_8021X_PORT_STATE_AUTHORIZED = 0, - /** Receive and transmit direction are unauthorized. All the packets - except EAPOL are not allowed to transmit and receive. The address learning - process is disabled. */ - GSW_8021X_PORT_STATE_UNAUTHORIZED = 1, - /** Receive direction is authorized, transmit direction is unauthorized. - The port is allowed to receive all packets. Packet transmission to this - port is not allowed. The address learning process is also allowed. */ - GSW_8021X_PORT_STATE_RX_AUTHORIZED = 2, - /** Transmit direction is authorized, receive direction is unauthorized. - The port is allowed to transmit all packets. Packet reception on this - port is not allowed. The address learning process is disabled. */ - GSW_8021X_PORT_STATE_TX_AUTHORIZED = 3 +typedef enum { + /** Receive and transmit direction are authorized. The port is allowed to + transmit and receive all packets and the address learning process is + also allowed. */ + GSW_8021X_PORT_STATE_AUTHORIZED = 0, + /** Receive and transmit direction are unauthorized. All the packets + except EAPOL are not allowed to transmit and receive. The address learning + process is disabled. */ + GSW_8021X_PORT_STATE_UNAUTHORIZED = 1, + /** Receive direction is authorized, transmit direction is unauthorized. + The port is allowed to receive all packets. Packet transmission to this + port is not allowed. The address learning process is also allowed. */ + GSW_8021X_PORT_STATE_RX_AUTHORIZED = 2, + /** Transmit direction is authorized, receive direction is unauthorized. + The port is allowed to transmit all packets. Packet reception on this + port is not allowed. The address learning process is disabled. */ + GSW_8021X_PORT_STATE_TX_AUTHORIZED = 3 } GSW_8021X_portState_t; /** \brief EAPOL frames filtering rule parameter. Used by \ref GSW_8021X_EAPOL_RULE_GET and \ref GSW_8021X_EAPOL_RULE_SET. */ -typedef struct -{ - /** Filter authentication packets and forward them, discard them or - disable the filter. */ - GSW_portForward_t eForwardPort; - /** Target (bridge) port for forwarded packets, only used if selected by - 'eForwardPort'. Forwarding is done - if 'eForwardPort = GSW_PORT_FORWARD_PORT'. */ - u8 nForwardPortId; +typedef struct { + /** Filter authentication packets and forward them, discard them or + disable the filter. */ + GSW_portForward_t eForwardPort; + /** Target (bridge) port for forwarded packets, only used if selected by + 'eForwardPort'. Forwarding is done + if 'eForwardPort = GSW_PORT_FORWARD_PORT'. */ + u8 nForwardPortId; } GSW_8021X_EAPOL_Rule_t; /** \brief 802.1x port authentication status. Used by \ref GSW_8021X_PORT_CFG_GET and \ref GSW_8021X_PORT_CFG_SET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u32 nPortId; - /** 802.1x state of the port. */ - GSW_8021X_portState_t eState; +typedef struct { + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u32 nPortId; + /** 802.1x state of the port. */ + GSW_8021X_portState_t eState; } GSW_8021X_portCfg_t; /** \brief Global Ethernet trunking configuration. Used by \ref GSW_TRUNKING_CFG_GET and \ref GSW_TRUNKING_CFG_SET. */ -typedef struct -{ - /** IP source address is used by the - hash algorithm to calculate the egress trunking port index. */ - ltq_bool_t bIP_Src; - /** IP destination address is used by the - hash algorithm to calculate the egress trunking port index. */ - ltq_bool_t bIP_Dst; - /** MAC source address is used by the - hash algorithm to calculate the egress trunking port index. */ - ltq_bool_t bMAC_Src; - /** MAC destination address is used by the - hash algorithm to calculate the egress trunking port index. */ - ltq_bool_t bMAC_Dst; +typedef struct { + /** IP source address is used by the + hash algorithm to calculate the egress trunking port index. */ + ltq_bool_t bIP_Src; + /** IP destination address is used by the + hash algorithm to calculate the egress trunking port index. */ + ltq_bool_t bIP_Dst; + /** MAC source address is used by the + hash algorithm to calculate the egress trunking port index. */ + ltq_bool_t bMAC_Src; + /** MAC destination address is used by the + hash algorithm to calculate the egress trunking port index. */ + ltq_bool_t bMAC_Dst; } GSW_trunkingCfg_t; /** \brief Ethernet port trunking configuration. Used by \ref GSW_TRUNKING_PORT_CFG_GET and \ref GSW_TRUNKING_PORT_CFG_SET. */ -typedef struct -{ - /** Ports are aggregated. - Enabling means that the 'nPortId' and - the 'nAggrPortId' ports form an aggregated link. */ - ltq_bool_t bAggregateEnable; - /** Ethernet Port number (zero-based counting). - The valid range is hardware dependent. - An error code is delivered if the selected port is not - available. */ - u32 nPortId; - /** Second Aggregated Ethernet Port number (zero-based counting). - The valid range is hardware dependent. - An error code is delivered if the selected port is not - available. */ - u32 nAggrPortId; +typedef struct { + /** Ports are aggregated. + Enabling means that the 'nPortId' and + the 'nAggrPortId' ports form an aggregated link. */ + ltq_bool_t bAggregateEnable; + /** Ethernet Port number (zero-based counting). + The valid range is hardware dependent. + An error code is delivered if the selected port is not + available. */ + u32 nPortId; + /** Second Aggregated Ethernet Port number (zero-based counting). + The valid range is hardware dependent. + An error code is delivered if the selected port is not + available. */ + u32 nAggrPortId; } GSW_trunkingPortCfg_t; /*@}*/ /* GSW_IOCTL_BRIDGE */ @@ -456,308 +453,292 @@ typedef struct /** \brief VLAN port configuration for ingress packet filtering. Tagged packet and untagged packet can be configured to be accepted or dropped (filtered out). Used by \ref GSW_VLAN_portCfg_t. */ -typedef enum -{ - /** Admit all. Tagged and untagged packets are allowed. */ - GSW_VLAN_ADMIT_ALL = 0, - /** Untagged packets only (not supported yet). Tagged packets are dropped. */ - GSW_VLAN_ADMIT_UNTAGGED = 1, - /** Tagged packets only. Untagged packets are dropped. */ - GSW_VLAN_ADMIT_TAGGED = 2 +typedef enum { + /** Admit all. Tagged and untagged packets are allowed. */ + GSW_VLAN_ADMIT_ALL = 0, + /** Untagged packets only (not supported yet). Tagged packets are dropped. */ + GSW_VLAN_ADMIT_UNTAGGED = 1, + /** Tagged packets only. Untagged packets are dropped. */ + GSW_VLAN_ADMIT_TAGGED = 2 } GSW_VLAN_Admit_t; /** \brief Add a CTAG VLAN ID group to the CTAG VLAN hardware table of the switch. Used by \ref GSW_VLAN_ID_CREATE. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; - /** Filtering Identifier (FID) (not supported by all switches). */ - u32 nFId; +typedef struct { + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; + /** Filtering Identifier (FID) (not supported by all switches). */ + u32 nFId; } GSW_VLAN_IdCreate_t; /** \brief Read out the CTAG VLAN ID to FID assignment. The user provides the CTAG VLAN ID parameter and the switch API returns the FID parameter. Used by \ref GSW_VLAN_ID_GET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; - /** Filtering Identifier (FID) (not supported by all switches). */ - u32 nFId; +typedef struct { + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; + /** Filtering Identifier (FID) (not supported by all switches). */ + u32 nFId; } GSW_VLAN_IdGet_t; /** \brief Default VLAN membership portmap and egress tagmap for unconfigured VLAN groups. Every bit in the portmap variables represents one port (port 0 = LSB bit). Used by \ref GSW_VLAN_MEMBER_INIT. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Portmap field of the uninitialized VLAN groups. */ - u32 nPortMemberMap; - /** Egress tagmap field of the uninitialized VLAN groups. */ - u32 nEgressTagMap; +typedef struct { + /** Portmap field of the uninitialized VLAN groups. */ + u32 nPortMemberMap; + /** Egress tagmap field of the uninitialized VLAN groups. */ + u32 nEgressTagMap; } GSW_VLAN_memberInit_t; /** \brief Remove a CTAG VLAN ID from the switch CTAG VLAN table. Used by \ref GSW_VLAN_ID_DELETE. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; +typedef struct { + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; } GSW_VLAN_IdDelete_t; /** \brief Adds a CTAG VLAN to a port and set its egress filter information. Used by \ref GSW_VLAN_PORT_MEMBER_ADD. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. - - \remarks - This field is used as portmap field, when the MSB bit is set. - In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u32 nPortId; - /** Tag Member Egress. Enable egress tag-based support. - If enabled, all port egress traffic - from this CTAG VLAN group carries a CTAG VLAN group tag. */ - ltq_bool_t bVLAN_TagEgress; +typedef struct { + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. + + \remarks + This field is used as portmap field, when the MSB bit is set. + In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u32 nPortId; + /** Tag Member Egress. Enable egress tag-based support. + If enabled, all port egress traffic + from this CTAG VLAN group carries a CTAG VLAN group tag. */ + ltq_bool_t bVLAN_TagEgress; } GSW_VLAN_portMemberAdd_t; /** \brief Remove the CTAG VLAN configuration from an Ethernet port. Used by \ref GSW_VLAN_PORT_MEMBER_REMOVE. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. - If the selected VLAN ID is not found in the VLAN table, - an error code is delivered. */ - u16 nVId; - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. - - \remarks - This field is used as portmap field, when the MSB bit is set. - In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u32 nPortId; +typedef struct { + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. + If the selected VLAN ID is not found in the VLAN table, + an error code is delivered. */ + u16 nVId; + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. + + \remarks + This field is used as portmap field, when the MSB bit is set. + In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u32 nPortId; } GSW_VLAN_portMemberRemove_t; /** \brief Read the CTAG VLAN port membership table. Used by \ref GSW_VLAN_PORT_MEMBER_READ. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Restart the get operation from the start of the table. Otherwise - return the next table entry (next to the entry that was returned - during the previous get operation). This parameter is always reset - during the read operation. This boolean parameter is set by the - calling application. */ - ltq_bool_t bInitial; - /** Indicates that the read operation got all last valid entries of the - table. This boolean parameter is set by the switch API - when the Switch API is called after the last valid one was returned already. */ - ltq_bool_t bLast; - /** CTAG VLAN ID. The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; - /** Ethernet Port number (zero-based counting). Every bit represents - an Ethernet port. - - \remarks - This field is used as portmap field, when the MSB bit is set. - In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u32 nPortId; - /** Enable egress tag-Portmap. Every bit represents an Ethernet port. - This field is used as portmap field, and the MSB bit is - statically always set. LSB represents Port 0 with - incrementing counting. - The (MSB - 1) bit represent the last port. - All port egress traffic from this CTAG VLAN group carries a - tag, in case the port bit is set. - - \remarks - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u32 nTagId; +typedef struct { + /** Restart the get operation from the start of the table. Otherwise + return the next table entry (next to the entry that was returned + during the previous get operation). This parameter is always reset + during the read operation. This boolean parameter is set by the + calling application. */ + ltq_bool_t bInitial; + /** Indicates that the read operation got all last valid entries of the + table. This boolean parameter is set by the switch API + when the Switch API is called after the last valid one was returned already. */ + ltq_bool_t bLast; + /** CTAG VLAN ID. The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; + /** Ethernet Port number (zero-based counting). Every bit represents + an Ethernet port. + + \remarks + This field is used as portmap field, when the MSB bit is set. + In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u32 nPortId; + /** Enable egress tag-Portmap. Every bit represents an Ethernet port. + This field is used as portmap field, and the MSB bit is + statically always set. LSB represents Port 0 with + incrementing counting. + The (MSB - 1) bit represent the last port. + All port egress traffic from this CTAG VLAN group carries a + tag, in case the port bit is set. + + \remarks + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u32 nTagId; } GSW_VLAN_portMemberRead_t; /** \brief Port configuration for VLAN member violation. Used by \ref GSW_VLAN_portCfg_t. */ -typedef enum -{ - /** No VLAN member violation. Ingress and egress packets violating the - membership pass and are not filtered out. */ - GSW_VLAN_MEMBER_VIOLATION_NO = 0, - /** VLAN member violation for ingress packets. Ingress packets violating - the membership are filtered out. Egress packets violating the - membership are not filtered out. */ - GSW_VLAN_MEMBER_VIOLATION_INGRESS = 1, - /** VLAN member violation for egress packets. Egress packets violating - the membership are filtered out. Ingress packets violating the - membership are not filtered out.*/ - GSW_VLAN_MEMBER_VIOLATION_EGRESS = 2, - /** VLAN member violation for ingress and egress packets. - Ingress and egress packets violating the membership are filtered out. */ - GSW_VLAN_MEMBER_VIOLATION_BOTH = 3 +typedef enum { + /** No VLAN member violation. Ingress and egress packets violating the + membership pass and are not filtered out. */ + GSW_VLAN_MEMBER_VIOLATION_NO = 0, + /** VLAN member violation for ingress packets. Ingress packets violating + the membership are filtered out. Egress packets violating the + membership are not filtered out. */ + GSW_VLAN_MEMBER_VIOLATION_INGRESS = 1, + /** VLAN member violation for egress packets. Egress packets violating + the membership are filtered out. Ingress packets violating the + membership are not filtered out.*/ + GSW_VLAN_MEMBER_VIOLATION_EGRESS = 2, + /** VLAN member violation for ingress and egress packets. + Ingress and egress packets violating the membership are filtered out. */ + GSW_VLAN_MEMBER_VIOLATION_BOTH = 3 } GSW_VLAN_MemberViolation_t; /** \brief CTAG VLAN Port Configuration. Used by \ref GSW_VLAN_PORT_CFG_GET and \ref GSW_VLAN_PORT_CFG_SET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Port CTAG VLAN ID (PVID). The software shall ensure that the used VID has - been configured in advance on the hardware by - using \ref GSW_VLAN_ID_CREATE. */ - u16 nPortVId; - /** Drop ingress CTAG VLAN-tagged packets if the VLAN ID - is not listed in the active VLAN set. If disabled, all incoming - VLAN-tagged packets are forwarded using the FID tag members and - the port members of the PVID. - This parameter is only supported for devices which do not - support 4k VLAN table entries (64 entries instead). */ - ltq_bool_t bVLAN_UnknownDrop; - /** Reassign all ingress CTAG VLAN tagged packets to the port-based - VLAN ID (PVID). */ - ltq_bool_t bVLAN_ReAssign; - /** VLAN ingress and egress membership violation mode. Allows admittance of - VLAN-tagged packets where the port is not a member of the VLAN ID - carried in the received and sent packet. */ - GSW_VLAN_MemberViolation_t eVLAN_MemberViolation; - /** Ingress VLAN-tagged or untagged packet filter configuration. */ - GSW_VLAN_Admit_t eAdmitMode; - /** Transparent CTAG VLAN Mode (TVM). All packets are handled as untagged - packets. Any existing tag is ignored and treated as packet payload. */ - ltq_bool_t bTVM; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Port CTAG VLAN ID (PVID). The software shall ensure that the used VID has + been configured in advance on the hardware by + using \ref GSW_VLAN_ID_CREATE. */ + u16 nPortVId; + /** Drop ingress CTAG VLAN-tagged packets if the VLAN ID + is not listed in the active VLAN set. If disabled, all incoming + VLAN-tagged packets are forwarded using the FID tag members and + the port members of the PVID. + This parameter is only supported for devices which do not + support 4k VLAN table entries (64 entries instead). */ + ltq_bool_t bVLAN_UnknownDrop; + /** Reassign all ingress CTAG VLAN tagged packets to the port-based + VLAN ID (PVID). */ + ltq_bool_t bVLAN_ReAssign; + /** VLAN ingress and egress membership violation mode. Allows admittance of + VLAN-tagged packets where the port is not a member of the VLAN ID + carried in the received and sent packet. */ + GSW_VLAN_MemberViolation_t eVLAN_MemberViolation; + /** Ingress VLAN-tagged or untagged packet filter configuration. */ + GSW_VLAN_Admit_t eAdmitMode; + /** Transparent CTAG VLAN Mode (TVM). All packets are handled as untagged + packets. Any existing tag is ignored and treated as packet payload. */ + ltq_bool_t bTVM; } GSW_VLAN_portCfg_t; /** \brief This CTAG VLAN configuration supports replacing of the VID of received packets with the PVID of the receiving port. Used by \ref GSW_VLAN_RESERVED_ADD and \ref GSW_VLAN_RESERVED_REMOVE. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** VID of the received packet to be replaced by the PVID. - The valid range is from 0 to 4095. - An error code is delivered in case of range mismatch. */ - u16 nVId; +typedef struct { + /** VID of the received packet to be replaced by the PVID. + The valid range is from 0 to 4095. + An error code is delivered in case of range mismatch. */ + u16 nVId; } GSW_VLAN_reserved_t; /** \brief STAG VLAN global configuration. Used by \ref GSW_SVLAN_CFG_GET and \ref GSW_SVLAN_CFG_SET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Protocol EtherType Field. This 16-bit of the STAG VLAN (default=0x88A8). */ - u16 nEthertype; +typedef struct { + /** Protocol EtherType Field. This 16-bit of the STAG VLAN (default=0x88A8). */ + u16 nEthertype; } GSW_SVLAN_cfg_t; /** \brief STAG VLAN Port Configuration. Used by \ref GSW_SVLAN_PORT_CFG_GET and \ref GSW_SVLAN_PORT_CFG_SET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Port based STAG VLAN Support. All STAG VLAN protocol parsing and - configuration features are only applied on this port in case the - STAG VLAN port support is enabled. */ - ltq_bool_t bSVLAN_TagSupport; - /** Port Egress MAC based STAG VLAN. All egress packets contain a - STAG VLAN ID that is based on the VLAN ID which is retrieved - from the MAC bridging table. This MAC bridging table SVLAN ID - can be learned from the snooped traffic or statically added. */ - ltq_bool_t bSVLAN_MACbasedTag; - /** Port STAG VLAN ID (PVID) */ - u16 nPortVId; - /** Reassign all ingress STAG VLAN tagged packets to the port-based - STAG VLAN ID (PVID). */ - ltq_bool_t bVLAN_ReAssign; - /** VLAN ingress and egress membership violation mode. Allows admittance of - STAG VLAN-tagged packets where the port is not a member of the STAG VLAN ID - carried in the received and sent packet. */ - GSW_VLAN_MemberViolation_t eVLAN_MemberViolation; - /** Ingress STAG VLAN-tagged or untagged packet filter configuration. */ - GSW_VLAN_Admit_t eAdmitMode; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Port based STAG VLAN Support. All STAG VLAN protocol parsing and + configuration features are only applied on this port in case the + STAG VLAN port support is enabled. */ + ltq_bool_t bSVLAN_TagSupport; + /** Port Egress MAC based STAG VLAN. All egress packets contain a + STAG VLAN ID that is based on the VLAN ID which is retrieved + from the MAC bridging table. This MAC bridging table SVLAN ID + can be learned from the snooped traffic or statically added. */ + ltq_bool_t bSVLAN_MACbasedTag; + /** Port STAG VLAN ID (PVID) */ + u16 nPortVId; + /** Reassign all ingress STAG VLAN tagged packets to the port-based + STAG VLAN ID (PVID). */ + ltq_bool_t bVLAN_ReAssign; + /** VLAN ingress and egress membership violation mode. Allows admittance of + STAG VLAN-tagged packets where the port is not a member of the STAG VLAN ID + carried in the received and sent packet. */ + GSW_VLAN_MemberViolation_t eVLAN_MemberViolation; + /** Ingress STAG VLAN-tagged or untagged packet filter configuration. */ + GSW_VLAN_Admit_t eAdmitMode; } GSW_SVLAN_portCfg_t; /** \brief Egress VLAN Treatment Selector based upon FID or destination SubIf-Id MSB bits (Bit position 12 to 8) - for GSWIP-3.0 only. Used by \ref GSW_PCE_EgVLAN_Cfg_t. */ -typedef enum -{ - /** FID based Egress VLAN Treatment. */ - GSW_PCE_EG_VLAN_FID_BASED = 0, - /** Sub-InterfaceId Group (Bits 12 to 8) based Egress VLAN Treatment. */ - GSW_PCE_EG_VLAN_SUBIFID_BASED = 1 +typedef enum { + /** FID based Egress VLAN Treatment. */ + GSW_PCE_EG_VLAN_FID_BASED = 0, + /** Sub-InterfaceId Group (Bits 12 to 8) based Egress VLAN Treatment. */ + GSW_PCE_EG_VLAN_SUBIFID_BASED = 1 } GSW_PCE_EgVLAN_mode_t; /** \brief Egress VLAN Treatment Configuration - for GSWIP-3.0 only. Used by \ref GSW_PCE_EG_VLAN_CFG_GET and \ref GSW_PCE_EG_VLAN_CFG_SET. */ -typedef struct -{ - /** Egress Port Identifier */ - u16 nPortId; - /** To enable or disable Egress VLAN treatment on given port */ - ltq_bool_t bEgVidEna; - /** Egress VLAN Treatment Selector - FID or SubIf-Id-MSB (Bits 12 to 8) based */ - GSW_PCE_EgVLAN_mode_t eEgVLANmode; - /** Egress VLAN Treatment start index for specified nPortId. Continuous block of VLAN is used until next port's Start block assignment */ - u8 nEgStartVLANIdx; +typedef struct { + /** Egress Port Identifier */ + u16 nPortId; + /** To enable or disable Egress VLAN treatment on given port */ + ltq_bool_t bEgVidEna; + /** Egress VLAN Treatment Selector - FID or SubIf-Id-MSB (Bits 12 to 8) based */ + GSW_PCE_EgVLAN_mode_t eEgVLANmode; + /** Egress VLAN Treatment start index for specified nPortId. Continuous block of VLAN is used until next port's Start block assignment */ + u8 nEgStartVLANIdx; } GSW_PCE_EgVLAN_Cfg_t; /** \brief Egress VLAN Treatment Entry Configuration - for GSWIP-3.0 only. Used by \ref GSW_PCE_EG_VLAN_ENTRY_READ and \ref GSW_PCE_EG_VLAN_ENTRY_WRITE. */ -typedef struct -{ - /** Egress Port Identifier */ - u16 nPortId; - /** Index corresponding to FID or SubIf-ID Subfield (Bits 12 to 8) */ - u16 nIndex; - /** Egress VLAN Treatment Action Enable */ - ltq_bool_t bEgVLAN_Action; - /** STAG VLAN Removal action */ - ltq_bool_t bEgSVidRem_Action; - /** STAG VLAN Insert action */ - ltq_bool_t bEgSVidIns_Action; - /** SVLAN Value to be inserted in egress */ - u16 nEgSVid; - /** CTAG VLAN Removal action*/ - ltq_bool_t bEgCVidRem_Action; - /** CTAG VLAN Insert action */ - ltq_bool_t bEgCVidIns_Action; - /** CVLAN Value to be inserted in egress */ - u16 nEgCVid; +typedef struct { + /** Egress Port Identifier */ + u16 nPortId; + /** Index corresponding to FID or SubIf-ID Subfield (Bits 12 to 8) */ + u16 nIndex; + /** Egress VLAN Treatment Action Enable */ + ltq_bool_t bEgVLAN_Action; + /** STAG VLAN Removal action */ + ltq_bool_t bEgSVidRem_Action; + /** STAG VLAN Insert action */ + ltq_bool_t bEgSVidIns_Action; + /** SVLAN Value to be inserted in egress */ + u16 nEgSVid; + /** CTAG VLAN Removal action*/ + ltq_bool_t bEgCVidRem_Action; + /** CTAG VLAN Insert action */ + ltq_bool_t bEgCVidIns_Action; + /** CVLAN Value to be inserted in egress */ + u16 nEgCVid; } GSW_PCE_EgVLAN_Entry_t; /*@}*/ /* GSW_IOCTL_VLAN */ @@ -772,23 +753,21 @@ typedef struct /** \brief DSCP mapping table. Used by \ref GSW_QOS_DSCP_CLASS_SET and \ref GSW_QOS_DSCP_CLASS_GET. */ -typedef struct -{ - /** Traffic class associated with a particular DSCP value. - DSCP is the index to an array of resulting traffic class values. - The index starts counting from zero. */ - u8 nTrafficClass[64]; +typedef struct { + /** Traffic class associated with a particular DSCP value. + DSCP is the index to an array of resulting traffic class values. + The index starts counting from zero. */ + u8 nTrafficClass[64]; } GSW_QoS_DSCP_ClassCfg_t; /** \brief Traffic class associated with a particular 802.1P (PCP) priority mapping value. This table is global for the entire switch device. Priority map entry structure. Used by \ref GSW_QOS_PCP_CLASS_SET and \ref GSW_QOS_PCP_CLASS_GET. */ -typedef struct -{ - /** Configures the PCP to traffic class mapping. - The queue index starts counting from zero. */ - u8 nTrafficClass[8]; +typedef struct { + /** Configures the PCP to traffic class mapping. + The queue index starts counting from zero. */ + u8 nTrafficClass[8]; } GSW_QoS_PCP_ClassCfg_t; /** \brief Ingress DSCP remarking attribute. This attribute defines on the @@ -796,26 +775,25 @@ typedef struct A packet is only remarked in case its ingress and its egress port have remarking enabled. Used by \ref GSW_QoS_portRemarkingCfg_t. */ -typedef enum -{ - /** No DSCP Remarking. No remarking is done on the egress port. */ - GSW_DSCP_REMARK_DISABLE = 0, - /** TC DSCP 6-Bit Remarking. The complete DSCP remarking is done based - on the traffic class. The traffic class to DSCP value mapping is - given in a device global table. */ - GSW_DSCP_REMARK_TC6 = 1, - /** TC DSCP 3-Bit Remarking. The upper 3-Bits of the DSCP field are - remarked based on the traffic class. The traffic class to DSCP value - mapping is given in a device global table. */ - GSW_DSCP_REMARK_TC3 = 2, - /** Drop Precedence Remarking. The Drop Precedence is remarked on the - egress side. */ - GSW_DSCP_REMARK_DP3 = 3, - /** TC Drop Precedence Remarking. The Drop Precedence is remarked on the - egress side and the upper 3-Bits of the DSCP field are - remarked based on the traffic class. The traffic class to DSCP value - mapping is given in a device global table. */ - GSW_DSCP_REMARK_DP3_TC3 = 4 +typedef enum { + /** No DSCP Remarking. No remarking is done on the egress port. */ + GSW_DSCP_REMARK_DISABLE = 0, + /** TC DSCP 6-Bit Remarking. The complete DSCP remarking is done based + on the traffic class. The traffic class to DSCP value mapping is + given in a device global table. */ + GSW_DSCP_REMARK_TC6 = 1, + /** TC DSCP 3-Bit Remarking. The upper 3-Bits of the DSCP field are + remarked based on the traffic class. The traffic class to DSCP value + mapping is given in a device global table. */ + GSW_DSCP_REMARK_TC3 = 2, + /** Drop Precedence Remarking. The Drop Precedence is remarked on the + egress side. */ + GSW_DSCP_REMARK_DP3 = 3, + /** TC Drop Precedence Remarking. The Drop Precedence is remarked on the + egress side and the upper 3-Bits of the DSCP field are + remarked based on the traffic class. The traffic class to DSCP value + mapping is given in a device global table. */ + GSW_DSCP_REMARK_DP3_TC3 = 4 } GSW_Qos_ingressRemarking_t; /** \brief Port Remarking Configuration. Ingress and Egress remarking options for @@ -827,133 +805,127 @@ typedef enum enabled on ingress and egress port. Used by \ref GSW_QOS_PORT_REMARKING_CFG_SET and \ref GSW_QOS_PORT_REMARKING_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Ingress DSCP Remarking. Specifies on ingress side how a packet should - be remarked. This DSCP remarking only works in case remarking is - enabled on the egress port. - This configuration requires that remarking is also enabled on the - egress port. DSCP remarking enable on either ingress or egress port - side does not perform any remark operation. */ - GSW_Qos_ingressRemarking_t eDSCP_IngressRemarkingEnable; - /** Egress DSCP Remarking. Applies remarking on egress packets in a - fashion as specified on the ingress port. This ingress port remarking - is configured by the parameter 'eDSCP_IngressRemarking'. - This configuration requires that remarking is also enabled on the - ingress port. DSCP remarking enable on either ingress or egress port - side does not perform any remark operation. */ - ltq_bool_t bDSCP_EgressRemarkingEnable; - /** Ingress PCP Remarking. Applies remarking to all port ingress packets. - This configuration requires that remarking is also enabled on the - egress port. PCP remarking enable on either ingress or egress port - side does not perform any remark operation. */ - ltq_bool_t bPCP_IngressRemarkingEnable; - /** Egress PCP Remarking. Applies remarking for all port egress packets. - This configuration requires that remarking is also enabled on the - ingress port. PCP remarking enable on either ingress or egress port - side does not perform any remark operation. */ - ltq_bool_t bPCP_EgressRemarkingEnable; - /** Ingress STAG VLAN PCP Remarking */ - ltq_bool_t bSTAG_PCP_IngressRemarkingEnable; - /** Ingress STAG VLAN DEI Remarking */ - ltq_bool_t bSTAG_DEI_IngressRemarkingEnable; - /** Egress STAG VLAN PCP & DEI Remarking */ - ltq_bool_t bSTAG_PCP_DEI_EgressRemarkingEnable; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Ingress DSCP Remarking. Specifies on ingress side how a packet should + be remarked. This DSCP remarking only works in case remarking is + enabled on the egress port. + This configuration requires that remarking is also enabled on the + egress port. DSCP remarking enable on either ingress or egress port + side does not perform any remark operation. */ + GSW_Qos_ingressRemarking_t eDSCP_IngressRemarkingEnable; + /** Egress DSCP Remarking. Applies remarking on egress packets in a + fashion as specified on the ingress port. This ingress port remarking + is configured by the parameter 'eDSCP_IngressRemarking'. + This configuration requires that remarking is also enabled on the + ingress port. DSCP remarking enable on either ingress or egress port + side does not perform any remark operation. */ + ltq_bool_t bDSCP_EgressRemarkingEnable; + /** Ingress PCP Remarking. Applies remarking to all port ingress packets. + This configuration requires that remarking is also enabled on the + egress port. PCP remarking enable on either ingress or egress port + side does not perform any remark operation. */ + ltq_bool_t bPCP_IngressRemarkingEnable; + /** Egress PCP Remarking. Applies remarking for all port egress packets. + This configuration requires that remarking is also enabled on the + ingress port. PCP remarking enable on either ingress or egress port + side does not perform any remark operation. */ + ltq_bool_t bPCP_EgressRemarkingEnable; + /** Ingress STAG VLAN PCP Remarking */ + ltq_bool_t bSTAG_PCP_IngressRemarkingEnable; + /** Ingress STAG VLAN DEI Remarking */ + ltq_bool_t bSTAG_DEI_IngressRemarkingEnable; + /** Egress STAG VLAN PCP & DEI Remarking */ + ltq_bool_t bSTAG_PCP_DEI_EgressRemarkingEnable; } GSW_QoS_portRemarkingCfg_t; /** \brief Traffic class to DSCP mapping table. Used by \ref GSW_QOS_CLASS_DSCP_SET and \ref GSW_QOS_CLASS_DSCP_GET. */ -typedef struct -{ - /** DSCP value (6-bit) associated with a particular Traffic class. - Traffic class is the index to an array of resulting DSCP values. - The index starts counting from zero. */ - u8 nDSCP[16]; +typedef struct { + /** DSCP value (6-bit) associated with a particular Traffic class. + Traffic class is the index to an array of resulting DSCP values. + The index starts counting from zero. */ + u8 nDSCP[16]; } GSW_QoS_ClassDSCP_Cfg_t; /** \brief Traffic class associated with a particular 802.1P (PCP) priority mapping value. This table is global for the entire switch device. Priority map entry structure. Used by \ref GSW_QOS_CLASS_PCP_SET and \ref GSW_QOS_CLASS_PCP_GET. */ -typedef struct -{ - /** Configures the traffic class to PCP (3-bit) mapping. - The queue index starts counting from zero. */ - u8 nPCP[16]; +typedef struct { + /** Configures the traffic class to PCP (3-bit) mapping. + The queue index starts counting from zero. */ + u8 nPCP[16]; } GSW_QoS_ClassPCP_Cfg_t; /** \brief DSCP Drop Precedence to color code assignment. Used by \ref GSW_QoS_DSCP_DropPrecedenceCfg_t. */ -typedef enum -{ - /** Critical Packet. Metering never changes the drop precedence of these packets. */ - GSW_DROP_PRECEDENCE_CRITICAL = 0, - /** Green Drop Precedence Packet. Packet is marked with a 'low' drop precedence. */ - GSW_DROP_PRECEDENCE_GREEN = 1, - /** Yellow Drop Precedence Packet. Packet is marked with a 'middle' drop precedence. */ - GSW_DROP_PRECEDENCE_YELLOW = 2, - /** Red Drop Precedence Packet. Packet is marked with a 'high' drop precedence. */ - GSW_DROP_PRECEDENCE_RED = 3 +typedef enum { + /** Critical Packet. Metering never changes the drop precedence of these packets. */ + GSW_DROP_PRECEDENCE_CRITICAL = 0, + /** Green Drop Precedence Packet. Packet is marked with a 'low' drop precedence. */ + GSW_DROP_PRECEDENCE_GREEN = 1, + /** Yellow Drop Precedence Packet. Packet is marked with a 'middle' drop precedence. */ + GSW_DROP_PRECEDENCE_YELLOW = 2, + /** Red Drop Precedence Packet. Packet is marked with a 'high' drop precedence. */ + GSW_DROP_PRECEDENCE_RED = 3 } GSW_QoS_DropPrecedence_t; /** \brief DSCP to Drop Precedence assignment table configuration. Used by \ref GSW_QOS_DSCP_DROP_PRECEDENCE_CFG_SET and \ref GSW_QOS_DSCP_DROP_PRECEDENCE_CFG_GET. */ -typedef struct -{ - /** DSCP to drop precedence assignment. Every array entry represents the - drop precedence for one of the 64 existing DSCP values. - DSCP is the index to an array of resulting drop precedence values. - The index starts counting from zero. */ - GSW_QoS_DropPrecedence_t nDSCP_DropPrecedence[64]; +typedef struct { + /** DSCP to drop precedence assignment. Every array entry represents the + drop precedence for one of the 64 existing DSCP values. + DSCP is the index to an array of resulting drop precedence values. + The index starts counting from zero. */ + GSW_QoS_DropPrecedence_t nDSCP_DropPrecedence[64]; } GSW_QoS_DSCP_DropPrecedenceCfg_t; /** \brief Selection of the traffic class field. Used by \ref GSW_QoS_portCfg_t. The port default traffic class is assigned in case non of the configured protocol code points given by the packet. */ -typedef enum -{ - /** No traffic class assignment based on DSCP or PCP */ - GSW_QOS_CLASS_SELECT_NO = 0, - /** Traffic class assignment based on DSCP. PCP information is ignored. - The Port Class is used in case DSCP is not available in the packet. */ - GSW_QOS_CLASS_SELECT_DSCP = 1, - /** Traffic class assignment based on PCP. DSCP information is ignored. - The Port Class is used in case PCP is not available in the packet. */ - GSW_QOS_CLASS_SELECT_PCP = 2, - /** Traffic class assignment based on DSCP. Make the assignment based on - PCP in case the DSCP information is not available in the packet header. - The Port Class is used in case both are not available in the packet. */ - GSW_QOS_CLASS_SELECT_DSCP_PCP = 3, - /** CTAG VLAN PCP, IP DSCP. Traffic class assignment based - on CTAG VLAN PCP, alternative use DSCP based assignment. */ - GSW_QOS_CLASS_SELECT_PCP_DSCP = 4, - /** STAG VLAN PCP. Traffic class assignment based - on STAG VLAN PCP. */ - GSW_QOS_CLASS_SELECT_SPCP = 5, - /** STAG VLAN PCP, IP DSCP. Traffic class assignment based - on STAG VLAN PCP, alternative use DSCP based assignment. */ - GSW_QOS_CLASS_SELECT_SPCP_DSCP = 6, - /** IP DSCP, STAG VLAN PCP. Traffic class assignment based - on DSCP, alternative use STAG VLAN PCP based assignment. */ - GSW_QOS_CLASS_SELECT_DSCP_SPCP = 7, - /** STAG VLAN PCP, CTAG VLAN PCP. Traffic class assignment based - on STAG VLAN PCP, alternative use CTAG VLAN PCP based assignment. */ - GSW_QOS_CLASS_SELECT_SPCP_PCP = 8, - /** STAG VLAN PCP, CTAG VLAN PCP, IP DSCP. Traffic class assignment - based on STAG VLAN PCP, alternative use CTAG VLAN PCP based - assignment, alternative use DSCP based assignment. */ - GSW_QOS_CLASS_SELECT_SPCP_PCP_DSCP = 9, - /** IP DSCP, STAG VLAN PCP, CTAG VLAN PCP. Traffic class assignment - based on DSCP, alternative use STAG VLAN PCP based - assignment, alternative use CTAG VLAN PCP based assignment. */ - GSW_QOS_CLASS_SELECT_DSCP_SPCP_PCP = 10 +typedef enum { + /** No traffic class assignment based on DSCP or PCP */ + GSW_QOS_CLASS_SELECT_NO = 0, + /** Traffic class assignment based on DSCP. PCP information is ignored. + The Port Class is used in case DSCP is not available in the packet. */ + GSW_QOS_CLASS_SELECT_DSCP = 1, + /** Traffic class assignment based on PCP. DSCP information is ignored. + The Port Class is used in case PCP is not available in the packet. */ + GSW_QOS_CLASS_SELECT_PCP = 2, + /** Traffic class assignment based on DSCP. Make the assignment based on + PCP in case the DSCP information is not available in the packet header. + The Port Class is used in case both are not available in the packet. */ + GSW_QOS_CLASS_SELECT_DSCP_PCP = 3, + /** CTAG VLAN PCP, IP DSCP. Traffic class assignment based + on CTAG VLAN PCP, alternative use DSCP based assignment. */ + GSW_QOS_CLASS_SELECT_PCP_DSCP = 4, + /** STAG VLAN PCP. Traffic class assignment based + on STAG VLAN PCP. */ + GSW_QOS_CLASS_SELECT_SPCP = 5, + /** STAG VLAN PCP, IP DSCP. Traffic class assignment based + on STAG VLAN PCP, alternative use DSCP based assignment. */ + GSW_QOS_CLASS_SELECT_SPCP_DSCP = 6, + /** IP DSCP, STAG VLAN PCP. Traffic class assignment based + on DSCP, alternative use STAG VLAN PCP based assignment. */ + GSW_QOS_CLASS_SELECT_DSCP_SPCP = 7, + /** STAG VLAN PCP, CTAG VLAN PCP. Traffic class assignment based + on STAG VLAN PCP, alternative use CTAG VLAN PCP based assignment. */ + GSW_QOS_CLASS_SELECT_SPCP_PCP = 8, + /** STAG VLAN PCP, CTAG VLAN PCP, IP DSCP. Traffic class assignment + based on STAG VLAN PCP, alternative use CTAG VLAN PCP based + assignment, alternative use DSCP based assignment. */ + GSW_QOS_CLASS_SELECT_SPCP_PCP_DSCP = 9, + /** IP DSCP, STAG VLAN PCP, CTAG VLAN PCP. Traffic class assignment + based on DSCP, alternative use STAG VLAN PCP based + assignment, alternative use CTAG VLAN PCP based assignment. */ + GSW_QOS_CLASS_SELECT_DSCP_SPCP_PCP = 10 } GSW_QoS_ClassSelect_t; /** \brief Describes which priority information of ingress packets is used @@ -962,148 +934,139 @@ typedef enum using \ref GSW_QOS_DSCP_CLASS_SET. For VLAN, the priority to queue assignment is done using \ref GSW_QOS_PCP_CLASS_SET. Used by \ref GSW_QOS_PORT_CFG_SET and \ref GSW_QOS_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Select the packet header field on which to base the traffic class assignment. */ - GSW_QoS_ClassSelect_t eClassMode; - /** Default port priority in case no other priority - (such as VLAN-based PCP or IP-based DSCP) is used. */ - u8 nTrafficClass; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Select the packet header field on which to base the traffic class assignment. */ + GSW_QoS_ClassSelect_t eClassMode; + /** Default port priority in case no other priority + (such as VLAN-based PCP or IP-based DSCP) is used. */ + u8 nTrafficClass; } GSW_QoS_portCfg_t; /** \brief Configures a rate shaper instance with the rate and the burst size. Used by \ref GSW_QOS_SHAPER_CFG_SET and \ref GSW_QOS_SHAPER_CFG_GET. */ -typedef struct -{ - /** Rate shaper index (zero-based counting). */ - u32 nRateShaperId; - /** Enable/Disable the rate shaper. */ - ltq_bool_t bEnable; - /** 802.1Qav credit based shaper mode. This specific shaper - algorithm mode is used by the audio/video bridging (AVB) - network (according to 802.1Qav). By default, an token - based shaper algorithm is used. */ - ltq_bool_t bAVB; - /** Committed Burst Size (CBS [bytes]) */ - u32 nCbs; - /** Rate [kbit/s] */ - u32 nRate; +typedef struct { + /** Rate shaper index (zero-based counting). */ + u32 nRateShaperId; + /** Enable/Disable the rate shaper. */ + ltq_bool_t bEnable; + /** 802.1Qav credit based shaper mode. This specific shaper + algorithm mode is used by the audio/video bridging (AVB) + network (according to 802.1Qav). By default, an token + based shaper algorithm is used. */ + ltq_bool_t bAVB; + /** Committed Burst Size (CBS [bytes]) */ + u32 nCbs; + /** Rate [kbit/s] */ + u32 nRate; } GSW_QoS_ShaperCfg_t; /** \brief Assign one rate shaper instance to a QoS queue. Used by \ref GSW_QOS_SHAPER_QUEUE_ASSIGN and \ref GSW_QOS_SHAPER_QUEUE_DEASSIGN. */ -typedef struct -{ - /** Rate shaper index (zero-based counting). */ - u8 nRateShaperId; - /** QoS queue index (zero-based counting). */ - u8 nQueueId; +typedef struct { + /** Rate shaper index (zero-based counting). */ + u8 nRateShaperId; + /** QoS queue index (zero-based counting). */ + u8 nQueueId; } GSW_QoS_ShaperQueue_t; /** \brief Retrieve if a rate shaper instance is assigned to a QoS egress queue. Used by \ref GSW_QOS_SHAPER_QUEUE_GET. */ -typedef struct -{ - /** QoS queue index (zero-based counting). - This parameter is the input parameter for the GET function. */ - u8 nQueueId; - /** Rate shaper instance assigned. - If 1, a rate shaper instance is assigned to the queue. Otherwise no shaper instance is assigned. */ - ltq_bool_t bAssigned; - /** Rate shaper index (zero-based counting). Only a valid instance is returned in case 'bAssigned == 1'. */ - u8 nRateShaperId; +typedef struct { + /** QoS queue index (zero-based counting). + This parameter is the input parameter for the GET function. */ + u8 nQueueId; + /** Rate shaper instance assigned. + If 1, a rate shaper instance is assigned to the queue. Otherwise no shaper instance is assigned. */ + ltq_bool_t bAssigned; + /** Rate shaper index (zero-based counting). Only a valid instance is returned in case 'bAssigned == 1'. */ + u8 nRateShaperId; } GSW_QoS_ShaperQueueGet_t; /** \brief WRED Cfg Type - Automatic (Adaptive) or Manual. Used by \ref GSW_QoS_WRED_Cfg_t. */ -typedef enum -{ - /** Automatic - Adaptive Watermark Type - GSWIP-3.0/3.1 only*/ - GSW_QOS_WRED_Adaptive = 0, - /** Manual Threshold Levels Type */ - GSW_QOS_WRED_Manual = 1 +typedef enum { + /** Automatic - Adaptive Watermark Type - GSWIP-3.0/3.1 only*/ + GSW_QOS_WRED_Adaptive = 0, + /** Manual Threshold Levels Type */ + GSW_QOS_WRED_Manual = 1 } GSW_QoS_WRED_Mode_t; /** \brief WRED Thresholds Mode Type. - GSWIP-3.0/3.1 only Used by \ref GSW_QoS_WRED_Cfg_t. */ -typedef enum -{ - /** Local Thresholds Mode */ - GSW_QOS_WRED_Local_Thresh = 0, - /** Global Thresholds Mode */ - GSW_QOS_WRED_Global_Thresh = 1, - /** Port queue and Port WRED Thresholds */ - GSW_QOS_WRED_Port_Thresh = 2, - +typedef enum { + /** Local Thresholds Mode */ + GSW_QOS_WRED_Local_Thresh = 0, + /** Global Thresholds Mode */ + GSW_QOS_WRED_Global_Thresh = 1, + /** Port queue and Port WRED Thresholds */ + GSW_QOS_WRED_Port_Thresh = 2, + } GSW_QoS_WRED_ThreshMode_t; /** \brief Drop Probability Profile. Defines the drop probability profile. Used by \ref GSW_QoS_WRED_Cfg_t. */ -typedef enum -{ - /** Pmin = 25%, Pmax = 75% (default) */ - GSW_QOS_WRED_PROFILE_P0 = 0, - /** Pmin = 25%, Pmax = 50% */ - GSW_QOS_WRED_PROFILE_P1 = 1, - /** Pmin = 50%, Pmax = 50% */ - GSW_QOS_WRED_PROFILE_P2 = 2, - /** Pmin = 50%, Pmax = 75% */ - GSW_QOS_WRED_PROFILE_P3 = 3 +typedef enum { + /** Pmin = 25%, Pmax = 75% (default) */ + GSW_QOS_WRED_PROFILE_P0 = 0, + /** Pmin = 25%, Pmax = 50% */ + GSW_QOS_WRED_PROFILE_P1 = 1, + /** Pmin = 50%, Pmax = 50% */ + GSW_QOS_WRED_PROFILE_P2 = 2, + /** Pmin = 50%, Pmax = 75% */ + GSW_QOS_WRED_PROFILE_P3 = 3 } GSW_QoS_WRED_Profile_t; /** \brief Egress Queue Congestion Notification Watermark. Used by \ref GSW_QoS_WRED_Cfg_t. */ -typedef enum -{ - /** - >= 1/4 of green max water mark assert - <= 1/4 of green max water mark de assert*/ - GSW_QOS_WRED_WATERMARK_1_4 = 0, - /** - >= 1/8 of green max water mark assert - <= 1/8 of green max water mark de assert*/ - GSW_QOS_WRED_WATERMARK_1_8 = 1, - /** - >= 1/12 of green max water mark assert - <= 1/12 of green max water mark de assert*/ - GSW_QOS_WRED_WATERMARK_1_12 = 2, - /** - >= 1/16 of green max water mark assert - <= 1/16 of green max water mark de assert*/ - GSW_QOS_WRED_WATERMARK_1_16 = 3 +typedef enum { + /** + >= 1/4 of green max water mark assert + <= 1/4 of green max water mark de assert*/ + GSW_QOS_WRED_WATERMARK_1_4 = 0, + /** + >= 1/8 of green max water mark assert + <= 1/8 of green max water mark de assert*/ + GSW_QOS_WRED_WATERMARK_1_8 = 1, + /** + >= 1/12 of green max water mark assert + <= 1/12 of green max water mark de assert*/ + GSW_QOS_WRED_WATERMARK_1_12 = 2, + /** + >= 1/16 of green max water mark assert + <= 1/16 of green max water mark de assert*/ + GSW_QOS_WRED_WATERMARK_1_16 = 3 } GSW_QoS_WRED_WATERMARK_t; /** \brief Configures the global probability profile of the device. The min. and max. threshold values are given in number of packet buffer segments and required only in case of Manual Mode. The GSWIP-3.0/3.1 supports Auto mode and the threshold values are dynamically computed internally by GSWIP. The size of a segment can be retrieved using \ref GSW_CAP_GET. Used by \ref GSW_QOS_WRED_CFG_SET and \ref GSW_QOS_WRED_CFG_GET. */ -typedef struct -{ - /** Egress Queue Congestion Notification Watermark +typedef struct { + /** Egress Queue Congestion Notification Watermark only applicable for GSWIP 3.1*/ - GSW_QoS_WRED_WATERMARK_t eCongestionWatermark; + GSW_QoS_WRED_WATERMARK_t eCongestionWatermark; /** Drop Probability Profile. */ - GSW_QoS_WRED_Profile_t eProfile; - /** Automatic or Manual Mode of Thresholds Config */ - GSW_QoS_WRED_Mode_t eMode; - /** WRED Threshold Mode Config */ - GSW_QoS_WRED_ThreshMode_t eThreshMode; - /** WRED Red Threshold Min [number of segments] - Valid for Manual Mode only. */ - u32 nRed_Min; - /** WRED Red Threshold Max [number of segments] - Valid for Manual Mode only */ - u32 nRed_Max; - /** WRED Yellow Threshold Min [number of segments] - Valid for Manual Mode only */ - u32 nYellow_Min; - /** WRED Yellow Threshold Max [number of segments] - Valid for Manual Mode only */ - u32 nYellow_Max; - /** WRED Green Threshold Min [number of segments] - Valid for Manual Mode only */ - u32 nGreen_Min; - /** WRED Green Threshold Max [number of segments] - Valid for Manual Mode only */ - u32 nGreen_Max; + GSW_QoS_WRED_Profile_t eProfile; + /** Automatic or Manual Mode of Thresholds Config */ + GSW_QoS_WRED_Mode_t eMode; + /** WRED Threshold Mode Config */ + GSW_QoS_WRED_ThreshMode_t eThreshMode; + /** WRED Red Threshold Min [number of segments] - Valid for Manual Mode only. */ + u32 nRed_Min; + /** WRED Red Threshold Max [number of segments] - Valid for Manual Mode only */ + u32 nRed_Max; + /** WRED Yellow Threshold Min [number of segments] - Valid for Manual Mode only */ + u32 nYellow_Min; + /** WRED Yellow Threshold Max [number of segments] - Valid for Manual Mode only */ + u32 nYellow_Max; + /** WRED Green Threshold Min [number of segments] - Valid for Manual Mode only */ + u32 nGreen_Min; + /** WRED Green Threshold Max [number of segments] - Valid for Manual Mode only */ + u32 nGreen_Max; } GSW_QoS_WRED_Cfg_t; /** \brief Configures the WRED threshold level values. @@ -1111,22 +1074,21 @@ typedef struct buffer segments. The size of a segment can be retrieved using \ref GSW_CAP_GET. Used by \ref GSW_QOS_WRED_QUEUE_CFG_SET and \ref GSW_QOS_WRED_QUEUE_CFG_GET. */ -typedef struct -{ - /** QoS queue index (zero-based counting). */ - u32 nQueueId; - /** WRED Red Threshold Min [number of segments]. */ - u32 nRed_Min; - /** WRED Red Threshold Max [number of segments]. */ - u32 nRed_Max; - /** WRED Yellow Threshold Min [number of segments]. */ - u32 nYellow_Min; - /** WRED Yellow Threshold Max [number of segments]. */ - u32 nYellow_Max; - /** WRED Green Threshold Min [number of segments]. */ - u32 nGreen_Min; - /** WRED Green Threshold Max [number of segments]. */ - u32 nGreen_Max; +typedef struct { + /** QoS queue index (zero-based counting). */ + u32 nQueueId; + /** WRED Red Threshold Min [number of segments]. */ + u32 nRed_Min; + /** WRED Red Threshold Max [number of segments]. */ + u32 nRed_Max; + /** WRED Yellow Threshold Min [number of segments]. */ + u32 nYellow_Min; + /** WRED Yellow Threshold Max [number of segments]. */ + u32 nYellow_Max; + /** WRED Green Threshold Min [number of segments]. */ + u32 nGreen_Min; + /** WRED Green Threshold Max [number of segments]. */ + u32 nGreen_Max; } GSW_QoS_WRED_QueueCfg_t; /** \brief Configures the WRED threshold parameter per port. @@ -1136,23 +1098,22 @@ typedef struct buffer segments. The size of a segment can be retrieved using \ref GSW_CAP_GET. Used by \ref GSW_QOS_WRED_PORT_CFG_SET and \ref GSW_QOS_WRED_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). - The valid range is hardware dependent. */ - u32 nPortId; - /** WRED Red Threshold Min [number of segments]. */ - u32 nRed_Min; - /** WRED Red Threshold Max [number of segments]. */ - u32 nRed_Max; - /** WRED Yellow Threshold Min [number of segments]. */ - u32 nYellow_Min; - /** WRED Yellow Threshold Max [number of segments]. */ - u32 nYellow_Max; - /** WRED Green Threshold Min [number of segments]. */ - u32 nGreen_Min; - /** WRED Green Threshold Max [number of segments]. */ - u32 nGreen_Max; +typedef struct { + /** Ethernet Port number (zero-based counting). + The valid range is hardware dependent. */ + u32 nPortId; + /** WRED Red Threshold Min [number of segments]. */ + u32 nRed_Min; + /** WRED Red Threshold Max [number of segments]. */ + u32 nRed_Max; + /** WRED Yellow Threshold Min [number of segments]. */ + u32 nYellow_Min; + /** WRED Yellow Threshold Max [number of segments]. */ + u32 nYellow_Max; + /** WRED Green Threshold Min [number of segments]. */ + u32 nGreen_Min; + /** WRED Green Threshold Max [number of segments]. */ + u32 nGreen_Max; } GSW_QoS_WRED_PortCfg_t; /** \brief Configures the global buffer flow control threshold for @@ -1161,16 +1122,15 @@ typedef struct buffer segments. The size of a segment can be retrieved using \ref GSW_CAP_GET. Used by \ref GSW_QOS_FLOWCTRL_CFG_SET and \ref GSW_QOS_FLOWCTRL_CFG_GET. */ -typedef struct -{ - /** Global Buffer Non Conforming Flow Control Threshold Minimum [number of segments]. */ - u32 nFlowCtrlNonConform_Min; - /** Global Buffer Non Conforming Flow Control Threshold Maximum [number of segments]. */ - u32 nFlowCtrlNonConform_Max; - /** Global Buffer Conforming Flow Control Threshold Minimum [number of segments]. */ - u32 nFlowCtrlConform_Min; - /** Global Buffer Conforming Flow Control Threshold Maximum [number of segments]. */ - u32 nFlowCtrlConform_Max; +typedef struct { + /** Global Buffer Non Conforming Flow Control Threshold Minimum [number of segments]. */ + u32 nFlowCtrlNonConform_Min; + /** Global Buffer Non Conforming Flow Control Threshold Maximum [number of segments]. */ + u32 nFlowCtrlNonConform_Max; + /** Global Buffer Conforming Flow Control Threshold Minimum [number of segments]. */ + u32 nFlowCtrlConform_Min; + /** Global Buffer Conforming Flow Control Threshold Maximum [number of segments]. */ + u32 nFlowCtrlConform_Max; } GSW_QoS_FlowCtrlCfg_t; /** \brief Configures the ingress port flow control threshold for @@ -1179,238 +1139,225 @@ typedef struct buffer segments. The size of a segment can be retrieved using \ref GSW_CAP_GET. Used by \ref GSW_QOS_FLOWCTRL_PORT_CFG_SET and \ref GSW_QOS_FLOWCTRL_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). - The valid range is hardware dependent. */ - u32 nPortId; - /** Ingress Port occupied Buffer Flow Control Threshold Minimum [number of segments]. */ - u32 nFlowCtrl_Min; - /** Ingress Port occupied Buffer Flow Control Threshold Maximum [number of segments]. */ - u32 nFlowCtrl_Max; +typedef struct { + /** Ethernet Port number (zero-based counting). + The valid range is hardware dependent. */ + u32 nPortId; + /** Ingress Port occupied Buffer Flow Control Threshold Minimum [number of segments]. */ + u32 nFlowCtrl_Min; + /** Ingress Port occupied Buffer Flow Control Threshold Maximum [number of segments]. */ + u32 nFlowCtrl_Max; } GSW_QoS_FlowCtrlPortCfg_t; /** \brief Meter Type - srTCM or trTCM. Defines the Metering algorithm Type. Used by \ref GSW_QoS_meterCfg_t. */ -typedef enum -{ - /** srTCM Meter Type */ - GSW_QOS_Meter_srTCM = 0, - /** trTCM Meter Type - GSWIP-3.0 only */ - GSW_QOS_Meter_trTCM = 1, +typedef enum { + /** srTCM Meter Type */ + GSW_QOS_Meter_srTCM = 0, + /** trTCM Meter Type - GSWIP-3.0 only */ + GSW_QOS_Meter_trTCM = 1, } GSW_QoS_Meter_Type; /** \brief Configures the parameters of a rate meter instance. Used by \ref GSW_QOS_METER_ALLOC, \ref GSW_QOS_METER_FREE, \ref GSW_QOS_METER_CFG_SET and \ref GSW_QOS_METER_CFG_GET. */ -typedef struct -{ - /** Enable/Disable the meter shaper. */ - ltq_bool_t bEnable; - /** Meter index (zero-based counting). - - \remarks - For \ref GSW_QOS_METER_FREE, this is the only input and other fields are - ignored. For \ref GSW_QOS_METER_ALLOC, this is output when allocation - is successful. For \ref GSW_QOS_METER_CFG_SET and - \ref GSW_QOS_METER_CFG_GET, this is input to indicate meter to - configure/get-configuration. */ - u32 nMeterId; - /** Meter Name string for easy reference (Id to Name Mapping) - TBD*/ - char cMeterName[32]; - /** Meter Algorithm Type */ - GSW_QoS_Meter_Type eMtrType; - /** Committed Burst Size (CBS [Bytes]). */ - u32 nCbs; - /** Excess Burst Size (EBS [Bytes]). */ - u32 nEbs; - /** Committed Information Rate (CIR [kbit/s])*/ - u32 nRate; - /** Peak Information Rate (PIR [kbit/s]) - applicable for trTCM only */ - u32 nPiRate; - /** Peak Burst Size (PBS [Bytes]) - applicable for trTCM only */ +typedef struct { + /** Enable/Disable the meter shaper. */ + ltq_bool_t bEnable; + /** Meter index (zero-based counting). + + \remarks + For \ref GSW_QOS_METER_FREE, this is the only input and other fields are + ignored. For \ref GSW_QOS_METER_ALLOC, this is output when allocation + is successful. For \ref GSW_QOS_METER_CFG_SET and + \ref GSW_QOS_METER_CFG_GET, this is input to indicate meter to + configure/get-configuration. */ + u32 nMeterId; + /** Meter Name string for easy reference (Id to Name Mapping) - TBD*/ + char cMeterName[32]; + /** Meter Algorithm Type */ + GSW_QoS_Meter_Type eMtrType; + /** Committed Burst Size (CBS [Bytes]). */ + u32 nCbs; + /** Excess Burst Size (EBS [Bytes]). */ + u32 nEbs; + /** Committed Information Rate (CIR [kbit/s])*/ + u32 nRate; + /** Peak Information Rate (PIR [kbit/s]) - applicable for trTCM only */ + u32 nPiRate; + /** Peak Burst Size (PBS [Bytes]) - applicable for trTCM only */ // u32 nPbs; - /** Meter colour mode **/ - u32 nColourBlindMode; + /** Meter colour mode **/ + u32 nColourBlindMode; } GSW_QoS_meterCfg_t; /** \brief Specifies the direction for ingress and egress. Used by \ref GSW_QoS_meterPort_t and \ref GSW_QoS_meterPortGet_t. */ -typedef enum -{ - /** No direction. */ - GSW_DIRECTION_NONE = 0, - /** Ingress direction. */ - GSW_DIRECTION_INGRESS = 1, - /** Egress direction. */ - GSW_DIRECTION_EGRESS = 2, - /** Ingress and egress direction. */ - GSW_DIRECTION_BOTH = 3 +typedef enum { + /** No direction. */ + GSW_DIRECTION_NONE = 0, + /** Ingress direction. */ + GSW_DIRECTION_INGRESS = 1, + /** Egress direction. */ + GSW_DIRECTION_EGRESS = 2, + /** Ingress and egress direction. */ + GSW_DIRECTION_BOTH = 3 } GSW_direction_t; /** \brief Assign a rate meter instance to an ingress and/or egress port. Used by \ref GSW_QOS_METER_PORT_ASSIGN and \ref GSW_QOS_METER_PORT_DEASSIGN. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Meter index (zero-based counting). */ - u32 nMeterId; - /** Port assignment. Could be either ingress, egress or both. Setting it to - 'GSW_DIRECTION_NONE' would remove the queue for any port - assignment. */ - GSW_direction_t eDir; - /** Ingress Port Id. */ - u32 nPortIngressId; - /** Egress Port Id. */ - u32 nPortEgressId; +typedef struct { + /** Meter index (zero-based counting). */ + u32 nMeterId; + /** Port assignment. Could be either ingress, egress or both. Setting it to + 'GSW_DIRECTION_NONE' would remove the queue for any port + assignment. */ + GSW_direction_t eDir; + /** Ingress Port Id. */ + u32 nPortIngressId; + /** Egress Port Id. */ + u32 nPortEgressId; } GSW_QoS_meterPort_t; /** \brief Reads out all meter instance to port assignments. Used by \ref GSW_QOS_METER_PORT_GET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Restart the get operation from the start of the table. Otherwise - return the next table entry (next to the entry that was returned - during the previous get operation). This boolean parameter is set by the - calling application. */ - ltq_bool_t bInitial; - /** Indicates that the read operation got all last valid entries of the - table. This boolean parameter is set by the switch API - when the Switch API is called after the last valid one was returned already. */ - ltq_bool_t bLast; - /** Port assignment. Could be either ingress, egress or both. Setting it to - 'GSW_DIRECTION_NONE' would remove the queue for any port - assignment. */ - GSW_direction_t eDir; - /** Meter index (zero-based counting). */ - u8 nMeterId; - /** Ingress Port Id. */ - u8 nPortIngressId; - /** Egress Port Id. */ - u8 nPortEgressId; +typedef struct { + /** Restart the get operation from the start of the table. Otherwise + return the next table entry (next to the entry that was returned + during the previous get operation). This boolean parameter is set by the + calling application. */ + ltq_bool_t bInitial; + /** Indicates that the read operation got all last valid entries of the + table. This boolean parameter is set by the switch API + when the Switch API is called after the last valid one was returned already. */ + ltq_bool_t bLast; + /** Port assignment. Could be either ingress, egress or both. Setting it to + 'GSW_DIRECTION_NONE' would remove the queue for any port + assignment. */ + GSW_direction_t eDir; + /** Meter index (zero-based counting). */ + u8 nMeterId; + /** Ingress Port Id. */ + u8 nPortIngressId; + /** Egress Port Id. */ + u8 nPortEgressId; } GSW_QoS_meterPortGet_t; /** \brief Assigns one meter instances for storm control. Used by \ref GSW_QOS_STORM_CFG_SET and \ref GSW_QOS_STORM_CFG_GET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Meter index 0 (zero-based counting). */ - int nMeterId; - /** Meter instances used for broadcast traffic. */ - ltq_bool_t bBroadcast; - /** Meter instances used for multicast traffic. */ - ltq_bool_t bMulticast; - /** Meter instances used for unknown unicast traffic. */ - ltq_bool_t bUnknownUnicast; +typedef struct { + /** Meter index 0 (zero-based counting). */ + int nMeterId; + /** Meter instances used for broadcast traffic. */ + ltq_bool_t bBroadcast; + /** Meter instances used for multicast traffic. */ + ltq_bool_t bMulticast; + /** Meter instances used for unknown unicast traffic. */ + ltq_bool_t bUnknownUnicast; } GSW_QoS_stormCfg_t; /** \brief Triggers Metering Action for Traffic by CPU/MPE (available for GSWIP-3.0 only). Used by \ref GSW_QOS_METER_ACT */ -typedef struct -{ - /** CPU User Id - GSWIP-3.0 supports up to 2 users - CPU-0 & CPU-1 */ - u8 nCpuUserId; - /** Primary Meter Instance Id (zero-based counting). */ - u8 nMeterId; - /** Primary Meter Enable or Disable Action */ - ltq_bool_t bMeterEna; - /** Secondary Meter Instance Id (zero-based counting). (-1) to indicate this is not used */ - u8 nSecMeterId; - /** Secondary Meter Enable or Disable Action */ - ltq_bool_t bSecMeterEna; - /** Pre-Color to indicate the traffic type getting Metered. */ - GSW_QoS_DropPrecedence_t ePreColor; - /** Packet Length in Bytes subject to Metering action from CPU */ - u16 pktLen; - /** Metering Colour Output after it was subject to Metering Algorithm. - This is an output parameter carrying combined Meter action of two Meter instances */ - GSW_QoS_DropPrecedence_t eOutColor; +typedef struct { + /** CPU User Id - GSWIP-3.0 supports up to 2 users - CPU-0 & CPU-1 */ + u8 nCpuUserId; + /** Primary Meter Instance Id (zero-based counting). */ + u8 nMeterId; + /** Primary Meter Enable or Disable Action */ + ltq_bool_t bMeterEna; + /** Secondary Meter Instance Id (zero-based counting). (-1) to indicate this is not used */ + u8 nSecMeterId; + /** Secondary Meter Enable or Disable Action */ + ltq_bool_t bSecMeterEna; + /** Pre-Color to indicate the traffic type getting Metered. */ + GSW_QoS_DropPrecedence_t ePreColor; + /** Packet Length in Bytes subject to Metering action from CPU */ + u16 pktLen; + /** Metering Colour Output after it was subject to Metering Algorithm. + This is an output parameter carrying combined Meter action of two Meter instances */ + GSW_QoS_DropPrecedence_t eOutColor; } GSW_QoS_mtrAction_t; /** \brief Select the type of the Egress Queue Scheduler. Used by \ref GSW_QoS_schedulerCfg_t. */ -typedef enum -{ - /** Strict Priority Scheduler. */ - GSW_QOS_SCHEDULER_STRICT = 0, - /** Weighted Fair Queuing Shceduler. */ - GSW_QOS_SCHEDULER_WFQ = 1 +typedef enum { + /** Strict Priority Scheduler. */ + GSW_QOS_SCHEDULER_STRICT = 0, + /** Weighted Fair Queuing Shceduler. */ + GSW_QOS_SCHEDULER_WFQ = 1 } GSW_QoS_Scheduler_t; /** \brief Configures the egress queues attached to a single port, and that are scheduled to transmit the queued Ethernet packets. Used by \ref GSW_QOS_SCHEDULER_CFG_SET and \ref GSW_QOS_SCHEDULER_CFG_GET. */ -typedef struct -{ - /** QoS queue index (zero-based counting). */ - u8 nQueueId; - /** Scheduler Type (Strict Priority/Weighted Fair Queuing). */ - GSW_QoS_Scheduler_t eType; - /** Weight in Token. Parameter used for WFQ configuration. - Sets the weight in token in relation to all remaining - queues on this egress port having WFQ configuration. - This parameter is only used when 'eType=GSW_QOS_SCHEDULER_WFQ'. */ - u32 nWeight; +typedef struct { + /** QoS queue index (zero-based counting). */ + u8 nQueueId; + /** Scheduler Type (Strict Priority/Weighted Fair Queuing). */ + GSW_QoS_Scheduler_t eType; + /** Weight in Token. Parameter used for WFQ configuration. + Sets the weight in token in relation to all remaining + queues on this egress port having WFQ configuration. + This parameter is only used when 'eType=GSW_QOS_SCHEDULER_WFQ'. */ + u32 nWeight; } GSW_QoS_schedulerCfg_t; /** \brief Describes the QoS Queue Mapping Mode. GSWIP-3.1 only. Used by \ref GSW_QoS_queuePort_t. */ -typedef enum -{ - /** This is default mode where the QID is fixed at - \ref GSW_QOS_QUEUE_PORT_SET. */ - GSW_QOS_QMAP_SINGLE_MODE = 0, - /** This is new mode in GSWIP-3.1. The QID given in - \ref GSW_QOS_QUEUE_PORT_SET is base, and bit 0~3 of sub-interface ID - is offset. The final QID is base + SubIfId[0:3]. */ - GSW_QOS_QMAP_SUBIFID_MODE = 1 +typedef enum { + /** This is default mode where the QID is fixed at + \ref GSW_QOS_QUEUE_PORT_SET. */ + GSW_QOS_QMAP_SINGLE_MODE = 0, + /** This is new mode in GSWIP-3.1. The QID given in + \ref GSW_QOS_QUEUE_PORT_SET is base, and bit 0~3 of sub-interface ID + is offset. The final QID is base + SubIfId[0:3]. */ + GSW_QOS_QMAP_SUBIFID_MODE = 1 } GSW_QoS_qMapMode_t; /** \brief Sets the Queue ID for one traffic class of one port. Used by \ref GSW_QOS_QUEUE_PORT_SET and \ref GSW_QOS_QUEUE_PORT_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. - This is an input parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ - u16 nPortId; - /** Forward CPU (extraction) before external QoS queueing (DownMEP). - GSWIP-3.1 only. */ - ltq_bool_t bExtrationEnable; - /** When \ref GSW_QoS_queuePort_t::bExtrationEnable is FALSE, this field - defines Queue Mapping Mode. GSWIP-3.1 only. */ - GSW_QoS_qMapMode_t eQMapMode; - /** Traffic Class index (zero-based counting). - This is an input parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ - u8 nTrafficClassId; - /** QoS queue index (zero-based counting). - This is an output parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ - u8 nQueueId; - /** Queue Redirection bypass Option. - If enabled, all packets destined to 'nQueueId' are redirected from the - 'nPortId' to 'nRedirectPortId'. This is used for 2nd stage of FULL QoS - Path, where the packet has completed QoS process at CBM/CQEM and been - injected into GSWIP again. */ - ltq_bool_t bRedirectionBypass; - /** Redirected traffic forward port. - All egress packets to 'nPortId' are redirected to "nRedirectPortId". - If there is no redirection required, it should be same as "nPortId". - GSWIP-3.0/3.1 only. */ - u8 nRedirectPortId; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. + This is an input parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ + u16 nPortId; + /** Forward CPU (extraction) before external QoS queueing (DownMEP). + GSWIP-3.1 only. */ + ltq_bool_t bExtrationEnable; + /** When \ref GSW_QoS_queuePort_t::bExtrationEnable is FALSE, this field + defines Queue Mapping Mode. GSWIP-3.1 only. */ + GSW_QoS_qMapMode_t eQMapMode; + /** Traffic Class index (zero-based counting). + This is an input parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ + u8 nTrafficClassId; + /** QoS queue index (zero-based counting). + This is an output parameter for \ref GSW_QOS_QUEUE_PORT_GET. */ + u8 nQueueId; + /** Queue Redirection bypass Option. + If enabled, all packets destined to 'nQueueId' are redirected from the + 'nPortId' to 'nRedirectPortId'. This is used for 2nd stage of FULL QoS + Path, where the packet has completed QoS process at CBM/CQEM and been + injected into GSWIP again. */ + ltq_bool_t bRedirectionBypass; + /** Redirected traffic forward port. + All egress packets to 'nPortId' are redirected to "nRedirectPortId". + If there is no redirection required, it should be same as "nPortId". + GSWIP-3.0/3.1 only. */ + u8 nRedirectPortId; } GSW_QoS_queuePort_t; /** \brief Reserved egress queue buffer segments. Used by \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_SET and \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET. */ -typedef struct -{ - /** QoS queue index (zero-based counting). - This is an input parameter for \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET. */ - u8 nQueueId; - /** Reserved Buffer Segment Threshold [number of segments]. - This is an output parameter for \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET. */ - u32 nBufferReserved; +typedef struct { + /** QoS queue index (zero-based counting). + This is an input parameter for \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET. */ + u8 nQueueId; + /** Reserved Buffer Segment Threshold [number of segments]. + This is an output parameter for \ref GSW_QOS_QUEUE_BUFFER_RESERVE_CFG_GET. */ + u32 nBufferReserved; } GSW_QoS_QueueBufferReserveCfg_t; /** \brief Traffic class associated with a particular 802.1P (PCP) priority mapping value. @@ -1419,28 +1366,27 @@ typedef struct Bit 3 describes the 'DEI' field. Used by \ref GSW_QOS_SVLAN_CLASS_PCP_PORT_SET and \ref GSW_QOS_SVLAN_CLASS_PCP_PORT_GET. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Configures the traffic class to PCP (3-bit) mapping. - The queue index starts counting from zero. */ +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Configures the traffic class to PCP (3-bit) mapping. + The queue index starts counting from zero. */ // u8 nPCP_DEI[16]; - /** Configures the traffic class to CPCP (3-bit) mapping. - The queue index starts counting from zero. */ - u8 nCPCP[16]; + /** Configures the traffic class to CPCP (3-bit) mapping. + The queue index starts counting from zero. */ + u8 nCPCP[16]; - /** Configures the traffic class to SPCP (3-bit) mapping. - The queue index starts counting from zero. */ - u8 nSPCP[16]; + /** Configures the traffic class to SPCP (3-bit) mapping. + The queue index starts counting from zero. */ + u8 nSPCP[16]; - /** DSCP value (6-bit) associated with a particular Traffic class. - Traffic class is the index to an array of resulting DSCP values. - The index starts counting from zero. */ - u8 nDSCP[16]; + /** DSCP value (6-bit) associated with a particular Traffic class. + Traffic class is the index to an array of resulting DSCP values. + The index starts counting from zero. */ + u8 nDSCP[16]; } GSW_QoS_SVLAN_ClassPCP_PortCfg_t; @@ -1448,20 +1394,19 @@ typedef struct This table is global for the entire switch device. Priority map entry structure. The table index value is calculated by 'index=PCP + 8*DEI' Used by \ref GSW_QOS_SVLAN_PCP_CLASS_SET and \ref GSW_QOS_SVLAN_PCP_CLASS_GET. */ -typedef struct -{ - /** Configures the PCP and DEI to traffic class mapping. - The queue index starts counting from zero. */ - u8 nTrafficClass[16]; - /** Configures the PCP traffic color. - Not applicable to GSWIP-3.1. */ - u8 nTrafficColor[16]; - /** PCP Remark disable control. - Not applicable to GSWIP-3.1. */ - u8 nPCP_Remark_Enable[16]; - /** DEI Remark disable control. - Not applicable to GSWIP-3.1. */ - u8 nDEI_Remark_Enable[16]; +typedef struct { + /** Configures the PCP and DEI to traffic class mapping. + The queue index starts counting from zero. */ + u8 nTrafficClass[16]; + /** Configures the PCP traffic color. + Not applicable to GSWIP-3.1. */ + u8 nTrafficColor[16]; + /** PCP Remark disable control. + Not applicable to GSWIP-3.1. */ + u8 nPCP_Remark_Enable[16]; + /** DEI Remark disable control. + Not applicable to GSWIP-3.1. */ + u8 nDEI_Remark_Enable[16]; } GSW_QoS_SVLAN_PCP_ClassCfg_t; @@ -1473,274 +1418,266 @@ typedef struct /** \brief Configure the IGMP snooping mode. Used by \ref GSW_multicastSnoopCfg_t. */ -typedef enum -{ - /** IGMP management packet snooping and multicast level 3 table learning - is disabled. */ - GSW_MULTICAST_SNOOP_MODE_DISABLED = 0, - /** IGMP management packet snooping is enabled and used for the hardware - auto-learning to fill the multicast level 3 table. */ - GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING = 1, - /** IGMP management packet snooping is enabled and forwarded to the - configured port. No autolearning of the multicast level 3 table. This - table has to be maintained by the management software. */ - GSW_MULTICAST_SNOOP_MODE_FORWARD = 2 +typedef enum { + /** IGMP management packet snooping and multicast level 3 table learning + is disabled. */ + GSW_MULTICAST_SNOOP_MODE_DISABLED = 0, + /** IGMP management packet snooping is enabled and used for the hardware + auto-learning to fill the multicast level 3 table. */ + GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING = 1, + /** IGMP management packet snooping is enabled and forwarded to the + configured port. No autolearning of the multicast level 3 table. This + table has to be maintained by the management software. */ + GSW_MULTICAST_SNOOP_MODE_FORWARD = 2 } GSW_multicastSnoopMode_t; /** \brief Configure the IGMP report suppression mode. Used by \ref GSW_multicastSnoopCfg_t. */ -typedef enum -{ - /** Report Suppression and Join Aggregation. */ - GSW_MULTICAST_REPORT_JOIN = 0, - /** Report Suppression. No Join Aggregation. */ - GSW_MULTICAST_REPORT = 1, - /** Transparent Mode. No Report Suppression and no Join Aggregation. */ - GSW_MULTICAST_TRANSPARENT = 2 +typedef enum { + /** Report Suppression and Join Aggregation. */ + GSW_MULTICAST_REPORT_JOIN = 0, + /** Report Suppression. No Join Aggregation. */ + GSW_MULTICAST_REPORT = 1, + /** Transparent Mode. No Report Suppression and no Join Aggregation. */ + GSW_MULTICAST_TRANSPARENT = 2 } GSW_multicastReportSuppression_t; /** \brief Configure the switch multicast configuration. Used by \ref GSW_MULTICAST_SNOOP_CFG_SET and \ref GSW_MULTICAST_SNOOP_CFG_GET. */ -typedef struct -{ +typedef struct { /** Enables and configures the IGMP/MLD snooping feature. - Select autolearning or management packet forwarding mode. - Packet forwarding is done to the port selected in 'eForwardPort'. */ + Select autolearning or management packet forwarding mode. + Packet forwarding is done to the port selected in 'eForwardPort'. */ GSW_multicastSnoopMode_t eIGMP_Mode; /** IGMPv3 hardware support. - When enabled the IGMP table includes both the group table and - the source list table. Otherwise the table only includes the - group table. This feature is needed when supporting IGMPv3 and - MLDv2 protocols. */ + When enabled the IGMP table includes both the group table and + the source list table. Otherwise the table only includes the + group table. This feature is needed when supporting IGMPv3 and + MLDv2 protocols. */ ltq_bool_t bIGMPv3; /** Enables snooped IGMP control packets treated as cross-CTAG VLAN packets. This - parameter is used for hardware auto-learning and snooping packets - forwarded to a dedicated port. This dedicated port can be selected - over 'eForwardPort'. */ + parameter is used for hardware auto-learning and snooping packets + forwarded to a dedicated port. This dedicated port can be selected + over 'eForwardPort'. */ ltq_bool_t bCrossVLAN; /** Forward snooped packet, only used if forwarded mode - is selected - by 'eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_SNOOPFORWARD'. */ + is selected + by 'eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_SNOOPFORWARD'. */ GSW_portForward_t eForwardPort; /** Target port for forwarded packets, only used if selected by - 'eForwardPort'. Forwarding is done - if 'eForwardPort = GSW_PORT_FORWARD_PORT'. - This is Bridge Port ID in GSWIP-3.1. */ + 'eForwardPort'. Forwarding is done + if 'eForwardPort = GSW_PORT_FORWARD_PORT'. + This is Bridge Port ID in GSWIP-3.1. */ u8 nForwardPortId; /** Snooping control class of service. - Snooping control packet can be forwarded to the 'nForwardPortId' when - selected in 'eIGMP_Mode'. The class of service of this port can be - selected for the snooped control packets, starting from zero. - The maximum possible service class depends - on the hardware platform used. The value - GSW_TRAFFIC_CLASS_DISABLE disables overwriting the given - class assignment. */ + Snooping control packet can be forwarded to the 'nForwardPortId' when + selected in 'eIGMP_Mode'. The class of service of this port can be + selected for the snooped control packets, starting from zero. + The maximum possible service class depends + on the hardware platform used. The value + GSW_TRAFFIC_CLASS_DISABLE disables overwriting the given + class assignment. */ u8 nClassOfService; /** Robustness variable. - Used when the hardware-based IGMP/MLD snooping function is enabled. This - robust variable is used in case IGMP hardware learning is - enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). - Supported range: 1 ... 3 */ + Used when the hardware-based IGMP/MLD snooping function is enabled. This + robust variable is used in case IGMP hardware learning is + enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). + Supported range: 1 ... 3 */ u8 nRobust; /** Query interval. - Used to define the query interval in units of 100 ms when the - hardware-based IGMP/MLD snooping function is enabled. - The automatically learned router port will be aged out if no IGMP/MLD - query frame is received from the router port - for (nQueryInterval * nRobust) seconds. - The supported range is from 100 ms to 25.5 s, with a default value - of 10 s. This query interval is used in case IGMP hardware learning is - enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ + Used to define the query interval in units of 100 ms when the + hardware-based IGMP/MLD snooping function is enabled. + The automatically learned router port will be aged out if no IGMP/MLD + query frame is received from the router port + for (nQueryInterval * nRobust) seconds. + The supported range is from 100 ms to 25.5 s, with a default value + of 10 s. This query interval is used in case IGMP hardware learning is + enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ u8 nQueryInterval; /** IGMP/MLD report suppression and Join Aggregation control. - Whenever the report message is already sent out for the same multicast - group, the successive report message within the - query-max-responsetime with the same group ID will be filtered - by the switch. This is called report suppression. - Whenever the join message is already sent out for the same multicast - group, the successive join message with the same group ID will be filtered. - This is called join aggregation. This suppression control is used in - case IGMP hardware learning is - enable ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ + Whenever the report message is already sent out for the same multicast + group, the successive report message within the + query-max-responsetime with the same group ID will be filtered + by the switch. This is called report suppression. + Whenever the join message is already sent out for the same multicast + group, the successive join message with the same group ID will be filtered. + This is called join aggregation. This suppression control is used in + case IGMP hardware learning is + enable ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ GSW_multicastReportSuppression_t eSuppressionAggregation; /** Hardware IGMP snooping fast leave option. - Allows the hardware to automatically clear the membership - when receiving the IGMP leave packet. This - fast leave option is used in case IGMP hardware learning is - enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). - Note: The fast-leave option shall only be enabled where only - one host is connected to each interface. - If fast-leave is enabled where more than one host is connected - to an interface, some hosts might be dropped inadvertently. - Fast-leave processing is supported only with IGMP version 2 hosts. */ + Allows the hardware to automatically clear the membership + when receiving the IGMP leave packet. This + fast leave option is used in case IGMP hardware learning is + enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). + Note: The fast-leave option shall only be enabled where only + one host is connected to each interface. + If fast-leave is enabled where more than one host is connected + to an interface, some hosts might be dropped inadvertently. + Fast-leave processing is supported only with IGMP version 2 hosts. */ ltq_bool_t bFastLeave; - /** Hardware router port auto-learning. Allows for the - ports on which a router is located to be learned automatically. This router port learning option is - used in case IGMP hardware learning is - enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ + /** Hardware router port auto-learning. Allows for the + ports on which a router is located to be learned automatically. This router port learning option is + used in case IGMP hardware learning is + enabled ('eIGMP_Mode = GSW_MULTICAST_SNOOP_MODE_AUTOLEARNING'). */ ltq_bool_t bLearningRouter; - /** Discard Unknown IP Multicast Packets. - Multicast packets are defined as unknown in case the group address - cannot be found in the switch multicast group table. The table group - entries could be either automatically learned or they are statically - added. This Boolean parameter defines if such unknown multicast - packet are forwarded to the multicast forwarding - portmap (command \ref GSW_PORT_CFG_SET, - parameter 'bMulticastUnknownDrop') or if they are dropped instead. - - - 1: Drop unknown multicast packets. - - 0: Forward unknown multicast packets for the - multicast forwarding portmap. - */ + /** Discard Unknown IP Multicast Packets. + Multicast packets are defined as unknown in case the group address + cannot be found in the switch multicast group table. The table group + entries could be either automatically learned or they are statically + added. This Boolean parameter defines if such unknown multicast + packet are forwarded to the multicast forwarding + portmap (command \ref GSW_PORT_CFG_SET, + parameter 'bMulticastUnknownDrop') or if they are dropped instead. + + - 1: Drop unknown multicast packets. + - 0: Forward unknown multicast packets for the + multicast forwarding portmap. + */ ltq_bool_t bMulticastUnknownDrop; /** Multicast Forwarding based upon FID or Not - valid for GSWIP-3.0 only. - 1 : Multicast Forwarding is based upon FID. - 0 : Multicast Forwarding is not based upon FID. **/ - ltq_bool_t bMulticastFIDmode; + ltq_bool_t bMulticastFIDmode; } GSW_multicastSnoopCfg_t; /** \brief Add an Ethernet port as router port to the switch hardware multicast table. Used by \ref GSW_MULTICAST_ROUTER_PORT_ADD and \ref GSW_MULTICAST_ROUTER_PORT_REMOVE. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. - - \remarks - This field is used as portmap field, when the MSB bit is set. - In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u16 nPortId; +typedef struct { + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. + + \remarks + This field is used as portmap field, when the MSB bit is set. + In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u16 nPortId; } GSW_multicastRouter_t; /** \brief Check if a port has been selected as a router port. Used by \ref GSW_MULTICAST_ROUTER_PORT_READ. Not applicable to GSWIP-3.1. */ -typedef struct -{ - /** Restart the get operation from the start of the table. Otherwise - return the next table entry (next to the entry that was returned - during the previous get operation). This parameter is always reset - during the read operation. This boolean parameter is set by the - calling application. */ - ltq_bool_t bInitial; - /** Indicates that the read operation got all last valid entries of the - table. This boolean parameter is set by the switch API - when the Switch API is called after the last valid one was returned already. */ - ltq_bool_t bLast; - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; +typedef struct { + /** Restart the get operation from the start of the table. Otherwise + return the next table entry (next to the entry that was returned + during the previous get operation). This parameter is always reset + during the read operation. This boolean parameter is set by the + calling application. */ + ltq_bool_t bInitial; + /** Indicates that the read operation got all last valid entries of the + table. This boolean parameter is set by the switch API + when the Switch API is called after the last valid one was returned already. */ + ltq_bool_t bLast; + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; } GSW_multicastRouterRead_t; /** \brief Defines the multicast group member mode. Used by \ref GSW_multicastTable_t and \ref GSW_multicastTableRead_t. */ -typedef enum -{ - /** Include source IP address membership mode. - Only supported for IGMPv3. */ - GSW_IGMP_MEMBER_INCLUDE = 0, - /** Exclude source IP address membership mode. - Only supported for IGMPv3. */ - GSW_IGMP_MEMBER_EXCLUDE = 1, - /** Group source IP address is 'don't care'. This means all source IP - addresses (*) are included for the multicast group membership. - This is the default mode for IGMPv1 and IGMPv2. */ - GSW_IGMP_MEMBER_DONT_CARE = 2 +typedef enum { + /** Include source IP address membership mode. + Only supported for IGMPv3. */ + GSW_IGMP_MEMBER_INCLUDE = 0, + /** Exclude source IP address membership mode. + Only supported for IGMPv3. */ + GSW_IGMP_MEMBER_EXCLUDE = 1, + /** Group source IP address is 'don't care'. This means all source IP + addresses (*) are included for the multicast group membership. + This is the default mode for IGMPv1 and IGMPv2. */ + GSW_IGMP_MEMBER_DONT_CARE = 2 } GSW_IGMP_MemberMode_t; /** \brief Add a host as a member to a multicast group. Used by \ref GSW_MULTICAST_TABLE_ENTRY_ADD and \ref GSW_MULTICAST_TABLE_ENTRY_REMOVE. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u32 nPortId; - /** Sub-Interface Id - valid for GSWIP 3.0/3.1 only */ - u16 nSubIfId; - /** Select the IP version of the 'uIP_Gda' and 'uIP_Gsa' fields. - Both fields support either IPv4 or IPv6. */ - GSW_IP_Select_t eIPVersion; - /** Group Destination IP address (GDA). */ - GSW_IP_t uIP_Gda; - /** Group Source IP address. Only used in case IGMPv3 support is enabled - and 'eModeMember != GSW_IGMP_MEMBER_DONT_CARE'. */ - GSW_IP_t uIP_Gsa; - /** FID - valid for GSWIP 3.0 only subject to Global FID for MC is enabled. - always valid in GSWIP-3.1. */ - u8 nFID; - /** Exclude Mode - valid for GSWIP 3.0 only - Includes or Excludes Source IP - uIP_Gsa */ - ltq_bool_t bExclSrcIP; - /** Group member filter mode. - This is valid for GSWIP-3.0/3.1 to replaces bExclSrcIP. - This parameter is ignored when deleting a multicast membership table entry. - The configurations 'GSW_IGMP_MEMBER_EXCLUDE' - and 'GSW_IGMP_MEMBER_INCLUDE' are only supported - if IGMPv3 is used. */ - GSW_IGMP_MemberMode_t eModeMember; +typedef struct { + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u32 nPortId; + /** Sub-Interface Id - valid for GSWIP 3.0/3.1 only */ + u16 nSubIfId; + /** Select the IP version of the 'uIP_Gda' and 'uIP_Gsa' fields. + Both fields support either IPv4 or IPv6. */ + GSW_IP_Select_t eIPVersion; + /** Group Destination IP address (GDA). */ + GSW_IP_t uIP_Gda; + /** Group Source IP address. Only used in case IGMPv3 support is enabled + and 'eModeMember != GSW_IGMP_MEMBER_DONT_CARE'. */ + GSW_IP_t uIP_Gsa; + /** FID - valid for GSWIP 3.0 only subject to Global FID for MC is enabled. + always valid in GSWIP-3.1. */ + u8 nFID; + /** Exclude Mode - valid for GSWIP 3.0 only - Includes or Excludes Source IP - uIP_Gsa */ + ltq_bool_t bExclSrcIP; + /** Group member filter mode. + This is valid for GSWIP-3.0/3.1 to replaces bExclSrcIP. + This parameter is ignored when deleting a multicast membership table entry. + The configurations 'GSW_IGMP_MEMBER_EXCLUDE' + and 'GSW_IGMP_MEMBER_INCLUDE' are only supported + if IGMPv3 is used. */ + GSW_IGMP_MemberMode_t eModeMember; } GSW_multicastTable_t; /** \brief Read out the multicast membership table. Used by \ref GSW_MULTICAST_TABLE_ENTRY_READ. */ -typedef struct -{ - /** Restart the get operation from the beginning of the table. Otherwise - return the next table entry (next to the entry that was returned - during the previous get operation). This parameter is always reset - during the read operation. This boolean parameter is set by the - calling application. */ - ltq_bool_t bInitial; - /** Indicates that the read operation got all last valid entries of the - table. This boolean parameter is set by the switch API - when the Switch API is called after the last valid one was returned already. */ - ltq_bool_t bLast; - /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From - GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. - - \remarks - This field is used as portmap field, when the MSB bit is set. - In portmap mode, every value bit represents an Ethernet port. - LSB represents Port 0 with incrementing counting. - The (MSB - 1) bit represent the last port. - The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, - marking it as portmap variable. - Checking the portmap flag can be done by - using the \ref GSW_PORTMAP_FLAG_GET macro. */ - u16 nPortId; - /** Ethernet Port Map - to support GSWIP-3.1, following field is added - for port map in static entry. It's valid only when MSB of nPortId is set. - Each bit stands for 1 bridge port. */ - u16 nPortMap[16]; - /** Sub-Interface Id - valid for GSWIP 3.0 only */ - u8 nSubIfId; - /** Select the IP version of the 'uIP_Gda' and 'uIP_Gsa' fields. - Both fields support either IPv4 or IPv6. */ - GSW_IP_Select_t eIPVersion; - /** Group Destination IP address (GDA). */ - GSW_IP_t uIP_Gda; - /** Group Source IP address. Only used in case IGMPv3 support is enabled. */ - GSW_IP_t uIP_Gsa; - /** FID - valid for GSWIP 3.0 only subject to Global FID for MC is enabled */ - u8 nFID; - /** Exclude Mode - valid for GSWIP 3.0 only - Includes or Excludes Source IP - uIP_Gsa */ - ltq_bool_t bExclSrcIP; - /** Group member filter mode. - This parameter is ignored when deleting a multicast membership table entry. - The configurations 'GSW_IGMP_MEMBER_EXCLUDE' - and 'GSW_IGMP_MEMBER_INCLUDE' are only supported - if IGMPv3 is used. */ - GSW_IGMP_MemberMode_t eModeMember; +typedef struct { + /** Restart the get operation from the beginning of the table. Otherwise + return the next table entry (next to the entry that was returned + during the previous get operation). This parameter is always reset + during the read operation. This boolean parameter is set by the + calling application. */ + ltq_bool_t bInitial; + /** Indicates that the read operation got all last valid entries of the + table. This boolean parameter is set by the switch API + when the Switch API is called after the last valid one was returned already. */ + ltq_bool_t bLast; + /** Ethernet Port number (zero-based counting) in GSWIP-2.1/2.2/3.0. From + GSWIP-3.1, this field is Bridge Port ID. The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. + + \remarks + This field is used as portmap field, when the MSB bit is set. + In portmap mode, every value bit represents an Ethernet port. + LSB represents Port 0 with incrementing counting. + The (MSB - 1) bit represent the last port. + The macro \ref GSW_PORTMAP_FLAG_SET allows to set the MSB bit, + marking it as portmap variable. + Checking the portmap flag can be done by + using the \ref GSW_PORTMAP_FLAG_GET macro. */ + u16 nPortId; + /** Ethernet Port Map - to support GSWIP-3.1, following field is added + for port map in static entry. It's valid only when MSB of nPortId is set. + Each bit stands for 1 bridge port. */ + u16 nPortMap[16]; + /** Sub-Interface Id - valid for GSWIP 3.0 only */ + u8 nSubIfId; + /** Select the IP version of the 'uIP_Gda' and 'uIP_Gsa' fields. + Both fields support either IPv4 or IPv6. */ + GSW_IP_Select_t eIPVersion; + /** Group Destination IP address (GDA). */ + GSW_IP_t uIP_Gda; + /** Group Source IP address. Only used in case IGMPv3 support is enabled. */ + GSW_IP_t uIP_Gsa; + /** FID - valid for GSWIP 3.0 only subject to Global FID for MC is enabled */ + u8 nFID; + /** Exclude Mode - valid for GSWIP 3.0 only - Includes or Excludes Source IP - uIP_Gsa */ + ltq_bool_t bExclSrcIP; + /** Group member filter mode. + This parameter is ignored when deleting a multicast membership table entry. + The configurations 'GSW_IGMP_MEMBER_EXCLUDE' + and 'GSW_IGMP_MEMBER_INCLUDE' are only supported + if IGMPv3 is used. */ + GSW_IGMP_MemberMode_t eModeMember; } GSW_multicastTableRead_t; /*@}*/ /* GSW_IOCTL_MULTICAST */ @@ -1776,523 +1713,508 @@ typedef struct version information. A zero-based index is provided to the Switch API that describes the request version information. Used by \ref GSW_VERSION_GET. */ -typedef struct -{ - /** Version ID starting with 0. */ - u16 nId; - /** Name or ID of the version information. */ - char cName[GSW_VERSION_LEN]; - /** Version string information. */ - char cVersion[GSW_VERSION_LEN]; +typedef struct { + /** Version ID starting with 0. */ + u16 nId; + /** Name or ID of the version information. */ + char cName[GSW_VERSION_LEN]; + /** Version string information. */ + char cVersion[GSW_VERSION_LEN]; } GSW_version_t; /** \brief Switch API hardware initialization mode. Used by \ref GSW_HW_Init_t. */ -typedef enum -{ - /** Access the switch hardware to read out status and capability - information. Then define the basic hardware configuration to bring - the hardware into a pre-defined state. */ - GSW_HW_INIT_WR = 0, - /** Access the switch hardware to read out status and capability - information. Do not write any hardware configuration to the device. - This means that the current existing hardware configuration remains - unchanged. */ - GSW_HW_INIT_RO = 1, - /** Initialize the switch software module but do not touch the switch - hardware. This means that no read or write operations are done on - the switch hardware. Status and capability information cannot be - retrieved from the hardware. */ - GSW_HW_INIT_NO = 2 +typedef enum { + /** Access the switch hardware to read out status and capability + information. Then define the basic hardware configuration to bring + the hardware into a pre-defined state. */ + GSW_HW_INIT_WR = 0, + /** Access the switch hardware to read out status and capability + information. Do not write any hardware configuration to the device. + This means that the current existing hardware configuration remains + unchanged. */ + GSW_HW_INIT_RO = 1, + /** Initialize the switch software module but do not touch the switch + hardware. This means that no read or write operations are done on + the switch hardware. Status and capability information cannot be + retrieved from the hardware. */ + GSW_HW_INIT_NO = 2 } GSW_HW_InitMode_t; /** \brief Switch hardware platform initialization structure. Used by \ref GSW_HW_INIT. */ -typedef struct -{ - /** Select the type of Switch API and hardware initialization. */ - GSW_HW_InitMode_t eInitMode; +typedef struct { + /** Select the type of Switch API and hardware initialization. */ + GSW_HW_InitMode_t eInitMode; } GSW_HW_Init_t; /** \brief Aging Timer Value. Used by \ref GSW_cfg_t. */ -typedef enum -{ - /** 1 second aging time */ - GSW_AGETIMER_1_SEC = 1, - /** 10 seconds aging time */ - GSW_AGETIMER_10_SEC = 2, - /** 300 seconds aging time */ - GSW_AGETIMER_300_SEC = 3, - /** 1 hour aging time */ - GSW_AGETIMER_1_HOUR = 4, - /** 24 hours aging time */ - GSW_AGETIMER_1_DAY = 5, - /** Custom aging time in seconds */ - GSW_AGETIMER_CUSTOM = 6 +typedef enum { + /** 1 second aging time */ + GSW_AGETIMER_1_SEC = 1, + /** 10 seconds aging time */ + GSW_AGETIMER_10_SEC = 2, + /** 300 seconds aging time */ + GSW_AGETIMER_300_SEC = 3, + /** 1 hour aging time */ + GSW_AGETIMER_1_HOUR = 4, + /** 24 hours aging time */ + GSW_AGETIMER_1_DAY = 5, + /** Custom aging time in seconds */ + GSW_AGETIMER_CUSTOM = 6 } GSW_ageTimer_t; /** \brief Ethernet port speed mode. For certain generations of GSWIP, a port might support only a subset of the possible settings. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** 10 Mbit/s */ - GSW_PORT_SPEED_10 = 10, - /** 100 Mbit/s */ - GSW_PORT_SPEED_100 = 100, - /** 200 Mbit/s */ - GSW_PORT_SPEED_200 = 200, - /** 1000 Mbit/s */ - GSW_PORT_SPEED_1000 = 1000, - /** 2.5 Gbit/s */ - GSW_PORT_SPEED_25000 = 25000, - /** 10 Gbit/s */ - GSW_PORT_SPEED_100000= 100000, +typedef enum { + /** 10 Mbit/s */ + GSW_PORT_SPEED_10 = 10, + /** 100 Mbit/s */ + GSW_PORT_SPEED_100 = 100, + /** 200 Mbit/s */ + GSW_PORT_SPEED_200 = 200, + /** 1000 Mbit/s */ + GSW_PORT_SPEED_1000 = 1000, + /** 2.5 Gbit/s */ + GSW_PORT_SPEED_25000 = 25000, + /** 10 Gbit/s */ + GSW_PORT_SPEED_100000 = 100000, } GSW_portSpeed_t; /** \brief Ethernet port duplex status. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** Port operates in full-duplex mode */ - GSW_DUPLEX_FULL = 0, - /** Port operates in half-duplex mode */ - GSW_DUPLEX_HALF = 1 +typedef enum { + /** Port operates in full-duplex mode */ + GSW_DUPLEX_FULL = 0, + /** Port operates in half-duplex mode */ + GSW_DUPLEX_HALF = 1 } GSW_portDuplex_t; /** \brief Force the MAC and PHY link modus. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** Link up. Any connected LED - still behaves based on the real PHY status. */ - GSW_PORT_LINK_UP = 0, - /** Link down. */ - GSW_PORT_LINK_DOWN = 1 +typedef enum { + /** Link up. Any connected LED + still behaves based on the real PHY status. */ + GSW_PORT_LINK_UP = 0, + /** Link down. */ + GSW_PORT_LINK_DOWN = 1 } GSW_portLink_t; /** \brief Enumeration used for Switch capability types. GSWIP-3.0 only capabilities are explicitly indicated. Used by \ref GSW_cap_t. */ -typedef enum -{ - /** Number of physical Ethernet ports. */ - GSW_CAP_TYPE_PORT = 0, - /** Number of virtual Ethernet ports. */ - GSW_CAP_TYPE_VIRTUAL_PORT = 1, - /** Size of internal packet memory [in Bytes]. */ - GSW_CAP_TYPE_BUFFER_SIZE = 2, - /** Buffer segment size. - Byte size of a segment, used to store received packet data. */ - GSW_CAP_TYPE_SEGMENT_SIZE = 3, - /** Number of priority queues per device. */ - GSW_CAP_TYPE_PRIORITY_QUEUE = 4, - /** Number of meter instances. */ - GSW_CAP_TYPE_METER = 5, - /** Number of rate shaper instances. */ - GSW_CAP_TYPE_RATE_SHAPER = 6, - /** Number of CTAG VLAN groups that can be configured on the switch hardware. */ - GSW_CAP_TYPE_VLAN_GROUP = 7, - /** Number of Filtering Identifiers (FIDs) */ - GSW_CAP_TYPE_FID = 8, - /** Number of MAC Bridging table entries */ - GSW_CAP_TYPE_MAC_TABLE_SIZE = 9, - /** Number of multicast level 3 hardware table entries */ - GSW_CAP_TYPE_MULTICAST_TABLE_SIZE = 10, - /** Number of supported PPPoE sessions. */ - GSW_CAP_TYPE_PPPOE_SESSION = 11, - /** Number of STAG VLAN groups that can be configured on the switch hardware. */ - GSW_CAP_TYPE_SVLAN_GROUP = 12, - /** Number of PMAC Supported in Switch Macro - for GSWIP-3.0 only. */ - GSW_CAP_TYPE_PMAC = 13, - /** Number of entries in Payload Table size - for GSWIP-3.0 only. */ - GSW_CAP_TYPE_PAYLOAD = 14, - /** Number of RMON Counters Supported - for GSWIP-3.0 only. */ - GSW_CAP_TYPE_IF_RMON = 15, - /** Number of Egress VLAN Treatment Entries - for GSWIP-3.0 only. */ - GSW_CAP_TYPE_EGRESS_VLAN = 16, - /** Number of Routing Source-MAC Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_SMAC = 17, - /** Number of Routing Destination-MAC Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_DMAC = 18, - /** Number of Routing-PPPoE Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_PPPoE = 19, - /** Number of Routing-NAT Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_NAT = 20, - /** Number of MTU Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_MTU = 21, - /** Number of Tunnel Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_TUNNEL = 22, - /** Number of RTP Entries - for GSWIP-R-3.0 only. */ - GSW_CAP_TYPE_RT_RTP = 23, - /** Number of CTP ports - for GSWIP-3.1 only. */ - GSW_CAP_TYPE_CTP = 24, - /** Number of bridge ports - for GSWIP-3.1 only. */ - GSW_CAP_TYPE_BRIDGE_PORT = 25, - /** Last Capability Index */ - GSW_CAP_TYPE_LAST = 26 +typedef enum { + /** Number of physical Ethernet ports. */ + GSW_CAP_TYPE_PORT = 0, + /** Number of virtual Ethernet ports. */ + GSW_CAP_TYPE_VIRTUAL_PORT = 1, + /** Size of internal packet memory [in Bytes]. */ + GSW_CAP_TYPE_BUFFER_SIZE = 2, + /** Buffer segment size. + Byte size of a segment, used to store received packet data. */ + GSW_CAP_TYPE_SEGMENT_SIZE = 3, + /** Number of priority queues per device. */ + GSW_CAP_TYPE_PRIORITY_QUEUE = 4, + /** Number of meter instances. */ + GSW_CAP_TYPE_METER = 5, + /** Number of rate shaper instances. */ + GSW_CAP_TYPE_RATE_SHAPER = 6, + /** Number of CTAG VLAN groups that can be configured on the switch hardware. */ + GSW_CAP_TYPE_VLAN_GROUP = 7, + /** Number of Filtering Identifiers (FIDs) */ + GSW_CAP_TYPE_FID = 8, + /** Number of MAC Bridging table entries */ + GSW_CAP_TYPE_MAC_TABLE_SIZE = 9, + /** Number of multicast level 3 hardware table entries */ + GSW_CAP_TYPE_MULTICAST_TABLE_SIZE = 10, + /** Number of supported PPPoE sessions. */ + GSW_CAP_TYPE_PPPOE_SESSION = 11, + /** Number of STAG VLAN groups that can be configured on the switch hardware. */ + GSW_CAP_TYPE_SVLAN_GROUP = 12, + /** Number of PMAC Supported in Switch Macro - for GSWIP-3.0 only. */ + GSW_CAP_TYPE_PMAC = 13, + /** Number of entries in Payload Table size - for GSWIP-3.0 only. */ + GSW_CAP_TYPE_PAYLOAD = 14, + /** Number of RMON Counters Supported - for GSWIP-3.0 only. */ + GSW_CAP_TYPE_IF_RMON = 15, + /** Number of Egress VLAN Treatment Entries - for GSWIP-3.0 only. */ + GSW_CAP_TYPE_EGRESS_VLAN = 16, + /** Number of Routing Source-MAC Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_SMAC = 17, + /** Number of Routing Destination-MAC Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_DMAC = 18, + /** Number of Routing-PPPoE Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_PPPoE = 19, + /** Number of Routing-NAT Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_NAT = 20, + /** Number of MTU Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_MTU = 21, + /** Number of Tunnel Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_TUNNEL = 22, + /** Number of RTP Entries - for GSWIP-R-3.0 only. */ + GSW_CAP_TYPE_RT_RTP = 23, + /** Number of CTP ports - for GSWIP-3.1 only. */ + GSW_CAP_TYPE_CTP = 24, + /** Number of bridge ports - for GSWIP-3.1 only. */ + GSW_CAP_TYPE_BRIDGE_PORT = 25, + /** Last Capability Index */ + GSW_CAP_TYPE_LAST = 26 } GSW_capType_t; /** \brief Capability structure. Used by \ref GSW_CAP_GET. */ -typedef struct -{ - /** Defines the capability type, see \ref GSW_capType_t.*/ - GSW_capType_t nCapType; - /** Description of the capability. */ - char cDesc[GSW_CAP_STRING_LEN]; - /** Defines if, what or how many are available. The definition of cap - depends on the type, see captype. */ - u32 nCap; +typedef struct { + /** Defines the capability type, see \ref GSW_capType_t.*/ + GSW_capType_t nCapType; + /** Description of the capability. */ + char cDesc[GSW_CAP_STRING_LEN]; + /** Defines if, what or how many are available. The definition of cap + depends on the type, see captype. */ + u32 nCap; } GSW_cap_t; /** \brief Global Switch configuration Attributes. Used by \ref GSW_CFG_SET and \ref GSW_CFG_GET. */ -typedef struct -{ - /** MAC table aging timer. After this timer expires the MAC table - entry is aged out. */ - GSW_ageTimer_t eMAC_TableAgeTimer; - /** VLAN Awareness. The switch is VLAN unaware if this variable is disabled. - In this mode, no VLAN-related APIs are supported and return with an error. - The existing VLAN configuration is discarded when VLAN is disabled again. */ - ltq_bool_t bVLAN_Aware; - /** Maximum Ethernet packet length. */ - u16 nMaxPacketLen; - /** Automatic MAC address table learning limitation consecutive action. - These frame addresses are not learned, but there exists control as to whether - the frame is still forwarded or dropped. - - - False: Drop - - True: Forward - */ - ltq_bool_t bLearningLimitAction; - /** Accept or discard MAC spoofing and port MAC locking violation packets. - MAC spoofing detection features identifies ingress packets that carry - a MAC source address which was previously learned on a different - ingress port (learned by MAC bridging table). This also applies to - static added entries. MAC spoofing detection is enabled on port - level by 'bMAC_SpoofingDetection'. - MAC address port locking is configured on port level - by 'bLearningMAC_PortLock'. - - - False: Drop - - True: Forward - */ - ltq_bool_t bMAC_SpoofingAction; - /** Pause frame MAC source address mode. If enabled, use the alternative - address specified with 'nMAC'. */ - ltq_bool_t bPauseMAC_ModeSrc; - /** Pause frame MAC source address. */ - u8 nPauseMAC_Src[GSW_MAC_ADDR_LEN]; +typedef struct { + /** MAC table aging timer. After this timer expires the MAC table + entry is aged out. */ + GSW_ageTimer_t eMAC_TableAgeTimer; + /** If eMAC_TableAgeTimer = GSW_AGETIMER_CUSTOM, this variable defines + MAC table aging timer in seconds. */ + u32 nAgeTimer; + /** VLAN Awareness. The switch is VLAN unaware if this variable is disabled. + In this mode, no VLAN-related APIs are supported and return with an error. + The existing VLAN configuration is discarded when VLAN is disabled again. */ + ltq_bool_t bVLAN_Aware; + /** Maximum Ethernet packet length. */ + u16 nMaxPacketLen; + /** Automatic MAC address table learning limitation consecutive action. + These frame addresses are not learned, but there exists control as to whether + the frame is still forwarded or dropped. + + - False: Drop + - True: Forward + */ + ltq_bool_t bLearningLimitAction; + /** Accept or discard MAC spoofing and port MAC locking violation packets. + MAC spoofing detection features identifies ingress packets that carry + a MAC source address which was previously learned on a different + ingress port (learned by MAC bridging table). This also applies to + static added entries. MAC spoofing detection is enabled on port + level by 'bMAC_SpoofingDetection'. + MAC address port locking is configured on port level + by 'bLearningMAC_PortLock'. + + - False: Drop + - True: Forward + */ + ltq_bool_t bMAC_SpoofingAction; + /** Pause frame MAC source address mode. If enabled, use the alternative + address specified with 'nMAC'. */ + ltq_bool_t bPauseMAC_ModeSrc; + /** Pause frame MAC source address. */ + u8 nPauseMAC_Src[GSW_MAC_ADDR_LEN]; } GSW_cfg_t; /** \brief Port Enable Type Selection. Used by \ref GSW_portCfg_t. */ -typedef enum -{ - /** The port is disabled in both directions. */ - GSW_PORT_DISABLE = 0, - /** The port is enabled in both directions (ingress and egress). */ - GSW_PORT_ENABLE_RXTX = 1, - /** The port is enabled in the receive (ingress) direction only. */ - GSW_PORT_ENABLE_RX = 2, - /** The port is enabled in the transmit (egress) direction only. */ - GSW_PORT_ENABLE_TX = 3 +typedef enum { + /** The port is disabled in both directions. */ + GSW_PORT_DISABLE = 0, + /** The port is enabled in both directions (ingress and egress). */ + GSW_PORT_ENABLE_RXTX = 1, + /** The port is enabled in the receive (ingress) direction only. */ + GSW_PORT_ENABLE_RX = 2, + /** The port is enabled in the transmit (egress) direction only. */ + GSW_PORT_ENABLE_TX = 3 } GSW_portEnable_t; /** \brief Port Mirror Options. Used by \ref GSW_portCfg_t. */ -typedef enum -{ - /** Mirror Feature is disabled. Normal port usage. */ - GSW_PORT_MONITOR_NONE = 0, - /** Port Ingress packets are mirrored to the monitor port. */ - GSW_PORT_MONITOR_RX = 1, - /** Port Egress packets are mirrored to the monitor port. */ - GSW_PORT_MONITOR_TX = 2, - /** Port Ingress and Egress packets are mirrored to the monitor port. */ - GSW_PORT_MONITOR_RXTX = 3, - /** Packet mirroring of 'unknown VLAN violation' frames. */ - GSW_PORT_MONITOR_VLAN_UNKNOWN = 4, - /** Packet mirroring of 'VLAN ingress or egress membership violation' frames. */ - GSW_PORT_MONITOR_VLAN_MEMBERSHIP = 16, - /** Packet mirroring of 'port state violation' frames. */ - GSW_PORT_MONITOR_PORT_STATE = 32, - /** Packet mirroring of 'MAC learning limit violation' frames. */ - GSW_PORT_MONITOR_LEARNING_LIMIT = 64, - /** Packet mirroring of 'port lock violation' frames. */ - GSW_PORT_MONITOR_PORT_LOCK = 128 +typedef enum { + /** Mirror Feature is disabled. Normal port usage. */ + GSW_PORT_MONITOR_NONE = 0, + /** Port Ingress packets are mirrored to the monitor port. */ + GSW_PORT_MONITOR_RX = 1, + /** Port Egress packets are mirrored to the monitor port. */ + GSW_PORT_MONITOR_TX = 2, + /** Port Ingress and Egress packets are mirrored to the monitor port. */ + GSW_PORT_MONITOR_RXTX = 3, + /** Packet mirroring of 'unknown VLAN violation' frames. */ + GSW_PORT_MONITOR_VLAN_UNKNOWN = 4, + /** Packet mirroring of 'VLAN ingress or egress membership violation' frames. */ + GSW_PORT_MONITOR_VLAN_MEMBERSHIP = 16, + /** Packet mirroring of 'port state violation' frames. */ + GSW_PORT_MONITOR_PORT_STATE = 32, + /** Packet mirroring of 'MAC learning limit violation' frames. */ + GSW_PORT_MONITOR_LEARNING_LIMIT = 64, + /** Packet mirroring of 'port lock violation' frames. */ + GSW_PORT_MONITOR_PORT_LOCK = 128 } GSW_portMonitor_t; /** \brief Ethernet flow control status. Used by \ref GSW_portCfg_t. */ -typedef enum -{ - /** Automatic flow control mode selection through auto-negotiation. */ - GSW_FLOW_AUTO = 0, - /** Receive flow control only */ - GSW_FLOW_RX = 1, - /** Transmit flow control only */ - GSW_FLOW_TX = 2, - /** Receive and Transmit flow control */ - GSW_FLOW_RXTX = 3, - /** No flow control */ - GSW_FLOW_OFF = 4 +typedef enum { + /** Automatic flow control mode selection through auto-negotiation. */ + GSW_FLOW_AUTO = 0, + /** Receive flow control only */ + GSW_FLOW_RX = 1, + /** Transmit flow control only */ + GSW_FLOW_TX = 2, + /** Receive and Transmit flow control */ + GSW_FLOW_RXTX = 3, + /** No flow control */ + GSW_FLOW_OFF = 4 } GSW_portFlow_t; /** \brief Interface RMON Counter Mode - (FID, SUBID or FLOWID) Config - GSWIP-3.0 only. Used by \ref GSW_portCfg_t. */ -typedef enum -{ - /** FID based Interface RMON counters Usage */ - GSW_IF_RMON_FID = 0, - /** Sub-Interface Id based Interface RMON counters Usage */ - GSW_IF_RMON_SUBID = 1, - /** Flow Id (LSB bits 3 to 0) based Interface RMON counters Usage */ - GSW_IF_RMON_FLOWID_LSB = 2, - /** Flow Id (MSB bits 7 to 4) based Interface RMON counters Usage */ - GSW_IF_RMON_FLOWID_MSB = 3 +typedef enum { + /** FID based Interface RMON counters Usage */ + GSW_IF_RMON_FID = 0, + /** Sub-Interface Id based Interface RMON counters Usage */ + GSW_IF_RMON_SUBID = 1, + /** Flow Id (LSB bits 3 to 0) based Interface RMON counters Usage */ + GSW_IF_RMON_FLOWID_LSB = 2, + /** Flow Id (MSB bits 7 to 4) based Interface RMON counters Usage */ + GSW_IF_RMON_FLOWID_MSB = 3 } GSW_If_RMON_Mode_t; /** \brief Port Type - GSWIP-3.1 only. Used by \ref GSW_portCfg_t. */ -typedef enum -{ - GSW_PHYSICAL_PORT = 0, - GSW_LOGICAL_PORT = 1, - GSW_CTP_PORT = 2, - GSW_BRIDGE_PORT = 3 +typedef enum { + /** Logical Port */ + GSW_LOGICAL_PORT = 0, + /** Physical Port + Applicable only for GSWIP-3.1/3.2 */ + GSW_PHYSICAL_PORT = 1, + /** Connectivity Termination Port (CTP) + Applicable only for GSWIP-3.1/3.2 */ + GSW_CTP_PORT = 2, + /** Bridge Port + Applicable only for GSWIP-3.1/3.2 */ + GSW_BRIDGE_PORT = 3 } GSW_portType_t; /** \brief Port Configuration Parameters. Used by \ref GSW_PORT_CFG_GET and \ref GSW_PORT_CFG_SET. */ -typedef struct -{ - /** Port Type. This gives information which type of port is configured. - nPortId should be based on this field. */ - GSW_portType_t ePortType; - - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Enable Port (ingress only, egress only, both directions, or disabled). - This parameter is used for Spanning Tree Protocol and 802.1X applications. */ - GSW_portEnable_t eEnable; - /** Drop unknown unicast packets. - Do not send out unknown unicast packets on this port, - if the boolean parameter is enabled. By default packets of this type - are forwarded to this port. */ - ltq_bool_t bUnicastUnknownDrop; - /** Drop unknown multicast packets. - Do not send out unknown multicast packets on this port, - if boolean parameter is enabled. By default packets of this type - are forwarded to this port. - Some platforms also drop broadcast packets. */ - ltq_bool_t bMulticastUnknownDrop; - /** Drop reserved packet types - (destination address from '01 80 C2 00 00 00' to - '01 80 C2 00 00 2F') received on this port. */ - ltq_bool_t bReservedPacketDrop; - /** Drop Broadcast packets received on this port. By default packets of this - type are forwarded to this port. */ - ltq_bool_t bBroadcastDrop; - /** Enables MAC address table aging. - The MAC table entries learned on this port are removed after the - aging time has expired. - The aging time is a global parameter, common to all ports. */ - ltq_bool_t bAging; - /** MAC address table learning on the port specified by 'nPortId'. - By default this parameter is always enabled. */ - ltq_bool_t bLearning; - /** Automatic MAC address table learning locking on the port specified - by 'nPortId'. - This parameter is only taken into account when 'bLearning' is enabled. */ - ltq_bool_t bLearningMAC_PortLock; - /** Automatic MAC address table learning limitation on this port. - The learning functionality is disabled when the limit value is zero. - The value 0xFFFF to allow unlimited learned address. - This parameter is only taken into account when 'bLearning' is enabled. */ - u16 nLearningLimit; - /** MAC spoofing detection. Identifies ingress packets that carry - a MAC source address which was previously learned on a different ingress - port (learned by MAC bridging table). This also applies to static added - entries. Those violated packets could be accepted or discarded, - depending on the global switch configuration 'bMAC_SpoofingAction'. - This parameter is only taken into account when 'bLearning' is enabled. */ - ltq_bool_t bMAC_SpoofingDetection; - /** Port Flow Control Status. Enables the flow control function. */ - GSW_portFlow_t eFlowCtrl; - /** Port monitor feature. Allows forwarding of egress and/or ingress - packets to the monitor port. If enabled, the monitor port gets - a copy of the selected packet type. */ - GSW_portMonitor_t ePortMonitor; - /** Assign Interface RMON Counters for this Port - GSWIP-3.0 */ - ltq_bool_t bIfCounters; - /** Interface RMON Counters Start Index - GSWIP-3.0. - Value of (-1) denotes unassigned Interface Counters. - Valid range : 0-255 available to be shared amongst ports in desired way*/ - int nIfCountStartIdx; - /** Interface RMON Counters Mode - GSWIP-3.0 */ - GSW_If_RMON_Mode_t eIfRMONmode; +typedef struct { + /** Port Type. This gives information which type of port is configured. + nPortId should be based on this field. */ + GSW_portType_t ePortType; + + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Enable Port (ingress only, egress only, both directions, or disabled). + This parameter is used for Spanning Tree Protocol and 802.1X applications. */ + GSW_portEnable_t eEnable; + /** Drop unknown unicast packets. + Do not send out unknown unicast packets on this port, + if the boolean parameter is enabled. By default packets of this type + are forwarded to this port. */ + ltq_bool_t bUnicastUnknownDrop; + /** Drop unknown multicast packets. + Do not send out unknown multicast packets on this port, + if boolean parameter is enabled. By default packets of this type + are forwarded to this port. + Some platforms also drop broadcast packets. */ + ltq_bool_t bMulticastUnknownDrop; + /** Drop reserved packet types + (destination address from '01 80 C2 00 00 00' to + '01 80 C2 00 00 2F') received on this port. */ + ltq_bool_t bReservedPacketDrop; + /** Drop Broadcast packets received on this port. By default packets of this + type are forwarded to this port. */ + ltq_bool_t bBroadcastDrop; + /** Enables MAC address table aging. + The MAC table entries learned on this port are removed after the + aging time has expired. + The aging time is a global parameter, common to all ports. */ + ltq_bool_t bAging; + /** MAC address table learning on the port specified by 'nPortId'. + By default this parameter is always enabled. */ + ltq_bool_t bLearning; + /** Automatic MAC address table learning locking on the port specified + by 'nPortId'. + This parameter is only taken into account when 'bLearning' is enabled. */ + ltq_bool_t bLearningMAC_PortLock; + /** Automatic MAC address table learning limitation on this port. + The learning functionality is disabled when the limit value is zero. + The value 0xFFFF to allow unlimited learned address. + This parameter is only taken into account when 'bLearning' is enabled. */ + u16 nLearningLimit; + /** MAC spoofing detection. Identifies ingress packets that carry + a MAC source address which was previously learned on a different ingress + port (learned by MAC bridging table). This also applies to static added + entries. Those violated packets could be accepted or discarded, + depending on the global switch configuration 'bMAC_SpoofingAction'. + This parameter is only taken into account when 'bLearning' is enabled. */ + ltq_bool_t bMAC_SpoofingDetection; + /** Port Flow Control Status. Enables the flow control function. */ + GSW_portFlow_t eFlowCtrl; + /** Port monitor feature. Allows forwarding of egress and/or ingress + packets to the monitor port. If enabled, the monitor port gets + a copy of the selected packet type. */ + GSW_portMonitor_t ePortMonitor; + /** Assign Interface RMON Counters for this Port - GSWIP-3.0 */ + ltq_bool_t bIfCounters; + /** Interface RMON Counters Start Index - GSWIP-3.0. + Value of (-1) denotes unassigned Interface Counters. + Valid range : 0-255 available to be shared amongst ports in desired way*/ + int nIfCountStartIdx; + /** Interface RMON Counters Mode - GSWIP-3.0 */ + GSW_If_RMON_Mode_t eIfRMONmode; } GSW_portCfg_t; /** \brief Special tag Ethertype mode */ -typedef enum -{ - /** The EtherType field of the Special Tag of egress packets is always set - to a prefined value. This same defined value applies for all - switch ports. */ - GSW_CPU_ETHTYPE_PREDEFINED = 0, - /** The Ethertype field of the Special Tag of egress packets is set to - the FlowID parameter, which is a results of the switch flow - classification result. The switch flow table rule provides this - FlowID as action parameter. */ - GSW_CPU_ETHTYPE_FLOWID = 1 +typedef enum { + /** The EtherType field of the Special Tag of egress packets is always set + to a prefined value. This same defined value applies for all + switch ports. */ + GSW_CPU_ETHTYPE_PREDEFINED = 0, + /** The Ethertype field of the Special Tag of egress packets is set to + the FlowID parameter, which is a results of the switch flow + classification result. The switch flow table rule provides this + FlowID as action parameter. */ + GSW_CPU_ETHTYPE_FLOWID = 1 } GSW_CPU_SpecialTagEthType_t; /** \brief Parser Flags and Offsets Header settings on CPU Port for GSWIP-3.0. Used by \ref GSW_CPU_PortCfg_t. */ -typedef enum -{ - /** No Parsing Flags or Offsets accompanying to CPU Port for this combination */ - GSW_CPU_PARSER_NIL = 0, - /** 8-Bytes Parsing Flags (Bit 63:0) accompanying to CPU Port for this combination */ - GSW_CPU_PARSER_FLAGS = 1, - /** 40-Bytes Offsets (Offset-0 to -39) + 8-Bytes Parsing Flags (Bit 63:0) accompanying to CPU Port for this combination */ - GSW_CPU_PARSER_OFFSETS_FLAGS = 2, - /** Reserved - for future use */ - GSW_CPU_PARSER_RESERVED = 3 +typedef enum { + /** No Parsing Flags or Offsets accompanying to CPU Port for this combination */ + GSW_CPU_PARSER_NIL = 0, + /** 8-Bytes Parsing Flags (Bit 63:0) accompanying to CPU Port for this combination */ + GSW_CPU_PARSER_FLAGS = 1, + /** 40-Bytes Offsets (Offset-0 to -39) + 8-Bytes Parsing Flags (Bit 63:0) accompanying to CPU Port for this combination */ + GSW_CPU_PARSER_OFFSETS_FLAGS = 2, + /** Reserved - for future use */ + GSW_CPU_PARSER_RESERVED = 3 } GSW_CPU_ParserHeaderCfg_t; /** \brief Defines one port that is directly connected to the CPU and its applicable settings. Used by \ref GSW_CPU_PORT_CFG_SET and \ref GSW_CPU_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting) set to CPU Port. The valid number is hardware - dependent. (E.g. Port number 0 for GSWIP-3.0 or 6 for GSWIP-2.x). An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** CPU port validity. - Set command: set true to define a CPU port, set false to undo the setting. - Get command: true if defined as CPU, false if not defined as CPU port. */ - ltq_bool_t bCPU_PortValid; - /** Special tag enable in ingress direction. */ - ltq_bool_t bSpecialTagIngress; - /** Special tag enable in egress direction. */ - ltq_bool_t bSpecialTagEgress; - /** Enable FCS check - - - false: No check, forward all frames - - 1: Check FCS, drop frames with errors - */ - ltq_bool_t bFcsCheck; - /** Enable FCS generation - - - false: Forward packets without FCS - - 1: Generate FCS for all frames - */ - ltq_bool_t bFcsGenerate; - /** Special tag Ethertype mode. Not applicable to GSWIP-3.1. */ - GSW_CPU_SpecialTagEthType_t bSpecialTagEthType; - /** GSWIP-3.0 specific Parser Header Config for no MPE flags (i.e. MPE1=0, MPE2=0). */ - GSW_CPU_ParserHeaderCfg_t eNoMPEParserCfg; - /** GSWIP-3.0 specific Parser Header Config for MPE-1 set flag (i.e. MPE1=1, MPE2=0). */ - GSW_CPU_ParserHeaderCfg_t eMPE1ParserCfg; - /** GSWIP-3.0 specific Parser Header Config for MPE-2 set flag (i.e. MPE1=0, MPE2=1). */ - GSW_CPU_ParserHeaderCfg_t eMPE2ParserCfg; - /** GSWIP-3.0 specific Parser Header Config for both MPE-1 and MPE-2 set flag (i.e. MPE1=1, MPE2=1). */ - GSW_CPU_ParserHeaderCfg_t eMPE1MPE2ParserCfg; +typedef struct { + /** Ethernet Port number (zero-based counting) set to CPU Port. The valid number is hardware + dependent. (E.g. Port number 0 for GSWIP-3.0 or 6 for GSWIP-2.x). An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** CPU port validity. + Set command: set true to define a CPU port, set false to undo the setting. + Get command: true if defined as CPU, false if not defined as CPU port. */ + ltq_bool_t bCPU_PortValid; + /** Special tag enable in ingress direction. */ + ltq_bool_t bSpecialTagIngress; + /** Special tag enable in egress direction. */ + ltq_bool_t bSpecialTagEgress; + /** Enable FCS check + + - false: No check, forward all frames + - 1: Check FCS, drop frames with errors + */ + ltq_bool_t bFcsCheck; + /** Enable FCS generation + + - false: Forward packets without FCS + - 1: Generate FCS for all frames + */ + ltq_bool_t bFcsGenerate; + /** Special tag Ethertype mode. Not applicable to GSWIP-3.1. */ + GSW_CPU_SpecialTagEthType_t bSpecialTagEthType; + /** GSWIP-3.0 specific Parser Header Config for no MPE flags (i.e. MPE1=0, MPE2=0). */ + GSW_CPU_ParserHeaderCfg_t eNoMPEParserCfg; + /** GSWIP-3.0 specific Parser Header Config for MPE-1 set flag (i.e. MPE1=1, MPE2=0). */ + GSW_CPU_ParserHeaderCfg_t eMPE1ParserCfg; + /** GSWIP-3.0 specific Parser Header Config for MPE-2 set flag (i.e. MPE1=0, MPE2=1). */ + GSW_CPU_ParserHeaderCfg_t eMPE2ParserCfg; + /** GSWIP-3.0 specific Parser Header Config for both MPE-1 and MPE-2 set flag (i.e. MPE1=1, MPE2=1). */ + GSW_CPU_ParserHeaderCfg_t eMPE1MPE2ParserCfg; } GSW_CPU_PortCfg_t; /** \brief Ethernet layer-2 header selector, when adding or removing on transmitted packets. Used by \ref GSW_CPU_PortExtendCfg_t. */ -typedef enum -{ - /** No additional Ethernet header. */ - GSW_CPU_HEADER_NO = 0, - /** Additional Ethernet header. */ - GSW_CPU_HEADER_MAC = 1, - /** Additional Ethernet- and CTAG VLAN- header. */ - GSW_CPU_HEADER_VLAN = 2 +typedef enum { + /** No additional Ethernet header. */ + GSW_CPU_HEADER_NO = 0, + /** Additional Ethernet header. */ + GSW_CPU_HEADER_MAC = 1, + /** Additional Ethernet- and CTAG VLAN- header. */ + GSW_CPU_HEADER_VLAN = 2 } GSW_CPU_HeaderMode_t; /** \brief CPU Port Layer-2 Header extension. Used by \ref GSW_CPU_PortExtendCfg_t. */ -typedef struct -{ - /** Packet MAC Source Address. */ - u8 nMAC_Src[GSW_MAC_ADDR_LEN]; - /** Packet MAC Destination Address. */ - u8 nMAC_Dst[GSW_MAC_ADDR_LEN]; - /** Packet EtherType Field. */ - u16 nEthertype; - /** CTAG VLAN Tag Priority Field. - Only used when adding VLAN tag is - enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ - u8 nVLAN_Prio; - /** CTAG VLAN Tag Canonical Format Identifier. - Only used when adding VLAN tag is - enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ - u8 nVLAN_CFI; - /** CTAG VLAN Tag VID. - Only used when adding VLAN tag is - enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ - u16 nVLAN_ID; +typedef struct { + /** Packet MAC Source Address. */ + u8 nMAC_Src[GSW_MAC_ADDR_LEN]; + /** Packet MAC Destination Address. */ + u8 nMAC_Dst[GSW_MAC_ADDR_LEN]; + /** Packet EtherType Field. */ + u16 nEthertype; + /** CTAG VLAN Tag Priority Field. + Only used when adding VLAN tag is + enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ + u8 nVLAN_Prio; + /** CTAG VLAN Tag Canonical Format Identifier. + Only used when adding VLAN tag is + enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ + u8 nVLAN_CFI; + /** CTAG VLAN Tag VID. + Only used when adding VLAN tag is + enabled (eHeaderAdd=GSW_CPU_HEADER_VLAN). */ + u16 nVLAN_ID; } GSW_CPU_Header_t; /** \brief CPU port PAUSE frame handling. Used by \ref GSW_CPU_PortExtendCfg_t. */ -typedef enum -{ - /** Forward all PAUSE frames coming from the switch macro towards - the DMA channel. These frames do not influence the packet transmission. */ - GSW_CPU_PAUSE_FORWARD = 0, - /** Dispatch all PAUSE frames coming from the switch macro towards - the DMA channel. These are filtered out and the packets transmission is - stopped and restarted accordingly. */ - GSW_CPU_PAUSE_DISPATCH = 1 +typedef enum { + /** Forward all PAUSE frames coming from the switch macro towards + the DMA channel. These frames do not influence the packet transmission. */ + GSW_CPU_PAUSE_FORWARD = 0, + /** Dispatch all PAUSE frames coming from the switch macro towards + the DMA channel. These are filtered out and the packets transmission is + stopped and restarted accordingly. */ + GSW_CPU_PAUSE_DISPATCH = 1 } GSW_CPU_Pause_t; /** \brief Ethernet port interface mode. A port might support only a subset of the possible settings. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** Normal PHY interface (twisted pair), use the internal MII Interface. */ - GSW_PORT_HW_MII = 0, - /** Reduced MII interface in normal mode. */ - GSW_PORT_HW_RMII = 1, - /** GMII or MII, depending upon the speed. */ - GSW_PORT_HW_GMII = 2, - /** RGMII mode. */ - GSW_PORT_HW_RGMII = 3, - /** XGMII mode. */ - GSW_PORT_HW_XGMII = 4, +typedef enum { + /** Normal PHY interface (twisted pair), use the internal MII Interface. */ + GSW_PORT_HW_MII = 0, + /** Reduced MII interface in normal mode. */ + GSW_PORT_HW_RMII = 1, + /** GMII or MII, depending upon the speed. */ + GSW_PORT_HW_GMII = 2, + /** RGMII mode. */ + GSW_PORT_HW_RGMII = 3, + /** XGMII mode. */ + GSW_PORT_HW_XGMII = 4, } GSW_MII_Mode_t; /** \brief Ethernet port configuration for PHY or MAC mode. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** MAC Mode. The Ethernet port is configured to work in MAC mode. */ - GSW_PORT_MAC = 0, - /** PHY Mode. The Ethernet port is configured to work in PHY mode. */ - GSW_PORT_PHY = 1 +typedef enum { + /** MAC Mode. The Ethernet port is configured to work in MAC mode. */ + GSW_PORT_MAC = 0, + /** PHY Mode. The Ethernet port is configured to work in PHY mode. */ + GSW_PORT_PHY = 1 } GSW_MII_Type_t; /** \brief Ethernet port clock source configuration. Used by \ref GSW_portLinkCfg_t. */ -typedef enum -{ - /** Clock Mode not applicable. */ - GSW_PORT_CLK_NA = 0, - /** Clock Master Mode. The port is configured to provide the clock as output signal. */ - GSW_PORT_CLK_MASTER = 1, - /** Clock Slave Mode. The port is configured to use the input clock signal. */ - GSW_PORT_CLK_SLAVE = 2 +typedef enum { + /** Clock Mode not applicable. */ + GSW_PORT_CLK_NA = 0, + /** Clock Master Mode. The port is configured to provide the clock as output signal. */ + GSW_PORT_CLK_MASTER = 1, + /** Clock Slave Mode. The port is configured to use the input clock signal. */ + GSW_PORT_CLK_SLAVE = 2 } GSW_clkMode_t; /** \brief Additional CPU port configuration for platforms where the CPU port is @@ -2300,173 +2222,165 @@ typedef enum Used by \ref GSW_CPU_PORT_EXTEND_CFG_SET and \ref GSW_CPU_PORT_EXTEND_CFG_GET. */ -typedef struct -{ - /** Add Ethernet layer-2 header (also CTAG VLAN) to the transmit packet. - The corresponding header fields are set in 'sHeader'. */ - GSW_CPU_HeaderMode_t eHeaderAdd; - /** Remove Ethernet layer-2 header (also CTAG VLAN) for packets going from - Ethernet switch to the DMA. Only the first VLAN tag found is removed - and additional available VLAN tags remain untouched. */ - ltq_bool_t bHeaderRemove; - /** Ethernet layer-2 header information. Used when adding a header to the - transmitted packet. The parameter 'eHeaderAdd' selects the mode if - a layer-2 header should be added (including VLAN). - This structure contains all fields of the Ethernet and VLAN header. */ - GSW_CPU_Header_t sHeader; - /** Describes how the port handles received PAUSE frames coming from the - switch. Either forward them to DMA or stop/start transmission. - Note that the parameter 'eFlowCtrl' of the - command 'GSW_PORT_CFG_SET' determines whether the switch - generates PAUSE frames. */ - GSW_CPU_Pause_t ePauseCtrl; - /** Remove the CRC (FCS) of all packets coming from the switch towards - the DMA channel. - Note that the FCS check and generation option can be configured - using 'GSW_CPU_PORT_CFG_SET'. */ - ltq_bool_t bFcsRemove; - /** Port map of Ethernet switch ports that are assigned to the WAN side - (dedicated for applications where ports are grouped into WAN- and - LAN-segments). All ports that are not selected belong to the LAN segment. - The LSB bit represents port 0, the higher bits represent the higher - port numbers. */ - u32 nWAN_Ports; +typedef struct { + /** Add Ethernet layer-2 header (also CTAG VLAN) to the transmit packet. + The corresponding header fields are set in 'sHeader'. */ + GSW_CPU_HeaderMode_t eHeaderAdd; + /** Remove Ethernet layer-2 header (also CTAG VLAN) for packets going from + Ethernet switch to the DMA. Only the first VLAN tag found is removed + and additional available VLAN tags remain untouched. */ + ltq_bool_t bHeaderRemove; + /** Ethernet layer-2 header information. Used when adding a header to the + transmitted packet. The parameter 'eHeaderAdd' selects the mode if + a layer-2 header should be added (including VLAN). + This structure contains all fields of the Ethernet and VLAN header. */ + GSW_CPU_Header_t sHeader; + /** Describes how the port handles received PAUSE frames coming from the + switch. Either forward them to DMA or stop/start transmission. + Note that the parameter 'eFlowCtrl' of the + command 'GSW_PORT_CFG_SET' determines whether the switch + generates PAUSE frames. */ + GSW_CPU_Pause_t ePauseCtrl; + /** Remove the CRC (FCS) of all packets coming from the switch towards + the DMA channel. + Note that the FCS check and generation option can be configured + using 'GSW_CPU_PORT_CFG_SET'. */ + ltq_bool_t bFcsRemove; + /** Port map of Ethernet switch ports that are assigned to the WAN side + (dedicated for applications where ports are grouped into WAN- and + LAN-segments). All ports that are not selected belong to the LAN segment. + The LSB bit represents port 0, the higher bits represent the higher + port numbers. */ + u32 nWAN_Ports; } GSW_CPU_PortExtendCfg_t; /** \brief Ethernet port link, speed status and flow control status. Used by \ref GSW_PORT_LINK_CFG_GET and \ref GSW_PORT_LINK_CFG_SET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Force Port Duplex Mode. - - - 0: Negotiate Duplex Mode. Auto-negotiation mode. Negotiated - duplex mode given in 'eDuplex' - during GSW_PORT_LINK_CFG_GET calls. - - 1: Force Duplex Mode. Force duplex mode in 'eDuplex'. - */ - ltq_bool_t bDuplexForce; - /** Port Duplex Status. */ - GSW_portDuplex_t eDuplex; - /** Force Link Speed. - - - 0: Negotiate Link Speed. Negotiated speed given in - 'eSpeed' during GSW_PORT_LINK_CFG_GET calls. - - 1: Force Link Speed. Forced speed mode in 'eSpeed'. - */ - ltq_bool_t bSpeedForce; - /** Ethernet port link up/down and speed status. */ - GSW_portSpeed_t eSpeed; - /** Force Link. - - - 0: Auto-negotiate Link. Current link status is given in - 'eLink' during GSW_PORT_LINK_CFG_GET calls. - - 1: Force Duplex Mode. Force duplex mode in 'eLink'. - */ - ltq_bool_t bLinkForce; - /** Link Status. Read out the current link status. - Note that the link could be forced by setting 'bLinkForce'. */ - GSW_portLink_t eLink; - /** Selected interface mode (MII/RMII/RGMII/GMII/XGMII). */ - GSW_MII_Mode_t eMII_Mode; - /** Select MAC or PHY mode (PHY = Reverse xMII). */ - GSW_MII_Type_t eMII_Type; - /** Interface Clock mode (used for RMII mode). */ - GSW_clkMode_t eClkMode; - /** 'Low Power Idle' Support for 'Energy Efficient Ethernet'. - Only enable this feature in case the attached PHY also supports it. */ - ltq_bool_t bLPI; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Force Port Duplex Mode. + + - 0: Negotiate Duplex Mode. Auto-negotiation mode. Negotiated + duplex mode given in 'eDuplex' + during GSW_PORT_LINK_CFG_GET calls. + - 1: Force Duplex Mode. Force duplex mode in 'eDuplex'. + */ + ltq_bool_t bDuplexForce; + /** Port Duplex Status. */ + GSW_portDuplex_t eDuplex; + /** Force Link Speed. + + - 0: Negotiate Link Speed. Negotiated speed given in + 'eSpeed' during GSW_PORT_LINK_CFG_GET calls. + - 1: Force Link Speed. Forced speed mode in 'eSpeed'. + */ + ltq_bool_t bSpeedForce; + /** Ethernet port link up/down and speed status. */ + GSW_portSpeed_t eSpeed; + /** Force Link. + + - 0: Auto-negotiate Link. Current link status is given in + 'eLink' during GSW_PORT_LINK_CFG_GET calls. + - 1: Force Duplex Mode. Force duplex mode in 'eLink'. + */ + ltq_bool_t bLinkForce; + /** Link Status. Read out the current link status. + Note that the link could be forced by setting 'bLinkForce'. */ + GSW_portLink_t eLink; + /** Selected interface mode (MII/RMII/RGMII/GMII/XGMII). */ + GSW_MII_Mode_t eMII_Mode; + /** Select MAC or PHY mode (PHY = Reverse xMII). */ + GSW_MII_Type_t eMII_Type; + /** Interface Clock mode (used for RMII mode). */ + GSW_clkMode_t eClkMode; + /** 'Low Power Idle' Support for 'Energy Efficient Ethernet'. + Only enable this feature in case the attached PHY also supports it. */ + ltq_bool_t bLPI; } GSW_portLinkCfg_t; /** \brief Ethernet Interface RGMII Clock Configuration. Only needed in case the interface runs in RGMII mode. Used by \ref GSW_PORT_RGMII_CLK_CFG_SET and \ref GSW_PORT_RGMII_CLK_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Clock Delay RX [multiple of 500 ps]. */ - u8 nDelayRx; - /** Clock Delay TX [multiple of 500 ps]. */ - u8 nDelayTx; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Clock Delay RX [multiple of 500 ps]. */ + u8 nDelayRx; + /** Clock Delay TX [multiple of 500 ps]. */ + u8 nDelayTx; } GSW_portRGMII_ClkCfg_t; /** \brief Query whether the Ethernet switch hardware has detected a connected PHY on the port. Used by \ref GSW_PORT_PHY_QUERY. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Check if the Ethernet switch hardware has detected a connected PHY - on this port. */ - ltq_bool_t bPHY_Present; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Check if the Ethernet switch hardware has detected a connected PHY + on this port. */ + ltq_bool_t bPHY_Present; } GSW_portPHY_Query_t; /** \brief Ethernet PHY address definition. Defines the relationship between a bridge port and the MDIO address of a PHY that is attached to this port. Used by \ref GSW_PORT_PHY_ADDR_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Device address on the MDIO interface */ - u8 nAddressDev; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Device address on the MDIO interface */ + u8 nAddressDev; } GSW_portPHY_Addr_t; /** \brief Port redirection control. Used by \ref GSW_PORT_REDIRECT_GET and \ref GSW_PORT_REDIRECT_SET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Port Redirect Option. - If enabled, all packets destined to 'nPortId' are redirected to the - CPU port. The destination port map in the status header information is - not changed so that the original destination port can be identified by - software. */ - ltq_bool_t bRedirectEgress; - /** Port Ingress Direct Forwarding. - If enabled, all packets sourced from 'nPortId' are directly forwarded to queue 0 - of the CPU port. These packets are not modified and are not affected by - normal learning, look up, VLAN processing and queue selection. */ - ltq_bool_t bRedirectIngress; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Port Redirect Option. + If enabled, all packets destined to 'nPortId' are redirected to the + CPU port. The destination port map in the status header information is + not changed so that the original destination port can be identified by + software. */ + ltq_bool_t bRedirectEgress; + /** Port Ingress Direct Forwarding. + If enabled, all packets sourced from 'nPortId' are directly forwarded to queue 0 + of the CPU port. These packets are not modified and are not affected by + normal learning, look up, VLAN processing and queue selection. */ + ltq_bool_t bRedirectIngress; } GSW_portRedirectCfg_t; /** \brief Port monitor configuration. Used by \ref GSW_MONITOR_PORT_CFG_GET and \ref GSW_MONITOR_PORT_CFG_SET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** This port is used as a monitor port. To use this feature, the port - mirror function is enabled on one or more ports. */ - ltq_bool_t bMonitorPort; - /* Monitoring Sub-IF id */ - u16 nSubIfId; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** This port is used as a monitor port. To use this feature, the port + mirror function is enabled on one or more ports. */ + ltq_bool_t bMonitorPort; + /* Monitoring Sub-IF id */ + u16 nSubIfId; } GSW_monitorPortCfg_t; /** \brief MDIO Interface Configuration. Used by \ref GSW_MDIO_CFG_GET and \ref GSW_MDIO_CFG_SET. */ -typedef struct -{ - /** MDIO interface clock and data rate [in kHz]. */ - u32 nMDIO_Speed; - /** MDIO interface enable. */ - ltq_bool_t bMDIO_Enable; +typedef struct { + /** MDIO interface clock and data rate [in kHz]. */ + u32 nMDIO_Speed; + /** MDIO interface enable. */ + ltq_bool_t bMDIO_Enable; } GSW_MDIO_cfg_t; /** \brief MDIO Register Access. @@ -2475,20 +2389,18 @@ typedef struct Some PHY device registers have standard bit definitions as stated in IEEE 802. Used by \ref GSW_MDIO_DATA_READ and \ref GSW_MDIO_DATA_WRITE. */ -typedef struct -{ - /** Device address on the MDIO interface */ - u8 nAddressDev; - /** Register address inside the device. */ - u8 nAddressReg; - /** Exchange data word with the device (read / write). */ - u16 nData; +typedef struct { + /** Device address on the MDIO interface */ + u8 nAddressDev; + /** Register address inside the device. */ + u8 nAddressReg; + /** Exchange data word with the device (read / write). */ + u16 nData; } GSW_MDIO_data_t; /** \brief MAC Cli struct. MAC Cli struct for passing args and argument values. */ -typedef struct -{ +typedef struct { /** Number of args */ u32 argc; /** Argument values */ @@ -2500,72 +2412,68 @@ typedef struct device registers have standard bit definitions as stated in IEEE 802. Used by \ref GSW_MMD_DATA_READ and \ref GSW_MMD_DATA_WRITE. */ -typedef struct -{ - /** Device address on the MDIO interface */ - u8 nAddressDev; - /** MMD Register address/offset inside the device. */ - u32 nAddressReg; - /** Exchange data word with the device (read / write). */ - u16 nData; +typedef struct { + /** Device address on the MDIO interface */ + u8 nAddressDev; + /** MMD Register address/offset inside the device. */ + u32 nAddressReg; + /** Exchange data word with the device (read / write). */ + u16 nData; } GSW_MMD_data_t; /** \brief Enumeration for function status return. The upper four bits are reserved for error classification */ -typedef enum -{ - /** Correct or Expected Status */ - GSW_statusOk = 0, - /** Invalid function parameter */ - GSW_statusParam = -2, - /** No space left in VLAN table */ - GSW_statusVLAN_Space = -3, - /** Requested VLAN ID not found in table */ - GSW_statusVLAN_ID = -4, - /** Invalid ioctl */ - GSW_statusInvalIoctl = -5, - /** Operation not supported by hardware */ - GSW_statusNoSupport = -6, - /** Timeout */ - GSW_statusTimeout = -7, - /** At least one value is out of range */ - GSW_statusValueRange = -8, - /** The PortId/QueueId/MeterId/etc. is not available in this hardware or the - selected feature is not available on this port */ - GSW_statusPortInvalid = -9, - /** The interrupt is not available in this hardware */ - GSW_statusIRQ_Invalid = -10, - /** The MAC table is full, an entry could not be added */ - GSW_statusMAC_TableFull = -11, - /** Locking failed - SWAPI is busy */ - GSW_statusLock_Failed = -12, - /** Generic or unknown error occurred */ - GSW_statusErr = -1 +typedef enum { + /** Correct or Expected Status */ + GSW_statusOk = 0, + /** Invalid function parameter */ + GSW_statusParam = -2, + /** No space left in VLAN table */ + GSW_statusVLAN_Space = -3, + /** Requested VLAN ID not found in table */ + GSW_statusVLAN_ID = -4, + /** Invalid ioctl */ + GSW_statusInvalIoctl = -5, + /** Operation not supported by hardware */ + GSW_statusNoSupport = -6, + /** Timeout */ + GSW_statusTimeout = -7, + /** At least one value is out of range */ + GSW_statusValueRange = -8, + /** The PortId/QueueId/MeterId/etc. is not available in this hardware or the + selected feature is not available on this port */ + GSW_statusPortInvalid = -9, + /** The interrupt is not available in this hardware */ + GSW_statusIRQ_Invalid = -10, + /** The MAC table is full, an entry could not be added */ + GSW_statusMAC_TableFull = -11, + /** Locking failed - SWAPI is busy */ + GSW_statusLock_Failed = -12, + /** Generic or unknown error occurred */ + GSW_statusErr = -1 } GSW_return_t; /** \brief Configures the Wake-on-LAN function. Used by \ref GSW_WOL_CFG_SET and \ref GSW_WOL_CFG_GET. */ -typedef struct -{ - /** WoL MAC address. */ - u8 nWolMAC[GSW_MAC_ADDR_LEN]; - /** WoL password. */ - u8 nWolPassword[GSW_MAC_ADDR_LEN]; - /** WoL password enable. */ - ltq_bool_t bWolPasswordEnable; +typedef struct { + /** WoL MAC address. */ + u8 nWolMAC[GSW_MAC_ADDR_LEN]; + /** WoL password. */ + u8 nWolPassword[GSW_MAC_ADDR_LEN]; + /** WoL password enable. */ + ltq_bool_t bWolPasswordEnable; } GSW_WoL_Cfg_t; /** \brief Enables Wake-on-LAN functionality on the port. Used by \ref GSW_WOL_PORT_CFG_SET and \ref GSW_WOL_PORT_CFG_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u16 nPortId; - /** Enable Wake-on-LAN. */ - ltq_bool_t bWakeOnLAN_Enable; - /** Ignore address check */ - ltq_bool_t bIgnoreAdrCheck; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u16 nPortId; + /** Enable Wake-on-LAN. */ + ltq_bool_t bWakeOnLAN_Enable; + /** Ignore address check */ + ltq_bool_t bIgnoreAdrCheck; } GSW_WoL_PortCfg_t; /*@}*/ /* GSW_IOCTL_OAM */ @@ -2576,339 +2484,340 @@ typedef struct /** \brief RMON Counters Type enumeration. Used by \ref GSW_RMON_clear_t and \ref GSW_RMON_mode_t. */ -typedef enum -{ - /** All RMON Types Counters */ - GSW_RMON_ALL_TYPE = 0, - /** All PMAC RMON Counters */ - GSW_RMON_PMAC_TYPE = 1, - /** Port based RMON Counters */ - GSW_RMON_PORT_TYPE = 2, - /** Meter based RMON Counters */ - GSW_RMON_METER_TYPE = 3, - /** Interface based RMON Counters */ - GSW_RMON_IF_TYPE = 4, - /** Route based RMON Counters */ - GSW_RMON_ROUTE_TYPE = 5, - /** Redirected Traffic based RMON Counters */ - GSW_RMON_REDIRECT_TYPE = 6, - /** Bridge Port based RMON Counters */ - GSW_RMON_BRIDGE_TYPE = 7, - /** CTP Port based RMON Counters */ - GSW_RMON_CTP_TYPE = 8, +typedef enum { + /** All RMON Types Counters */ + GSW_RMON_ALL_TYPE = 0, + /** All PMAC RMON Counters */ + GSW_RMON_PMAC_TYPE = 1, + /** Port based RMON Counters */ + GSW_RMON_PORT_TYPE = 2, + /** Meter based RMON Counters */ + GSW_RMON_METER_TYPE = 3, + /** Interface based RMON Counters */ + GSW_RMON_IF_TYPE = 4, + /** Route based RMON Counters */ + GSW_RMON_ROUTE_TYPE = 5, + /** Redirected Traffic based RMON Counters */ + GSW_RMON_REDIRECT_TYPE = 6, + /** Bridge Port based RMON Counters */ + GSW_RMON_BRIDGE_TYPE = 7, + /** CTP Port based RMON Counters */ + GSW_RMON_CTP_TYPE = 8, } GSW_RMON_type_t; /** \brief RMON Counters Data Structure for clearance of values. Used by \ref GSW_RMON_CLEAR. */ -typedef struct -{ - /** RMON Counters Type */ - GSW_RMON_type_t eRmonType; - /** RMON Counters Identifier - Meter, Port, If, Route, etc. */ - u8 nRmonId; +typedef struct { + /** RMON Counters Type */ + GSW_RMON_type_t eRmonType; + /** RMON Counters Identifier - Meter, Port, If, Route, etc. */ + u8 nRmonId; } GSW_RMON_clear_t; /**Defined as per RMON counter table structure Applicable only for GSWIP 3.1*/ -typedef enum -{ - GSW_RMON_CTP_PORT_RX = 0, - GSW_RMON_CTP_PORT_TX = 1, - GSW_RMON_BRIDGE_PORT_RX = 2, - GSW_RMON_BRIDGE_PORT_TX = 3, - GSW_RMON_CTP_PORT_PCE_BYPASS = 4, - GSW_RMON_TFLOW_RX = 5, - GSW_RMON_TFLOW_TX = 6, - GSW_RMON_QMAP = 0x0E, - GSW_RMON_METER = 0x19, - GSW_RMON_PMAC = 0x1C, +typedef enum { + GSW_RMON_CTP_PORT_RX = 0, + GSW_RMON_CTP_PORT_TX = 1, + GSW_RMON_BRIDGE_PORT_RX = 2, + GSW_RMON_BRIDGE_PORT_TX = 3, + GSW_RMON_CTP_PORT_PCE_BYPASS = 4, + GSW_RMON_TFLOW_RX = 5, + GSW_RMON_TFLOW_TX = 6, + GSW_RMON_QMAP = 0x0E, + GSW_RMON_METER = 0x19, + GSW_RMON_PMAC = 0x1C, } GSW_RMON_portType_t; /* TFLOW counter mode type */ -typedef enum -{ +typedef enum { /* Global mode */ - GSW_TFLOW_CMODE_GLOBAL = 0, - /* Logical mode */ - GSW_TFLOW_CMODE_LOGICAL = 1, - /* CTP port mode */ - GSW_TFLOW_CMODE_CTP = 2, + GSW_TFLOW_CMODE_GLOBAL = 0, + /* Logical mode */ + GSW_TFLOW_CMODE_LOGICAL = 1, + /* CTP port mode */ + GSW_TFLOW_CMODE_CTP = 2, /* Bridge port mode */ - GSW_TFLOW_CMODE_BRIDGE = 3, + GSW_TFLOW_CMODE_BRIDGE = 3, } GSW_TflowCmodeType_t; /* TFLOW counter type */ -typedef enum -{ +typedef enum { /* Set all Rx/Tx/PCE-Bp-Tx registers to same value */ - GSW_TFLOW_COUNTER_ALL = 0, //Default for 'set' function. - /* SEt PCE Rx register config only */ - GSW_TFLOW_COUNTER_PCE_Rx = 1, //Default for 'get' function. - /* SEt PCE Tx register config only */ - GSW_TFLOW_COUNTER_PCE_Tx = 2, - /* SEt PCE-Bypass Tx register config only */ - GSW_TFLOW_COUNTER_PCE_BP_Tx = 3, + GSW_TFLOW_COUNTER_ALL = 0, //Default for 'set' function. + /* SEt PCE Rx register config only */ + GSW_TFLOW_COUNTER_PCE_Rx = 1, //Default for 'get' function. + /* SEt PCE Tx register config only */ + GSW_TFLOW_COUNTER_PCE_Tx = 2, + /* SEt PCE-Bypass Tx register config only */ + GSW_TFLOW_COUNTER_PCE_BP_Tx = 3, } GSW_TflowCountConfType_t; /* TFLOW CTP counter LSB bits */ -typedef enum -{ +typedef enum { /* Num of valid bits */ - GSW_TCM_CTP_VAL_BITS_0 = 0, + GSW_TCM_CTP_VAL_BITS_0 = 0, GSW_TCM_CTP_VAL_BITS_1 = 1, GSW_TCM_CTP_VAL_BITS_2 = 2, GSW_TCM_CTP_VAL_BITS_3 = 3, GSW_TCM_CTP_VAL_BITS_4 = 4, GSW_TCM_CTP_VAL_BITS_5 = 5, - GSW_TCM_CTP_VAL_BITS_6 = 6, + GSW_TCM_CTP_VAL_BITS_6 = 6, } GSW_TflowCtpValBits_t; - + /* TFLOW bridge port counter LSB bits */ -typedef enum -{ +typedef enum { /* Num of valid bits */ GSW_TCM_BRP_VAL_BITS_2 = 2, GSW_TCM_BRP_VAL_BITS_3 = 3, GSW_TCM_BRP_VAL_BITS_4 = 4, GSW_TCM_BRP_VAL_BITS_5 = 5, - GSW_TCM_BRP_VAL_BITS_6 = 6, + GSW_TCM_BRP_VAL_BITS_6 = 6, } GSW_TflowBrpValBits_t; /** \brief RMON Counters for individual Port. This structure contains the RMON counters of an Ethernet Switch Port. Used by \ref GSW_RMON_PORT_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. This parameter specifies for which MAC port the RMON - counter is read. It has to be set by the application before - calling \ref GSW_RMON_PORT_GET. */ - u16 nPortId; - /**Table address selection based on port type - Applicable only for GSWIP 3.1 - \ref GSW_RMON_portType_t**/ - GSW_RMON_portType_t ePortType; - /*Applicable only for GSWIP 3.1*/ - ltq_bool_t b64BitMode; - /*Applicable only for GSWIP 3.1*/ - u32 nRxExtendedVlanDiscardPkts; - /*Applicable only for GSWIP 3.1*/ - u32 nMtuExceedDiscardPkts; - /*Applicable only for GSWIP 3.1*/ - u32 nTxUnderSizeGoodPkts; - /*Applicable only for GSWIP 3.1*/ - u32 nTxOversizeGoodPkts; - /** Receive Packet Count (only packets that are accepted and not discarded). */ - u32 nRxGoodPkts; - /** Receive Unicast Packet Count. */ - u32 nRxUnicastPkts; - /** Receive Broadcast Packet Count. */ - u32 nRxBroadcastPkts; - /** Receive Multicast Packet Count. */ - u32 nRxMulticastPkts; - /** Receive FCS Error Packet Count. */ - u32 nRxFCSErrorPkts; - /** Receive Undersize Good Packet Count. */ - u32 nRxUnderSizeGoodPkts; - /** Receive Oversize Good Packet Count. */ - u32 nRxOversizeGoodPkts; - /** Receive Undersize Error Packet Count. */ - u32 nRxUnderSizeErrorPkts; - /** Receive Good Pause Packet Count. */ - u32 nRxGoodPausePkts; - /** Receive Oversize Error Packet Count. */ - u32 nRxOversizeErrorPkts; - /** Receive Align Error Packet Count. */ - u32 nRxAlignErrorPkts; - /** Filtered Packet Count. */ - u32 nRxFilteredPkts; - /** Receive Size 64 Bytes Packet Count. */ - u32 nRx64BytePkts; - /** Receive Size 65-127 Bytes Packet Count. */ - u32 nRx127BytePkts; - /** Receive Size 128-255 Bytes Packet Count. */ - u32 nRx255BytePkts; - /** Receive Size 256-511 Bytes Packet Count. */ - u32 nRx511BytePkts; - /** Receive Size 512-1023 Bytes Packet Count. */ - u32 nRx1023BytePkts; - /** Receive Size 1024-1522 Bytes (or more, if configured) Packet Count. */ - u32 nRxMaxBytePkts; - /** Overall Transmit Good Packets Count. */ - u32 nTxGoodPkts; - /** Transmit Unicast Packet Count. */ - u32 nTxUnicastPkts; - /** Transmit Broadcast Packet Count. */ - u32 nTxBroadcastPkts; - /** Transmit Multicast Packet Count. */ - u32 nTxMulticastPkts; - /** Transmit Single Collision Count. */ - u32 nTxSingleCollCount; - /** Transmit Multiple Collision Count. */ - u32 nTxMultCollCount; - /** Transmit Late Collision Count. */ - u32 nTxLateCollCount; - /** Transmit Excessive Collision Count. */ - u32 nTxExcessCollCount; - /** Transmit Collision Count. */ - u32 nTxCollCount; - /** Transmit Pause Packet Count. */ - u32 nTxPauseCount; - /** Transmit Size 64 Bytes Packet Count. */ - u32 nTx64BytePkts; - /** Transmit Size 65-127 Bytes Packet Count. */ - u32 nTx127BytePkts; - /** Transmit Size 128-255 Bytes Packet Count. */ - u32 nTx255BytePkts; - /** Transmit Size 256-511 Bytes Packet Count. */ - u32 nTx511BytePkts; - /** Transmit Size 512-1023 Bytes Packet Count. */ - u32 nTx1023BytePkts; - /** Transmit Size 1024-1522 Bytes (or more, if configured) Packet Count. */ - u32 nTxMaxBytePkts; - /** Transmit Drop Packet Count. */ - u32 nTxDroppedPkts; - /** Transmit Dropped Packet Count, based on Congestion Management. */ - u32 nTxAcmDroppedPkts; - /** Receive Dropped Packet Count. */ - u32 nRxDroppedPkts; - /** Receive Good Byte Count (64 bit). */ - u64 nRxGoodBytes; - /** Receive Bad Byte Count (64 bit). */ - u64 nRxBadBytes; - /** Transmit Good Byte Count (64 bit). */ - u64 nTxGoodBytes; +typedef struct { + /** Port Type. This gives information which type of port to get RMON. + nPortId should be based on this field. + This is new in GSWIP-3.1. For GSWIP-2.1/2.2/3.0, this field is always + ZERO (GSW_LOGICAL_PORT). */ + GSW_portType_t ePortType; + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. This parameter specifies for which MAC port the RMON + counter is read. It has to be set by the application before + calling \ref GSW_RMON_PORT_GET. */ + u16 nPortId; + /** Sub interface ID group. The valid range is hardware/protocol dependent. + + \remarks + This field is valid when \ref GSW_RMON_Port_cnt_t::ePortType is + \ref GSW_portType_t::GSW_CTP_PORT. + Sub interface ID group is defined for each of \ref GSW_LogicalPortMode_t. + For both \ref GSW_LOGICAL_PORT_8BIT_WLAN and + \ref GSW_LOGICAL_PORT_9BIT_WLAN, this field is VAP. + For \ref GSW_LOGICAL_PORT_GPON, this field is GEM index. + For \ref GSW_LOGICAL_PORT_EPON, this field is stream index. + For \ref GSW_LOGICAL_PORT_GINT, this field is LLID. + For others, this field is 0. */ + u32 nSubIfIdGroup; + /** Separate set of CTP Tx counters when PCE is bypassed. GSWIP-3.1 only.*/ + ltq_bool_t bPceBypass; + /*Applicable only for GSWIP 3.1*/ + /** Discarded at Extended VLAN Operation Packet Count. GSWIP-3.1 only. */ + u32 nRxExtendedVlanDiscardPkts; + /** Discarded MTU Exceeded Packet Count. GSWIP-3.1 only. */ + u32 nMtuExceedDiscardPkts; + /** Tx Undersize (<64) Packet Count. GSWIP-3.1 only. */ + u32 nTxUnderSizeGoodPkts; + /** Tx Oversize (>1518) Packet Count. GSWIP-3.1 only. */ + u32 nTxOversizeGoodPkts; + /** Receive Packet Count (only packets that are accepted and not discarded). */ + u32 nRxGoodPkts; + /** Receive Unicast Packet Count. */ + u32 nRxUnicastPkts; + /** Receive Broadcast Packet Count. */ + u32 nRxBroadcastPkts; + /** Receive Multicast Packet Count. */ + u32 nRxMulticastPkts; + /** Receive FCS Error Packet Count. */ + u32 nRxFCSErrorPkts; + /** Receive Undersize Good Packet Count. */ + u32 nRxUnderSizeGoodPkts; + /** Receive Oversize Good Packet Count. */ + u32 nRxOversizeGoodPkts; + /** Receive Undersize Error Packet Count. */ + u32 nRxUnderSizeErrorPkts; + /** Receive Good Pause Packet Count. */ + u32 nRxGoodPausePkts; + /** Receive Oversize Error Packet Count. */ + u32 nRxOversizeErrorPkts; + /** Receive Align Error Packet Count. */ + u32 nRxAlignErrorPkts; + /** Filtered Packet Count. */ + u32 nRxFilteredPkts; + /** Receive Size 64 Bytes Packet Count. */ + u32 nRx64BytePkts; + /** Receive Size 65-127 Bytes Packet Count. */ + u32 nRx127BytePkts; + /** Receive Size 128-255 Bytes Packet Count. */ + u32 nRx255BytePkts; + /** Receive Size 256-511 Bytes Packet Count. */ + u32 nRx511BytePkts; + /** Receive Size 512-1023 Bytes Packet Count. */ + u32 nRx1023BytePkts; + /** Receive Size 1024-1522 Bytes (or more, if configured) Packet Count. */ + u32 nRxMaxBytePkts; + /** Overall Transmit Good Packets Count. */ + u32 nTxGoodPkts; + /** Transmit Unicast Packet Count. */ + u32 nTxUnicastPkts; + /** Transmit Broadcast Packet Count. */ + u32 nTxBroadcastPkts; + /** Transmit Multicast Packet Count. */ + u32 nTxMulticastPkts; + /** Transmit Single Collision Count. */ + u32 nTxSingleCollCount; + /** Transmit Multiple Collision Count. */ + u32 nTxMultCollCount; + /** Transmit Late Collision Count. */ + u32 nTxLateCollCount; + /** Transmit Excessive Collision Count. */ + u32 nTxExcessCollCount; + /** Transmit Collision Count. */ + u32 nTxCollCount; + /** Transmit Pause Packet Count. */ + u32 nTxPauseCount; + /** Transmit Size 64 Bytes Packet Count. */ + u32 nTx64BytePkts; + /** Transmit Size 65-127 Bytes Packet Count. */ + u32 nTx127BytePkts; + /** Transmit Size 128-255 Bytes Packet Count. */ + u32 nTx255BytePkts; + /** Transmit Size 256-511 Bytes Packet Count. */ + u32 nTx511BytePkts; + /** Transmit Size 512-1023 Bytes Packet Count. */ + u32 nTx1023BytePkts; + /** Transmit Size 1024-1522 Bytes (or more, if configured) Packet Count. */ + u32 nTxMaxBytePkts; + /** Transmit Drop Packet Count. */ + u32 nTxDroppedPkts; + /** Transmit Dropped Packet Count, based on Congestion Management. */ + u32 nTxAcmDroppedPkts; + /** Receive Dropped Packet Count. */ + u32 nRxDroppedPkts; + /** Receive Good Byte Count (64 bit). */ + u64 nRxGoodBytes; + /** Receive Bad Byte Count (64 bit). */ + u64 nRxBadBytes; + /** Transmit Good Byte Count (64 bit). */ + u64 nTxGoodBytes; } GSW_RMON_Port_cnt_t; /** \brief RMON Counters Mode Enumeration. This enumeration defines Counters mode - Packets based or Bytes based counting. Metering and Routing Sessions RMON counting support either Byte based or packets based only. */ -typedef enum -{ - /** Packet based RMON Counters */ - GSW_RMON_COUNT_PKTS = 0, - /** Bytes based RMON Counters */ - GSW_RMON_COUNT_BYTES = 1, - /** number of dropped frames, supported only for interface cunters */ - GSW_RMON_DROP_COUNT = 2, +typedef enum { + /** Packet based RMON Counters */ + GSW_RMON_COUNT_PKTS = 0, + /** Bytes based RMON Counters */ + GSW_RMON_COUNT_BYTES = 1, + /** number of dropped frames, supported only for interface cunters */ + GSW_RMON_DROP_COUNT = 2, } GSW_RMON_CountMode_t; /** \brief RMON Counters Mode for different Elements. This structure takes RMON Counter Element Name and mode config */ -typedef struct -{ - /** RMON Counters Type */ - GSW_RMON_type_t eRmonType; - /** RMON Counters Mode */ - GSW_RMON_CountMode_t eCountMode; +typedef struct { + /** RMON Counters Type */ + GSW_RMON_type_t eRmonType; + /** RMON Counters Mode */ + GSW_RMON_CountMode_t eCountMode; } GSW_RMON_mode_t; /** \brief RMON Counters for Meter - Type (GSWIP-3.0 only). This structure contains the RMON counters of one Meter Instance. Used by \ref GSW_RMON_METER_GET. */ -typedef struct -{ - /** Meter Instance number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected meter is not - available. This parameter specifies for which Meter Id the RMON-1 - counter is read. It has to be set by the application before - calling \ref GSW_RMON_METER_GET. */ - u8 nMeterId; - /** Metered Green colored packets or bytes (depending upon mode) count. */ - u32 nGreenCount; - /** Metered Yellow colored packets or bytes (depending upon mode) count. */ - u32 nYellowCount; - /** Metered Red colored packets or bytes (depending upon mode) count. */ - u32 nRedCount; - /** Metered Reserved (Future Use) packets or bytes (depending upon mode) count. */ - u32 nResCount; +typedef struct { + /** Meter Instance number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected meter is not + available. This parameter specifies for which Meter Id the RMON-1 + counter is read. It has to be set by the application before + calling \ref GSW_RMON_METER_GET. */ + u8 nMeterId; + /** Metered Green colored packets or bytes (depending upon mode) count. */ + u32 nGreenCount; + /** Metered Yellow colored packets or bytes (depending upon mode) count. */ + u32 nYellowCount; + /** Metered Red colored packets or bytes (depending upon mode) count. */ + u32 nRedCount; + /** Metered Reserved (Future Use) packets or bytes (depending upon mode) count. */ + u32 nResCount; } GSW_RMON_Meter_cnt_t; /** \brief RMON Redirected Counters for (GSWIP-3.0 only). This structure contains the RMON counters of all Redirected packets. Used by \ref GSW_RMON_REDIRECT_GET. */ -typedef struct -{ - /** Received Total Packets count. */ - u32 nRxPktsCount; - /** Received Discarded Packets count. */ - u32 nRxDiscPktsCount; - /** Received Bytes count excluding discards. */ - u64 nRxBytesCount; - /** Transmitted Total Packets count. */ - u32 nTxPktsCount; - /** Egress Queue Discarded Packets count. */ - u32 nTxDiscPktsCount; - /** Transmitted Bytes count excluding discards. */ - u64 nTxBytesCount; +typedef struct { + /** Received Total Packets count. */ + u32 nRxPktsCount; + /** Received Discarded Packets count. */ + u32 nRxDiscPktsCount; + /** Received Bytes count excluding discards. */ + u64 nRxBytesCount; + /** Transmitted Total Packets count. */ + u32 nTxPktsCount; + /** Egress Queue Discarded Packets count. */ + u32 nTxDiscPktsCount; + /** Transmitted Bytes count excluding discards. */ + u64 nTxBytesCount; } GSW_RMON_Redirect_cnt_t; /** \brief RMON Interface Counters for (GSWIP-3.0 only). This structure contains the RMON counters of Interface Instance. Used by \ref GSW_RMON_IF_GET. */ -typedef struct -{ - /** Interface Counter Index Number. (Range : 0-255) - It has to be reserved for ports by the application before - calling \ref GSW_RMON_IF_GET. */ - u8 nIfId; - /** Counters Mode - Global level current settings. */ - GSW_RMON_CountMode_t countMode; - /** Received Total Packets count. */ - u32 nRxPktsCount; - /** Received Discarded Packets count */ - u32 nRxDiscPktsCount; - /** Received Bytes count - When this is used, Discarded Count is not available*/ - u32 nRxBytesCount; - /** Transmitted Total Packets count. */ - u32 nTxPktsCount; - /** Egress Discarded Packets count. */ - u32 nTxDiscPktsCount; - /** Transmitted Bytes count - When this is used, Discarded Count is not available */ - u32 nTxBytesCount; +typedef struct { + /** Interface Counter Index Number. (Range : 0-255) + It has to be reserved for ports by the application before + calling \ref GSW_RMON_IF_GET. */ + u8 nIfId; + /** Counters Mode - Global level current settings. */ + GSW_RMON_CountMode_t countMode; + /** Received Total Packets count. */ + u32 nRxPktsCount; + /** Received Discarded Packets count */ + u32 nRxDiscPktsCount; + /** Received Bytes count - When this is used, Discarded Count is not available*/ + u32 nRxBytesCount; + /** Transmitted Total Packets count. */ + u32 nTxPktsCount; + /** Egress Discarded Packets count. */ + u32 nTxDiscPktsCount; + /** Transmitted Bytes count - When this is used, Discarded Count is not available */ + u32 nTxBytesCount; } GSW_RMON_If_cnt_t; /** \brief RMON Routing Counters for (GSWIP-3.0 only). This structure contains the RMON counters of Routing Port number. Used by \ref GSW_RMON_ROUTE_GET. */ -typedef struct -{ - /** Routed Port Number. */ - u8 nRoutedPortId; - /** Fast Path unicast IPv4 Total UDP Packets Received Count. */ - u32 nRxUCv4UDPPktsCount; - /** Fast Path unicast IPv4 Total TCP Packets Received Count. */ - u32 nRxUCv4TCPPktsCount; - /** Fast Path unicast IPv6 Total UDP Packets Received Count. */ - u32 nRxUCv6UDPPktsCount; - /** Fast Path unicast IPv6 Total TCP Packets Received Count. */ - u32 nRxUCv6TCPPktsCount; - /** Fast Path multicast IPv4 packets Received Count. */ - u32 nRxMCv4PktsCount; - /** Fast Path multicast IPv6 packets Received Count. */ - u32 nRxMCv6PktsCount; - /** CPU Path Received Total Packets Count. */ - u32 nRxCpuPktsCount; - /** Fast Path Dropped Total Packets Count. */ - u32 nRxPktsDropCount; - /** Fast Path IPv4 Traffic Total Bytes Received Count */ - u32 nRxIPv4BytesCount; - /** Fast Path IPv6 Traffic Total Bytes Received Count */ - u32 nRxIPv6BytesCount; - /** CPU Path Traffic Total Bytes Received Count */ - u32 nRxCpuBytesCount; - /** Fast Path Traffic Total Bytes Dropped Count */ - u32 nRxBytesDropCount; - /** Fast Path Traffic Total Packets Transmitted Count */ - u32 nTxPktsCount; - /** Fast Path Traffic Total Bytes Transmitted Count */ - u32 nTxBytesCount; +typedef struct { + /** Routed Port Number. */ + u8 nRoutedPortId; + /** Fast Path unicast IPv4 Total UDP Packets Received Count. */ + u32 nRxUCv4UDPPktsCount; + /** Fast Path unicast IPv4 Total TCP Packets Received Count. */ + u32 nRxUCv4TCPPktsCount; + /** Fast Path unicast IPv6 Total UDP Packets Received Count. */ + u32 nRxUCv6UDPPktsCount; + /** Fast Path unicast IPv6 Total TCP Packets Received Count. */ + u32 nRxUCv6TCPPktsCount; + /** Fast Path multicast IPv4 packets Received Count. */ + u32 nRxMCv4PktsCount; + /** Fast Path multicast IPv6 packets Received Count. */ + u32 nRxMCv6PktsCount; + /** CPU Path Received Total Packets Count. */ + u32 nRxCpuPktsCount; + /** Fast Path Dropped Total Packets Count. */ + u32 nRxPktsDropCount; + /** Fast Path IPv4 Traffic Total Bytes Received Count */ + u32 nRxIPv4BytesCount; + /** Fast Path IPv6 Traffic Total Bytes Received Count */ + u32 nRxIPv6BytesCount; + /** CPU Path Traffic Total Bytes Received Count */ + u32 nRxCpuBytesCount; + /** Fast Path Traffic Total Bytes Dropped Count */ + u32 nRxBytesDropCount; + /** Fast Path Traffic Total Packets Transmitted Count */ + u32 nTxPktsCount; + /** Fast Path Traffic Total Bytes Transmitted Count */ + u32 nTxBytesCount; } GSW_RMON_Route_cnt_t; /*@}*/ /* GSW_IOCTL_RMON */ @@ -2917,89 +2826,87 @@ typedef struct /*@{*/ /** \brief Configure the Backpressure mapping for egress Queues Congestion or ingress (receiving) ports to DMA channel. Used by \ref GSW_PMAC_BM_CFG_SET and \ref GSW_PMAC_BM_CFG_GET. */ -typedef struct -{ - /** PMAC Interface ID */ - u8 nPmacId; - /** Tx DMA Channel Identifier which receives sideband backpressure signal (0..15) */ - u8 nTxDmaChanId; - /** Transmit Queues Selection Mask which will generate backpressure - (Configurable upto 32 Egress Queues) */ - u32 txQMask; - /** Receive (Ingress) ports selection congestion Mask which will generate backpressure - (Configurable upto 16 ports) */ - u32 rxPortMask; +typedef struct { + /** PMAC Interface ID */ + u8 nPmacId; + /** Tx DMA Channel Identifier which receives sideband backpressure signal (0..15) */ + u8 nTxDmaChanId; + /** Transmit Queues Selection Mask which will generate backpressure - (Configurable upto 32 Egress Queues) */ + u32 txQMask; + /** Receive (Ingress) ports selection congestion Mask which will generate backpressure - (Configurable upto 16 ports) */ + u32 rxPortMask; } GSW_PMAC_BM_Cfg_t; /** \brief Short Length Received Frame Check Type for PMAC. Used by PMAC structure \ref GSW_PMAC_Glbl_Cfg_t. */ -typedef enum -{ - /** Short frame length check is disabled. */ - GSW_PMAC_SHORT_LEN_DIS = 0, - /** Short frame length check is enabled without considering VLAN Tags. */ - GSW_PMAC_SHORT_LEN_ENA_UNTAG = 1, - /** Short frame length check is enabled including VLAN Tags. */ - GSW_PMAC_SHORT_LEN_ENA_TAG = 2, - /** Reserved - Currently unused */ - GSW_PMAC_SHORT_LEN_RESERVED = 3 +typedef enum { + /** Short frame length check is disabled. */ + GSW_PMAC_SHORT_LEN_DIS = 0, + /** Short frame length check is enabled without considering VLAN Tags. */ + GSW_PMAC_SHORT_LEN_ENA_UNTAG = 1, + /** Short frame length check is enabled including VLAN Tags. */ + GSW_PMAC_SHORT_LEN_ENA_TAG = 2, + /** Reserved - Currently unused */ + GSW_PMAC_SHORT_LEN_RESERVED = 3 } GSW_PMAC_Short_Frame_Chk_t; /** \brief Egress PMAC Config Table Selector */ -typedef enum -{ - /** Use value of \ref GSW_PMAC_Glbl_Cfg_t::bProcFlagsEgCfgEna */ - GSW_PMAC_PROC_FLAGS_NONE = 0, - /** Use traffic class for egress config table addressing */ - GSW_PMAC_PROC_FLAGS_TC = 1, - /** Use flags (MPE1, MPE2, DEC, ENC) for egress config table addressing */ - GSW_PMAC_PROC_FLAGS_FLAG = 2, - /** Use reduced traffic class (saturated to 3) and flags (MPE1, MPE2) for - egress config table addressing */ - GSW_PMAC_PROC_FLAGS_MIX = 3 +typedef enum { + /** Use value of \ref GSW_PMAC_Glbl_Cfg_t::bProcFlagsEgCfgEna */ + GSW_PMAC_PROC_FLAGS_NONE = 0, + /** Use traffic class for egress config table addressing */ + GSW_PMAC_PROC_FLAGS_TC = 1, + /** Use flags (MPE1, MPE2, DEC, ENC) for egress config table addressing */ + GSW_PMAC_PROC_FLAGS_FLAG = 2, + /** Use reduced traffic class (saturated to 3) and flags (MPE1, MPE2) for + egress config table addressing */ + GSW_PMAC_PROC_FLAGS_MIX = 3 } GSW_PMAC_Proc_Flags_Eg_Cfg_t; /** \brief Configure the global settings of PMAC for GSWIP-3.x. This includes settings such as Jumbo frame, Checksum handling, Padding and Engress PMAC Selector Config. Used by \ref GSW_PMAC_GLBL_CFG_SET and \ref GSW_PMAC_GLBL_CFG_GET. */ -typedef struct -{ - /** PMAC Interface Id */ - u8 nPmacId; - /** Global Padding Settings - Disabled (Default), to enable set it true. */ - ltq_bool_t bPadEna; - /** VLAN Padding Setting - Disabled (Default), to enable set it true - applicable when bPadEna is set. */ - ltq_bool_t bVPadEna; - /** Stacked VLAN Padding Setting - Disabled (Default), to enable set it true - applicable when bPadEna is set. */ - ltq_bool_t bSVPadEna; - /** Packet carry FCS after PMAC process - Enabled (Default), to disable set it true. - For GSWIP-3.1 only. */ - ltq_bool_t bRxFCSDis; - /** Transmit FCS Regeneration Setting - Enabled (Default), to disable set it true. */ - ltq_bool_t bTxFCSDis; - /** IP and Transport (TCP/UDP) Headers Checksum Generation Control - Enabled (Default), to disable set it true. */ - ltq_bool_t bIPTransChkRegDis; - /** IP and Transport (TCP/UDP) Headers Checksum Verification Control - Enabled (Default), to disable set it true. */ - ltq_bool_t bIPTransChkVerDis; - /** To enable receipt of Jumbo frames - Disabled (Default - 1518 bytes normal frames without VLAN tags), to enable Jumbo set it true. */ - ltq_bool_t bJumboEna; - /** Maximum length of Jumbo frames in terms of bytes (Bits 13:0). The maximum handled in Switch is 9990 bytes. */ - u16 nMaxJumboLen; - /** Threshold length for Jumbo frames qualification in terms of bytes (Bits 13:0). */ - u16 nJumboThreshLen; - /** Long frame length check - Enabled (Default), to disable set it true. */ - ltq_bool_t bLongFrmChkDis; - /** Short frame length check Type - default (Enabled for 64 bytes without considering VLAN). */ - GSW_PMAC_Short_Frame_Chk_t eShortFrmChkType; - /** GSWIP3.0 specific - Egress PMAC Config Table Selector - TrafficClass or Processing Flags (MPE1, MPE22, DEC, ENC based). - The default setting is Traffic Class based selector for Egress PMAC. */ - ltq_bool_t bProcFlagsEgCfgEna; - /** GSWIP3.1 specific - Egress PMAC Config Table Selector - If this field is not \ref GSW_PMAC_PROC_FLAGS_NONE, it will override - bProcFlagsEgCfgEna. */ - GSW_PMAC_Proc_Flags_Eg_Cfg_t eProcFlagsEgCfg; - /** GSWIP3.1 specific - frame size threshold for buffer selection. - Value in this array should be in ascending order. */ - u32 nBslThreshold[3]; +typedef struct { + /** PMAC Interface Id */ + u8 nPmacId; + /** Automatic Padding Settings - Disabled (Default), to enable set it true. */ + ltq_bool_t bAPadEna; + /** Global Padding Settings - Disabled (Default), to enable set it true. */ + ltq_bool_t bPadEna; + /** VLAN Padding Setting - Disabled (Default), to enable set it true - applicable when bPadEna is set. */ + ltq_bool_t bVPadEna; + /** Stacked VLAN Padding Setting - Disabled (Default), to enable set it true - applicable when bPadEna is set. */ + ltq_bool_t bSVPadEna; + /** Packet carry FCS after PMAC process - Enabled (Default), to disable set it true. + For GSWIP-3.1 only. */ + ltq_bool_t bRxFCSDis; + /** Transmit FCS Regeneration Setting - Enabled (Default), to disable set it true. */ + ltq_bool_t bTxFCSDis; + /** IP and Transport (TCP/UDP) Headers Checksum Generation Control - Enabled (Default), to disable set it true. */ + ltq_bool_t bIPTransChkRegDis; + /** IP and Transport (TCP/UDP) Headers Checksum Verification Control - Enabled (Default), to disable set it true. */ + ltq_bool_t bIPTransChkVerDis; + /** To enable receipt of Jumbo frames - Disabled (Default - 1518 bytes normal frames without VLAN tags), to enable Jumbo set it true. */ + ltq_bool_t bJumboEna; + /** Maximum length of Jumbo frames in terms of bytes (Bits 13:0). The maximum handled in Switch is 9990 bytes. */ + u16 nMaxJumboLen; + /** Threshold length for Jumbo frames qualification in terms of bytes (Bits 13:0). */ + u16 nJumboThreshLen; + /** Long frame length check - Enabled (Default), to disable set it true. */ + ltq_bool_t bLongFrmChkDis; + /** Short frame length check Type - default (Enabled for 64 bytes without considering VLAN). */ + GSW_PMAC_Short_Frame_Chk_t eShortFrmChkType; + /** GSWIP3.0 specific - Egress PMAC Config Table Selector - TrafficClass or Processing Flags (MPE1, MPE22, DEC, ENC based). + The default setting is Traffic Class based selector for Egress PMAC. */ + ltq_bool_t bProcFlagsEgCfgEna; + /** GSWIP3.1 specific - Egress PMAC Config Table Selector + If this field is not \ref GSW_PMAC_PROC_FLAGS_NONE, it will override + bProcFlagsEgCfgEna. */ + GSW_PMAC_Proc_Flags_Eg_Cfg_t eProcFlagsEgCfg; + /** GSWIP3.1 specific - frame size threshold for buffer selection. + Value in this array should be in ascending order. */ + u32 nBslThreshold[3]; } GSW_PMAC_Glbl_Cfg_t; /** \brief PMAC Ingress Configuration Source @@ -3016,32 +2923,31 @@ typedef enum { /** \brief Configure the PMAC Ingress Configuration on a given Tx DMA channel to PMAC. (Upto 16 entries). This Ingress PMAC table is addressed through Trasnmit DMA Channel Identifier. Used by \ref GSW_PMAC_IG_CFG_SET and \ref GSW_PMAC_IG_CFG_GET. */ -typedef struct -{ - /** PMAC Interface Id */ - u8 nPmacId; - /** Tx DMA Channel Identifier (0..16) - Index of Ingress PMAC Config Table */ - u8 nTxDmaChanId; - /** Error set packets to be discarded (True) or not (False) */ - ltq_bool_t bErrPktsDisc; - /** Port Map info from default PMAC header (True) or incoming PMAC header (False) */ - ltq_bool_t bPmapDefault; - /** Port Map Enable info from default PMAC header (True) or incoming PMAC header (False) */ - ltq_bool_t bPmapEna; - /** Class Info from default PMAC header (True) or incoming PMAC header (False) */ - ltq_bool_t bClassDefault; - /** Class Enable info from default PMAC header (True) or incoming PMAC header (False) */ - ltq_bool_t bClassEna; - /** Sub_Interface Id Info from ingress PMAC header (GSW_PMAC_IG_CFG_SRC_PMAC), - default PMAC header (GSW_PMAC_IG_CFG_SRC_DEF_PMAC), or source sub-If in - packet descriptor (GSW_PMAC_IG_CFG_SRC_DMA_DESC) */ - GSW_PMAC_Ig_Cfg_Src_t eSubId; - /** Source Port Id from default PMAC header (True) or incoming PMAC header (False) */ - ltq_bool_t bSpIdDefault; - /** Packet PMAC header is present (True) or not (False) */ - ltq_bool_t bPmacPresent; - /** Default PMAC header - 8 Bytes Configuration - Ingress PMAC Header Format */ - u8 defPmacHdr[8]; +typedef struct { + /** PMAC Interface Id */ + u8 nPmacId; + /** Tx DMA Channel Identifier (0..16) - Index of Ingress PMAC Config Table */ + u8 nTxDmaChanId; + /** Error set packets to be discarded (True) or not (False) */ + ltq_bool_t bErrPktsDisc; + /** Port Map info from default PMAC header (True) or incoming PMAC header (False) */ + ltq_bool_t bPmapDefault; + /** Port Map Enable info from default PMAC header (True) or incoming PMAC header (False) */ + ltq_bool_t bPmapEna; + /** Class Info from default PMAC header (True) or incoming PMAC header (False) */ + ltq_bool_t bClassDefault; + /** Class Enable info from default PMAC header (True) or incoming PMAC header (False) */ + ltq_bool_t bClassEna; + /** Sub_Interface Id Info from ingress PMAC header (GSW_PMAC_IG_CFG_SRC_PMAC), + default PMAC header (GSW_PMAC_IG_CFG_SRC_DEF_PMAC), or source sub-If in + packet descriptor (GSW_PMAC_IG_CFG_SRC_DMA_DESC) */ + GSW_PMAC_Ig_Cfg_Src_t eSubId; + /** Source Port Id from default PMAC header (True) or incoming PMAC header (False) */ + ltq_bool_t bSpIdDefault; + /** Packet PMAC header is present (True) or not (False) */ + ltq_bool_t bPmacPresent; + /** Default PMAC header - 8 Bytes Configuration - Ingress PMAC Header Format */ + u8 defPmacHdr[8]; } GSW_PMAC_Ig_Cfg_t; /** \brief Configure the PMAC Egress Configuration. (Upto 1024 entries) @@ -3050,102 +2956,99 @@ typedef struct The bits 4-7 of index option is either based upon TC (default) or combination of Processing flags is decided through bProcFlagsEgPMACEna. It is expected to pass the correct value in bProcFlagsSelect same as global bProcFlagsEgPMACEna; Used by \ref GSW_PMAC_EG_CFG_SET and \ref GSW_PMAC_EG_CFG_GET. */ -typedef struct -{ - /** PMAC Interface ID */ - u8 nPmacId; - /** Destination Port Identifier (0..15) - Part of Table Index (Bits 0-3)*/ - u8 nDestPortId; - /** Traffic Class value [Lower 4 -bits (LSB-0, 1, 2, 3)]. - Part of Table Index Bits 4-7. - This value is considered, only when bProcFlagsSelect is not set */ - u8 nTrafficClass; - /** MPE-1 Flag value - Part of Table Index Bit 4. Valid only when bProcFlagsSelect is set. */ - ltq_bool_t bMpe1Flag; - /** MPE-2 Flag value - Part of Table Index Bit 5. Valid only when bProcFlagsSelect is set. */ - ltq_bool_t bMpe2Flag; - /** Cryptography Decryption Action Flag value - Part of Table Index Bit 6. Valid only, when bProcFlagsSelect is set. */ - ltq_bool_t bDecFlag; - /** Cryptography Encryption Action Flag value - Part of Table Index Bit 7. Valid only, when bProcFlagsSelect is set. */ - ltq_bool_t bEncFlag; - /** Flow-ID MSB (2-bits) value - valid range (0..2). - Part of Table Index Bits 8-9. */ - u8 nFlowIDMsb; - /** Selector for Processing Flags (MPE1, MPE2, DEC & ENC bits). If enabled, then the combination of flags bDecFlag, bEncFlag, bMpe1Flag and bMpe2Flag are considered as index instead of nTrafficClass. For using these combination flags, turn ON this boolean selector. - TC or combination processing flag is decided at global level through bProcFlagsEgPMACEna. - It is expected that user always passes correct value based upon bProcFlagsEgMPACEna. If mismatch found with global PMAC mode, SWAPI will return error code. - - \remarks - In GSWIP-3.1, this is ignored and driver will determine automatically by - reading register. - */ - ltq_bool_t bProcFlagsSelect; - /** Receive DMA Channel Identifier (0..15) */ - u8 nRxDmaChanId; - /** To remove L2 header & additional bytes (True) or Not (False) */ - ltq_bool_t bRemL2Hdr; - /** No. of bytes to be removed after Layer-2 Header, valid when bRemL2Hdr is set */ - u8 numBytesRem; - /** Packet egressing will have FCS (True) or Not (False) */ - ltq_bool_t bFcsEna; - /** Packet egressing will have PMAC (True) or Not (False) */ - ltq_bool_t bPmacEna; - /** Enable redirection flag. GSWIP-3.1 only. - Overwritten by bRes1DW0Enable and nRes1DW0. */ - ltq_bool_t bRedirEnable; - /** Allow (False) or not allow (True) segmentation during buffer selection. - GSWIP-3.1 only. Overwritten by bResDW1Enable and nResDW1. */ - ltq_bool_t bBslSegmentDisable; - /** Traffic class used for buffer selection. GSWIP-3.1 only. - Overwritten by bResDW1Enable and nResDW1. */ - u8 nBslTrafficClass; - /** If false, nResDW1 is ignored. */ - ltq_bool_t bResDW1Enable; - /** 4-bits Reserved Field in DMA Descriptor - DW1 (bit 7 to 4) - for any future/custom usage. (Valid range : 0-15) */ - u8 nResDW1; - /** If false, nRes1DW0 is ignored. */ - ltq_bool_t bRes1DW0Enable; - /** 3-bits Reserved Field in DMA Descriptor - DW0 (bit 31 to 29) - for any future/custom usage. (Valid range : 0-7) */ - u8 nRes1DW0; - /** If false, nRes2DW0 is ignored. */ - ltq_bool_t bRes2DW0Enable; - /** 2-bits Reserved Field in DMA Descriptor - DW0 (bit 14 to 13) - for any future/custom usage. (Valid range : 0-2) */ - u8 nRes2DW0; - /** Selector for TrafficClass bits. If enabled, then the flags - bDecFlag, bEncFlag, bMpe1Flag and bMpe2Flag are not used instead nTrafficClass parameter is used. For using these flags turn off this boolean */ - ltq_bool_t bTCEnable; +typedef struct { + /** PMAC Interface ID */ + u8 nPmacId; + /** Destination Port Identifier (0..15) - Part of Table Index (Bits 0-3)*/ + u8 nDestPortId; + /** Traffic Class value [Lower 4 -bits (LSB-0, 1, 2, 3)]. - Part of Table Index Bits 4-7. + This value is considered, only when bProcFlagsSelect is not set */ + u8 nTrafficClass; + /** MPE-1 Flag value - Part of Table Index Bit 4. Valid only when bProcFlagsSelect is set. */ + ltq_bool_t bMpe1Flag; + /** MPE-2 Flag value - Part of Table Index Bit 5. Valid only when bProcFlagsSelect is set. */ + ltq_bool_t bMpe2Flag; + /** Cryptography Decryption Action Flag value - Part of Table Index Bit 6. Valid only, when bProcFlagsSelect is set. */ + ltq_bool_t bDecFlag; + /** Cryptography Encryption Action Flag value - Part of Table Index Bit 7. Valid only, when bProcFlagsSelect is set. */ + ltq_bool_t bEncFlag; + /** Flow-ID MSB (2-bits) value - valid range (0..2). - Part of Table Index Bits 8-9. */ + u8 nFlowIDMsb; + /** Selector for Processing Flags (MPE1, MPE2, DEC & ENC bits). If enabled, then the combination of flags bDecFlag, bEncFlag, bMpe1Flag and bMpe2Flag are considered as index instead of nTrafficClass. For using these combination flags, turn ON this boolean selector. + TC or combination processing flag is decided at global level through bProcFlagsEgPMACEna. + It is expected that user always passes correct value based upon bProcFlagsEgMPACEna. If mismatch found with global PMAC mode, SWAPI will return error code. + + \remarks + In GSWIP-3.1, this is ignored and driver will determine automatically by + reading register. + */ + ltq_bool_t bProcFlagsSelect; + /** Receive DMA Channel Identifier (0..15) */ + u8 nRxDmaChanId; + /** To remove L2 header & additional bytes (True) or Not (False) */ + ltq_bool_t bRemL2Hdr; + /** No. of bytes to be removed after Layer-2 Header, valid when bRemL2Hdr is set */ + u8 numBytesRem; + /** Packet egressing will have FCS (True) or Not (False) */ + ltq_bool_t bFcsEna; + /** Packet egressing will have PMAC (True) or Not (False) */ + ltq_bool_t bPmacEna; + /** Enable redirection flag. GSWIP-3.1 only. + Overwritten by bRes1DW0Enable and nRes1DW0. */ + ltq_bool_t bRedirEnable; + /** Allow (False) or not allow (True) segmentation during buffer selection. + GSWIP-3.1 only. Overwritten by bResDW1Enable and nResDW1. */ + ltq_bool_t bBslSegmentDisable; + /** Traffic class used for buffer selection. GSWIP-3.1 only. + Overwritten by bResDW1Enable and nResDW1. */ + u8 nBslTrafficClass; + /** If false, nResDW1 is ignored. */ + ltq_bool_t bResDW1Enable; + /** 4-bits Reserved Field in DMA Descriptor - DW1 (bit 7 to 4) - for any future/custom usage. (Valid range : 0-15) */ + u8 nResDW1; + /** If false, nRes1DW0 is ignored. */ + ltq_bool_t bRes1DW0Enable; + /** 3-bits Reserved Field in DMA Descriptor - DW0 (bit 31 to 29) - for any future/custom usage. (Valid range : 0-7) */ + u8 nRes1DW0; + /** If false, nRes2DW0 is ignored. */ + ltq_bool_t bRes2DW0Enable; + /** 2-bits Reserved Field in DMA Descriptor - DW0 (bit 14 to 13) - for any future/custom usage. (Valid range : 0-2) */ + u8 nRes2DW0; + /** Selector for TrafficClass bits. If enabled, then the flags + bDecFlag, bEncFlag, bMpe1Flag and bMpe2Flag are not used instead nTrafficClass parameter is used. For using these flags turn off this boolean */ + ltq_bool_t bTCEnable; } GSW_PMAC_Eg_Cfg_t; /** \brief PMAC Counters available for specified DMA Channel. Used by \ref GSW_PMAC_COUNT_GET. */ -typedef struct -{ - /** PMAC Interface ID Applicable only for GSWIP 3.1 */ - u8 nPmacId; - /*Applicable only for GSWIP 3.1*/ - ltq_bool_t b64BitMode; - /** Transmit DMA Channel Identifier (0..15) for GSWIP3.0 (0..16) for GSWIP3.1 Source PortId for Egress Counters (0..15) for GSWIP3.1 - Index */ - u8 nTxDmaChanId; - /** Ingress Total discarded packets counter (32-bits) */ - u32 nDiscPktsCount; - /** Ingress Total discarded bytes counter (32-bits) */ - u32 nDiscBytesCount; - /** Egress Total TCP/UDP/IP checksum error-ed packets counter (32-bits) */ - u32 nChkSumErrPktsCount; - /** Egress Total TCP/UDP/IP checksum error-ed bytes counter (32-bits) */ - u32 nChkSumErrBytesCount; - /** Total Ingress Packet Count in Applicable only for GSWIP 3.1 (32-bits) */ - u32 nIngressPktsCount; - /** Total Ingress Bytes Count in Applicable only for GSWIP 3.1 (32-bits) */ - u32 nIngressBytesCount; - /** Total Engress Packet Count in Applicable only for GSWIP 3.1 (32-bits) */ - u32 nEgressPktsCount; - /** Total Engress Bytes Count in Applicable only for GSWIP 3.1 (32-bits) */ - u32 nEgressBytesCount; +typedef struct { + /** PMAC Interface ID Applicable only for GSWIP 3.1 */ + u8 nPmacId; + /*Applicable only for GSWIP 3.1*/ + ltq_bool_t b64BitMode; + /** Transmit DMA Channel Identifier (0..15) for GSWIP3.0 (0..16) for GSWIP3.1 Source PortId for Egress Counters (0..15) for GSWIP3.1 - Index */ + u8 nTxDmaChanId; + /** Ingress Total discarded packets counter (32-bits) */ + u32 nDiscPktsCount; + /** Ingress Total discarded bytes counter (32-bits) */ + u32 nDiscBytesCount; + /** Egress Total TCP/UDP/IP checksum error-ed packets counter (32-bits) */ + u32 nChkSumErrPktsCount; + /** Egress Total TCP/UDP/IP checksum error-ed bytes counter (32-bits) */ + u32 nChkSumErrBytesCount; + /** Total Ingress Packet Count in Applicable only for GSWIP 3.1 (32-bits) */ + u32 nIngressPktsCount; + /** Total Ingress Bytes Count in Applicable only for GSWIP 3.1 (32-bits) */ + u32 nIngressBytesCount; + /** Total Engress Packet Count in Applicable only for GSWIP 3.1 (32-bits) */ + u32 nEgressPktsCount; + /** Total Engress Bytes Count in Applicable only for GSWIP 3.1 (32-bits) */ + u32 nEgressBytesCount; } GSW_PMAC_Cnt_t; /** \brief For debugging Purpose only. Used for GSWIP 3.1. */ -typedef struct -{ +typedef struct { /** Table Index to get status of the Table Index only for GSWIP 3.1 */ u32 nTableIndex; /** Force table Index In USEonly for GSWIP 3.1 */ @@ -3157,25 +3060,132 @@ typedef struct /** Vlan Filter debugging usage*/ u8 nDiscardUntagged; /** Vlan Filter debugging usage*/ - u8 nDiscardUnMatchedTagged; + u8 nDiscardUnMatchedTagged; /** Pmac debugging purpose*/ u8 nPmacId; /** Pmac debugging purpose*/ - u8 nDestPort; + u8 nDestPort; } GSW_debug_t; +/** \brief For debugging Purpose only. + Used for GSWIP 3.1. */ + +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. This parameter specifies for which MAC port the RMON + counter is read. It has to be set by the application before + calling \ref GSW_RMON_PORT_GET. */ + u16 nPortId; + /**Table address selection based on port type + Applicable only for GSWIP 3.1 + \ref GSW_RMON_portType_t**/ + GSW_RMON_portType_t ePortType; + /*Applicable only for GSWIP 3.1*/ + ltq_bool_t b64BitMode; + /*Applicable only for GSWIP 3.1*/ + u32 nRxExtendedVlanDiscardPkts; + /*Applicable only for GSWIP 3.1*/ + u32 nMtuExceedDiscardPkts; + /*Applicable only for GSWIP 3.1*/ + u32 nTxUnderSizeGoodPkts; + /*Applicable only for GSWIP 3.1*/ + u32 nTxOversizeGoodPkts; + /** Receive Packet Count (only packets that are accepted and not discarded). */ + u32 nRxGoodPkts; + /** Receive Unicast Packet Count. */ + u32 nRxUnicastPkts; + /** Receive Broadcast Packet Count. */ + u32 nRxBroadcastPkts; + /** Receive Multicast Packet Count. */ + u32 nRxMulticastPkts; + /** Receive FCS Error Packet Count. */ + u32 nRxFCSErrorPkts; + /** Receive Undersize Good Packet Count. */ + u32 nRxUnderSizeGoodPkts; + /** Receive Oversize Good Packet Count. */ + u32 nRxOversizeGoodPkts; + /** Receive Undersize Error Packet Count. */ + u32 nRxUnderSizeErrorPkts; + /** Receive Good Pause Packet Count. */ + u32 nRxGoodPausePkts; + /** Receive Oversize Error Packet Count. */ + u32 nRxOversizeErrorPkts; + /** Receive Align Error Packet Count. */ + u32 nRxAlignErrorPkts; + /** Filtered Packet Count. */ + u32 nRxFilteredPkts; + /** Receive Size 64 Bytes Packet Count. */ + u32 nRx64BytePkts; + /** Receive Size 65-127 Bytes Packet Count. */ + u32 nRx127BytePkts; + /** Receive Size 128-255 Bytes Packet Count. */ + u32 nRx255BytePkts; + /** Receive Size 256-511 Bytes Packet Count. */ + u32 nRx511BytePkts; + /** Receive Size 512-1023 Bytes Packet Count. */ + u32 nRx1023BytePkts; + /** Receive Size 1024-1522 Bytes (or more, if configured) Packet Count. */ + u32 nRxMaxBytePkts; + /** Overall Transmit Good Packets Count. */ + u32 nTxGoodPkts; + /** Transmit Unicast Packet Count. */ + u32 nTxUnicastPkts; + /** Transmit Broadcast Packet Count. */ + u32 nTxBroadcastPkts; + /** Transmit Multicast Packet Count. */ + u32 nTxMulticastPkts; + /** Transmit Single Collision Count. */ + u32 nTxSingleCollCount; + /** Transmit Multiple Collision Count. */ + u32 nTxMultCollCount; + /** Transmit Late Collision Count. */ + u32 nTxLateCollCount; + /** Transmit Excessive Collision Count. */ + u32 nTxExcessCollCount; + /** Transmit Collision Count. */ + u32 nTxCollCount; + /** Transmit Pause Packet Count. */ + u32 nTxPauseCount; + /** Transmit Size 64 Bytes Packet Count. */ + u32 nTx64BytePkts; + /** Transmit Size 65-127 Bytes Packet Count. */ + u32 nTx127BytePkts; + /** Transmit Size 128-255 Bytes Packet Count. */ + u32 nTx255BytePkts; + /** Transmit Size 256-511 Bytes Packet Count. */ + u32 nTx511BytePkts; + /** Transmit Size 512-1023 Bytes Packet Count. */ + u32 nTx1023BytePkts; + /** Transmit Size 1024-1522 Bytes (or more, if configured) Packet Count. */ + u32 nTxMaxBytePkts; + /** Transmit Drop Packet Count. */ + u32 nTxDroppedPkts; + /** Transmit Dropped Packet Count, based on Congestion Management. */ + u32 nTxAcmDroppedPkts; + /** Receive Dropped Packet Count. */ + u32 nRxDroppedPkts; + /** Receive Good Byte Count (64 bit). */ + u64 nRxGoodBytes; + /** Receive Bad Byte Count (64 bit). */ + u64 nRxBadBytes; + /** Transmit Good Byte Count (64 bit). */ + u64 nTxGoodBytes; +} GSW_Debug_RMON_Port_cnt_t; + + + #if 0 /** \brief PMAC Egress Counters available for every egress PMAC port. Used by \ref GSW_PMAC_EG_COUNT_GET. */ -typedef struct -{ - /** Transmitting Port Identifier (0..15) */ - u8 nTxPortId; - /** Total TCP/UDP/IP checksum error-ed packets counter (32-bits) */ - u32 nChkSumErrPktsCount; - /** Total TCP/UDP/IP checksum error-ed bytes counter (32-bits) */ - u32 nChkSumErrBytesCount; +typedef struct { + /** Transmitting Port Identifier (0..15) */ + u8 nTxPortId; + /** Total TCP/UDP/IP checksum error-ed packets counter (32-bits) */ + u32 nChkSumErrPktsCount; + /** Total TCP/UDP/IP checksum error-ed bytes counter (32-bits) */ + u32 nChkSumErrBytesCount; } GSW_PMAC_Eg_Cnt_t; #endif /*@}*/ /* GSW_IOCTL_PMAC */ @@ -3189,1046 +3199,1048 @@ typedef struct /** \brief Extended VLAN Filter Type. Used by \ref GSW_EXTENDEDVLAN_filterVLAN_t. */ -typedef enum -{ - /** There is tag and criteria applies. */ - GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL = 0, - /** There is tag but no criteria. */ - GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER = 1, - /** Default entry if no other rule applies. */ - GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT = 2, - /** There is no tag. */ - GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG = 3, - /** Block invalid*/ - GSW_EXTENDEDVLAN_BLOCK_INVALID = 4 +typedef enum { + /** There is tag and criteria applies. */ + GSW_EXTENDEDVLAN_FILTER_TYPE_NORMAL = 0, + /** There is tag but no criteria. */ + GSW_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER = 1, + /** Default entry if no other rule applies. */ + GSW_EXTENDEDVLAN_FILTER_TYPE_DEFAULT = 2, + /** There is no tag. */ + GSW_EXTENDEDVLAN_FILTER_TYPE_NO_TAG = 3, + /** Block invalid*/ + GSW_EXTENDEDVLAN_BLOCK_INVALID = 4 } GSW_ExtendedVlanFilterType_t; /** \brief Extended VLAN Filter TPID Field. Used by \ref GSW_EXTENDEDVLAN_filterVLAN_t. */ -typedef enum -{ - /** Do not filter. */ - GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER = 0, - /** TPID is 0x8100. */ - GSW_EXTENDEDVLAN_FILTER_TPID_8021Q = 1, - /** TPID is global configured value. */ - GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE = 2 +typedef enum { + /** Do not filter. */ + GSW_EXTENDEDVLAN_FILTER_TPID_NO_FILTER = 0, + /** TPID is 0x8100. */ + GSW_EXTENDEDVLAN_FILTER_TPID_8021Q = 1, + /** TPID is global configured value. */ + GSW_EXTENDEDVLAN_FILTER_TPID_VTETYPE = 2 } GSW_ExtendedVlanFilterTpid_t; /** \brief Extended VLAN Filter DEI Field. Used by \ref GSW_EXTENDEDVLAN_filterVLAN_t. */ -typedef enum -{ - /** Do not filter. */ - GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER = 0, - /** DEI is 0. */ - GSW_EXTENDEDVLAN_FILTER_DEI_0 = 1, - /** DEI is 1. */ - GSW_EXTENDEDVLAN_FILTER_DEI_1 = 2 +typedef enum { + /** Do not filter. */ + GSW_EXTENDEDVLAN_FILTER_DEI_NO_FILTER = 0, + /** DEI is 0. */ + GSW_EXTENDEDVLAN_FILTER_DEI_0 = 1, + /** DEI is 1. */ + GSW_EXTENDEDVLAN_FILTER_DEI_1 = 2 } GSW_ExtendedVlanFilterDei_t; /** \brief Extended VLAN Filter EtherType. Used by \ref GSW_EXTENDEDVLAN_filterVLAN_t. */ -typedef enum -{ - /** Do not filter. */ - GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER = 0, - /** IPoE frame (Ethertyp is 0x0800). */ - GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE = 1, - /** PPPoE frame (Ethertyp is 0x8863 or 0x8864). */ - GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE = 2, - /** ARP frame (Ethertyp is 0x0806). */ - GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP = 3, - /** IPv6 IPoE frame (Ethertyp is 0x86DD). */ - GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE = 4 +typedef enum { + /** Do not filter. */ + GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_NO_FILTER = 0, + /** IPoE frame (Ethertyp is 0x0800). */ + GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPOE = 1, + /** PPPoE frame (Ethertyp is 0x8863 or 0x8864). */ + GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_PPPOE = 2, + /** ARP frame (Ethertyp is 0x0806). */ + GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_ARP = 3, + /** IPv6 IPoE frame (Ethertyp is 0x86DD). */ + GSW_EXTENDEDVLAN_FILTER_ETHERTYPE_IPV6IPOE = 4 } GSW_ExtendedVlanFilterEthertype_t; /** \brief Extended VLAN Filter VLAN Tag. Used by \ref GSW_EXTENDEDVLAN_filter_t. */ -typedef struct -{ - /** Filter Type: normal filter, default rule, or no tag */ - GSW_ExtendedVlanFilterType_t eType; - /** Enable priority field filtering. */ - ltq_bool_t bPriorityEnable; - /** Filter priority value if bPriorityEnable is TRUE. */ - u32 nPriorityVal; - /** Enable VID filtering. */ - ltq_bool_t bVidEnable; - /** Filter VID if bVidEnable is TRUE. */ - u32 nVidVal; - /** Mode to filter TPID of VLAN tag. */ - GSW_ExtendedVlanFilterTpid_t eTpid; - /** Mode to filter DEI of VLAN tag. */ - GSW_ExtendedVlanFilterDei_t eDei; +typedef struct { + /** Filter Type: normal filter, default rule, or no tag */ + GSW_ExtendedVlanFilterType_t eType; + /** Enable priority field filtering. */ + ltq_bool_t bPriorityEnable; + /** Filter priority value if bPriorityEnable is TRUE. */ + u32 nPriorityVal; + /** Enable VID filtering. */ + ltq_bool_t bVidEnable; + /** Filter VID if bVidEnable is TRUE. */ + u32 nVidVal; + /** Mode to filter TPID of VLAN tag. */ + GSW_ExtendedVlanFilterTpid_t eTpid; + /** Mode to filter DEI of VLAN tag. */ + GSW_ExtendedVlanFilterDei_t eDei; } GSW_EXTENDEDVLAN_filterVLAN_t; /** \brief Extended VLAN Filter. Used by \ref GSW_EXTENDEDVLAN_config_t. */ -typedef struct -{ - /** Filter for outer VLAN tag. */ - GSW_EXTENDEDVLAN_filterVLAN_t sOuterVlan; - /** Filter for inner VLAN tag. */ - GSW_EXTENDEDVLAN_filterVLAN_t sInnerVlan; - /** Filter EtherType. */ - GSW_ExtendedVlanFilterEthertype_t eEtherType; +typedef struct { + /** Filter for outer VLAN tag. */ + GSW_EXTENDEDVLAN_filterVLAN_t sOuterVlan; + /** Filter for inner VLAN tag. */ + GSW_EXTENDEDVLAN_filterVLAN_t sInnerVlan; + /** Filter EtherType. */ + GSW_ExtendedVlanFilterEthertype_t eEtherType; } GSW_EXTENDEDVLAN_filter_t; /** \brief Extended VLAN Treatment Remove Tag. Used by \ref GSW_EXTENDEDVLAN_treatmentVlan_t. */ -typedef enum -{ - /** Do not remove VLAN tag. */ - GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG = 0, - /** Remove 1 VLAN tag following DA/SA. */ - GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG = 1, - /** Remove 2 VLAN tag following DA/SA. */ - GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG = 2, - /** Discard upstream traffic. */ - GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM = 3, +typedef enum { + /** Do not remove VLAN tag. */ + GSW_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG = 0, + /** Remove 1 VLAN tag following DA/SA. */ + GSW_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG = 1, + /** Remove 2 VLAN tag following DA/SA. */ + GSW_EXTENDEDVLAN_TREATMENT_REMOVE_2_TAG = 2, + /** Discard upstream traffic. */ + GSW_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM = 3, } GSW_ExtendedVlanTreatmentRemoveTag_t; /** \brief Extended VLAN Treatment Set Priority. Used by \ref GSW_EXTENDEDVLAN_treatmentVlan_t. */ -typedef enum -{ - /** Set priority with given value. */ - GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL = 0, - /** Prority value is copied from inner VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY = 1, - /** Prority value is copied from outer VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY = 2, - /** Prority value is derived from DSCP field of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_DSCP = 3 +typedef enum { + /** Set priority with given value. */ + GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL = 0, + /** Prority value is copied from inner VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_INNER_PRORITY = 1, + /** Prority value is copied from outer VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_OUTER_PRORITY = 2, + /** Prority value is derived from DSCP field of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_DSCP = 3 } GSW_ExtendedVlanTreatmentPriority_t; /** \brief Extended VLAN Treatment Set VID. Used by \ref GSW_EXTENDEDVLAN_treatmentVlan_t. */ -typedef enum -{ - /** Set VID with given value. */ - GSW_EXTENDEDVLAN_TREATMENT_VID_VAL = 0, - /** VID is copied from inner VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_INNER_VID = 1, - /** VID is copied from outer VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID = 2, +typedef enum { + /** Set VID with given value. */ + GSW_EXTENDEDVLAN_TREATMENT_VID_VAL = 0, + /** VID is copied from inner VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_INNER_VID = 1, + /** VID is copied from outer VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_OUTER_VID = 2, } GSW_ExtendedVlanTreatmentVid_t; /** \brief Extended VLAN Treatment Set TPID. Used by \ref GSW_EXTENDEDVLAN_treatmentVlan_t. */ -typedef enum -{ - /** TPID is copied from inner VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID = 0, - /** TPID is copied from outer VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID = 1, - /** TPID is global configured value. */ - GSW_EXTENDEDVLAN_TREATMENT_VTETYPE = 2, - /** TPID is 0x8100. */ - GSW_EXTENDEDVLAN_TREATMENT_8021Q = 3 +typedef enum { + /** TPID is copied from inner VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_INNER_TPID = 0, + /** TPID is copied from outer VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_OUTER_TPID = 1, + /** TPID is global configured value. */ + GSW_EXTENDEDVLAN_TREATMENT_VTETYPE = 2, + /** TPID is 0x8100. */ + GSW_EXTENDEDVLAN_TREATMENT_8021Q = 3 } GSW_ExtendedVlanTreatmentTpid_t; /** \brief Extended VLAN Treatment Set DEI. Used by \ref GSW_EXTENDEDVLAN_treatmentVlan_t. */ -typedef enum -{ - /** DEI (if applicable) is copied from inner VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI = 0, - /** DEI (if applicable) is copied from outer VLAN tag of received packet. */ - GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI = 1, - /** DEI is 0. */ - GSW_EXTENDEDVLAN_TREATMENT_DEI_0 = 2, - /** DEI is 1. */ - GSW_EXTENDEDVLAN_TREATMENT_DEI_1 = 3 +typedef enum { + /** DEI (if applicable) is copied from inner VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_INNER_DEI = 0, + /** DEI (if applicable) is copied from outer VLAN tag of received packet. */ + GSW_EXTENDEDVLAN_TREATMENT_OUTER_DEI = 1, + /** DEI is 0. */ + GSW_EXTENDEDVLAN_TREATMENT_DEI_0 = 2, + /** DEI is 1. */ + GSW_EXTENDEDVLAN_TREATMENT_DEI_1 = 3 } GSW_ExtendedVlanTreatmentDei_t; /** \brief Extended VLAN Treatment VLAN Tag. Used by \ref GSW_EXTENDEDVLAN_treatment_t. */ -typedef struct -{ - /** Select source of priority field of VLAN tag. */ - GSW_ExtendedVlanTreatmentPriority_t ePriorityMode; - /** If \ref GSW_EXTENDEDVLAN_treatmentVlan_t::ePriorityMode is - \ref GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL, use this value for - priority field of VLAN tag. */ - u32 ePriorityVal; - /** Select source of VID field of VLAN tag. */ - GSW_ExtendedVlanTreatmentVid_t eVidMode; - /** If \ref GSW_EXTENDEDVLAN_treatmentVlan_t::eVidMode is - \ref GSW_EXTENDEDVLAN_TREATMENT_VID_VAL, use this value for VID field - of VLAN tag. */ - u32 eVidVal; - /** Select source of TPID field of VLAN tag. */ - GSW_ExtendedVlanTreatmentTpid_t eTpid; - /** Select source of DEI field of VLAN tag. */ - GSW_ExtendedVlanTreatmentDei_t eDei; +typedef struct { + /** Select source of priority field of VLAN tag. */ + GSW_ExtendedVlanTreatmentPriority_t ePriorityMode; + /** If \ref GSW_EXTENDEDVLAN_treatmentVlan_t::ePriorityMode is + \ref GSW_EXTENDEDVLAN_TREATMENT_PRIORITY_VAL, use this value for + priority field of VLAN tag. */ + u32 ePriorityVal; + /** Select source of VID field of VLAN tag. */ + GSW_ExtendedVlanTreatmentVid_t eVidMode; + /** If \ref GSW_EXTENDEDVLAN_treatmentVlan_t::eVidMode is + \ref GSW_EXTENDEDVLAN_TREATMENT_VID_VAL, use this value for VID field + of VLAN tag. */ + u32 eVidVal; + /** Select source of TPID field of VLAN tag. */ + GSW_ExtendedVlanTreatmentTpid_t eTpid; + /** Select source of DEI field of VLAN tag. */ + GSW_ExtendedVlanTreatmentDei_t eDei; } GSW_EXTENDEDVLAN_treatmentVlan_t; /** \brief Extended VLAN Treatment. Used by \ref GSW_EXTENDEDVLAN_config_t. */ -typedef struct -{ - /** Number of VLAN tag(s) to remove. */ - GSW_ExtendedVlanTreatmentRemoveTag_t eRemoveTag; - - /** Enable outer VLAN tag add/modification. */ - ltq_bool_t bAddOuterVlan; - /** If bAddOuterVlan is TRUE, add or modify outer VLAN tag. */ - GSW_EXTENDEDVLAN_treatmentVlan_t sOuterVlan; - - /** Enable inner VLAN tag add/modification. */ - ltq_bool_t bAddInnerVlan; - /** If bAddInnerVlan is TRUE, add or modify inner VLAN tag. */ - GSW_EXTENDEDVLAN_treatmentVlan_t sInnerVlan; - - /** Enable re-assignment of bridge port. */ - ltq_bool_t bReassignBridgePort; - /** If bReassignBridgePort is TRUE, use this value for bridge port. */ - u32 nNewBridgePortId; - - /** Enable new DSCP. */ - ltq_bool_t bNewDscpEnable; - /** If bNewDscpEnable is TRUE, use this value for DSCP. */ - u32 nNewDscp; - - /** Enable new traffic class. */ - ltq_bool_t bNewTrafficClassEnable; - /** If bNewTrafficClassEnable is TRUE, use this value for traffic class. */ - u32 nNewTrafficClass; - - /** Enable new meter. */ - ltq_bool_t bNewMeterEnable; - /** New meter ID. - - \remarks - Meter should be allocated with \ref GSW_QOS_METER_ALLOC before extended - VLAN treatment is added. If this extended VLAN treatment is deleted, - this meter should be released with \ref GSW_QOS_METER_FREE. */ - u32 sNewTrafficMeterId; - - /** DSCP to PCP mapping, if - \ref GSW_EXTENDEDVLAN_treatmentVlan_t::ePriorityMode in - \ref GSW_EXTENDEDVLAN_treatment_t::sOuterVlan.ePriorityMode or - \ref GSW_EXTENDEDVLAN_treatment_t::sInnerVlan.ePriorityMode is - \ref GSW_EXTENDEDVLAN_TREATMENT_DSCP. - - \remarks - The index of array stands for DSCP value. Each byte of the array is 3-bit - PCP value. For implementation, if DSCP2PCP is separate hardware table, - a resource management mechanism should be implemented. Allocation happens - when extended VLAN treatment added, and release happens when the - treatment is deleted. For debug, the DSCP2PCP table can be dumped with - \ref GSW_DSCP2PCP_MAP_GET. */ - u8 nDscp2PcpMap[64]; - - /** Enable loopback. */ - ltq_bool_t bLoopbackEnable; - /** Enable destination/source MAC address swap. */ - ltq_bool_t bDaSaSwapEnable; - /** Enable traffic mirrored to the monitoring port. */ - ltq_bool_t bMirrorEnable; +typedef struct { + /** Number of VLAN tag(s) to remove. */ + GSW_ExtendedVlanTreatmentRemoveTag_t eRemoveTag; + + /** Enable outer VLAN tag add/modification. */ + ltq_bool_t bAddOuterVlan; + /** If bAddOuterVlan is TRUE, add or modify outer VLAN tag. */ + GSW_EXTENDEDVLAN_treatmentVlan_t sOuterVlan; + + /** Enable inner VLAN tag add/modification. */ + ltq_bool_t bAddInnerVlan; + /** If bAddInnerVlan is TRUE, add or modify inner VLAN tag. */ + GSW_EXTENDEDVLAN_treatmentVlan_t sInnerVlan; + + /** Enable re-assignment of bridge port. */ + ltq_bool_t bReassignBridgePort; + /** If bReassignBridgePort is TRUE, use this value for bridge port. */ + u32 nNewBridgePortId; + + /** Enable new DSCP. */ + ltq_bool_t bNewDscpEnable; + /** If bNewDscpEnable is TRUE, use this value for DSCP. */ + u32 nNewDscp; + + /** Enable new traffic class. */ + ltq_bool_t bNewTrafficClassEnable; + /** If bNewTrafficClassEnable is TRUE, use this value for traffic class. */ + u32 nNewTrafficClass; + + /** Enable new meter. */ + ltq_bool_t bNewMeterEnable; + /** New meter ID. + + \remarks + Meter should be allocated with \ref GSW_QOS_METER_ALLOC before extended + VLAN treatment is added. If this extended VLAN treatment is deleted, + this meter should be released with \ref GSW_QOS_METER_FREE. */ + u32 sNewTrafficMeterId; + + /** DSCP to PCP mapping, if + \ref GSW_EXTENDEDVLAN_treatmentVlan_t::ePriorityMode in + \ref GSW_EXTENDEDVLAN_treatment_t::sOuterVlan.ePriorityMode or + \ref GSW_EXTENDEDVLAN_treatment_t::sInnerVlan.ePriorityMode is + \ref GSW_EXTENDEDVLAN_TREATMENT_DSCP. + + \remarks + The index of array stands for DSCP value. Each byte of the array is 3-bit + PCP value. For implementation, if DSCP2PCP is separate hardware table, + a resource management mechanism should be implemented. Allocation happens + when extended VLAN treatment added, and release happens when the + treatment is deleted. For debug, the DSCP2PCP table can be dumped with + \ref GSW_DSCP2PCP_MAP_GET. */ + u8 nDscp2PcpMap[64]; + + /** Enable loopback. */ + ltq_bool_t bLoopbackEnable; + /** Enable destination/source MAC address swap. */ + ltq_bool_t bDaSaSwapEnable; + /** Enable traffic mirrored to the monitoring port. */ + ltq_bool_t bMirrorEnable; } GSW_EXTENDEDVLAN_treatment_t; /** \brief Extended VLAN Allocation. Used by \ref GSW_EXTENDEDVLAN_ALLOC and \ref GSW_EXTENDEDVLAN_FREE. */ -typedef struct -{ - /** Total number of extended VLAN entries are requested. Proper value should - be given for \ref GSW_EXTENDEDVLAN_ALLOC. This field is ignored for - \ref GSW_EXTENDEDVLAN_FREE. */ - u32 nNumberOfEntries; - - /** If \ref GSW_EXTENDEDVLAN_ALLOC is successful, a valid ID will be returned - in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. - For \ref GSW_EXTENDEDVLAN_FREE, this field should be valid ID returned by - \ref GSW_EXTENDEDVLAN_ALLOC. */ - u32 nExtendedVlanBlockId; +typedef struct { + /** Total number of extended VLAN entries are requested. Proper value should + be given for \ref GSW_EXTENDEDVLAN_ALLOC. This field is ignored for + \ref GSW_EXTENDEDVLAN_FREE. */ + u32 nNumberOfEntries; + + /** If \ref GSW_EXTENDEDVLAN_ALLOC is successful, a valid ID will be returned + in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. + For \ref GSW_EXTENDEDVLAN_FREE, this field should be valid ID returned by + \ref GSW_EXTENDEDVLAN_ALLOC. */ + u32 nExtendedVlanBlockId; } GSW_EXTENDEDVLAN_alloc_t; /** \brief Extended VLAN Configuration. Used by \ref GSW_EXTENDEDVLAN_SET and \ref GSW_EXTENDEDVLAN_GET. */ -typedef struct -{ - /** This should be valid ID returned by \ref GSW_EXTENDEDVLAN_ALLOC. - If it is \ref INVALID_HANDLE, \ref GSW_EXTENDEDVLAN_config_t::nEntryIndex - is absolute index of Extended VLAN entry in hardware for debug purpose, - bypassing any check. */ - u32 nExtendedVlanBlockId; - - /** Index of entry, ranges between 0 and - \ref GSW_EXTENDEDVLAN_alloc_t::nNumberOfEntries - 1, to - set (\ref GSW_EXTENDEDVLAN_SET) or get (\ref GSW_EXTENDEDVLAN_GET) - Extended VLAN Configuration entry. For debug purpose, this field could be - absolute index of Entended VLAN entry in hardware, when - \ref GSW_EXTENDEDVLAN_config_t::nExtendedVlanBlockId is - \ref INVALID_HANDLE. */ - u32 nEntryIndex; - - /** Extended VLAN Filter */ - GSW_EXTENDEDVLAN_filter_t sFilter; - /** Extended VLAN Treatment */ - GSW_EXTENDEDVLAN_treatment_t sTreatment; +typedef struct { + /** This should be valid ID returned by \ref GSW_EXTENDEDVLAN_ALLOC. + If it is \ref INVALID_HANDLE, \ref GSW_EXTENDEDVLAN_config_t::nEntryIndex + is absolute index of Extended VLAN entry in hardware for debug purpose, + bypassing any check. */ + u32 nExtendedVlanBlockId; + + /** Index of entry, ranges between 0 and + \ref GSW_EXTENDEDVLAN_alloc_t::nNumberOfEntries - 1, to + set (\ref GSW_EXTENDEDVLAN_SET) or get (\ref GSW_EXTENDEDVLAN_GET) + Extended VLAN Configuration entry. For debug purpose, this field could be + absolute index of Entended VLAN entry in hardware, when + \ref GSW_EXTENDEDVLAN_config_t::nExtendedVlanBlockId is + \ref INVALID_HANDLE. */ + u32 nEntryIndex; + + /** Extended VLAN Filter */ + GSW_EXTENDEDVLAN_filter_t sFilter; + /** Extended VLAN Treatment */ + GSW_EXTENDEDVLAN_treatment_t sTreatment; } GSW_EXTENDEDVLAN_config_t; /** \brief VLAN Filter TCI Mask. Used by \ref GSW_VLANFILTER_config_t */ -typedef enum -{ - GSW_VLAN_FILTER_TCI_MASK_VID = 0, - GSW_VLAN_FILTER_TCI_MASK_PCP = 1, - GSW_VLAN_FILTER_TCI_MASK_TCI = 2 +typedef enum { + GSW_VLAN_FILTER_TCI_MASK_VID = 0, + GSW_VLAN_FILTER_TCI_MASK_PCP = 1, + GSW_VLAN_FILTER_TCI_MASK_TCI = 2 } GSW_VlanFilterTciMask_t; /** \brief VLAN Filter Allocation. Used by \ref GSW_VLANFILTER_ALLOC and \ref GSW_VLANFILTER_FREE. */ -typedef struct -{ - /** Total number of VLAN Filter entries are requested. Proper value should - be given for \ref GSW_VLANFILTER_ALLOC. This field is ignored for - \ref GSW_VLANFILTER_FREE. */ - u32 nNumberOfEntries; - - /** If \ref GSW_VLANFILTER_ALLOC is successful, a valid ID will be returned - in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. - For \ref GSW_EXTENDEDVLAN_FREE, this field should be valid ID returned by - \ref GSW_VLANFILTER_ALLOC. */ - u32 nVlanFilterBlockId; - - /** Discard packet without VLAN tag. */ - ltq_bool_t bDiscardUntagged; - /** Discard VLAN tagged packet not matching any filter entry. */ - ltq_bool_t bDiscardUnmatchedTagged; - /** Use default port VLAN ID for VLAN filtering - - \remarks - This field is not available in Falcon-Mx. */ - ltq_bool_t bUseDefaultPortVID; +typedef struct { + /** Total number of VLAN Filter entries are requested. Proper value should + be given for \ref GSW_VLANFILTER_ALLOC. This field is ignored for + \ref GSW_VLANFILTER_FREE. */ + u32 nNumberOfEntries; + + /** If \ref GSW_VLANFILTER_ALLOC is successful, a valid ID will be returned + in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. + For \ref GSW_EXTENDEDVLAN_FREE, this field should be valid ID returned by + \ref GSW_VLANFILTER_ALLOC. */ + u32 nVlanFilterBlockId; + + /** Discard packet without VLAN tag. */ + ltq_bool_t bDiscardUntagged; + /** Discard VLAN tagged packet not matching any filter entry. */ + ltq_bool_t bDiscardUnmatchedTagged; + /** Use default port VLAN ID for VLAN filtering + + \remarks + This field is not available in Falcon-Mx. */ + ltq_bool_t bUseDefaultPortVID; } GSW_VLANFILTER_alloc_t; /** \brief VLAN Filter. Used by \ref GSW_VLANFILTER_SET and \ref GSW_VLANFILTER_GET */ -typedef struct -{ - /** This should be valid ID return by \ref GSW_VLANFILTER_ALLOC. - If it is \ref INVALID_HANDLE, \ref GSW_VLANFILTER_config_t::nEntryIndex - is absolute index of VLAN Filter entry in hardware for debug purpose, - bypassing any check. */ - u32 nVlanFilterBlockId; - - /** Index of entry. ranges between 0 and - \ref GSW_VLANFILTER_alloc_t::nNumberOfEntries - 1, to - set (\ref GSW_VLANFILTER_SET) or get (\ref GSW_VLANFILTER_GET) - VLAN FIlter entry. For debug purpose, this field could be absolute index - of VLAN Filter entry in hardware, when - \ref GSW_VLANFILTER_config_t::nVlanFilterBlockId is - \ref INVALID_HANDLE. */ - u32 nEntryIndex; - - /** VLAN TCI filter mask mode. - - \remarks - In GSWIP-3.1, this field of first entry in the block will applies to rest - of entries in the same block. */ - GSW_VlanFilterTciMask_t eVlanFilterMask; - - /** This is value for VLAN filtering. It depends on - \ref GSW_VLANFILTER_config_t::eVlanFilterMask. - For GSW_VLAN_FILTER_TCI_MASK_VID, this is 12-bit VLAN ID. - For GSW_VLAN_FILTER_TCI_MASK_PCP, this is 3-bit PCP field of VLAN tag. - For GSW_VLAN_FILTER_TCI_MASK_TCI, this is 16-bit TCI of VLAN tag. */ - u32 nVal; - /** Discard packet if match. */ - ltq_bool_t bDiscardMatched; +typedef struct { + /** This should be valid ID return by \ref GSW_VLANFILTER_ALLOC. + If it is \ref INVALID_HANDLE, \ref GSW_VLANFILTER_config_t::nEntryIndex + is absolute index of VLAN Filter entry in hardware for debug purpose, + bypassing any check. */ + u32 nVlanFilterBlockId; + + /** Index of entry. ranges between 0 and + \ref GSW_VLANFILTER_alloc_t::nNumberOfEntries - 1, to + set (\ref GSW_VLANFILTER_SET) or get (\ref GSW_VLANFILTER_GET) + VLAN FIlter entry. For debug purpose, this field could be absolute index + of VLAN Filter entry in hardware, when + \ref GSW_VLANFILTER_config_t::nVlanFilterBlockId is + \ref INVALID_HANDLE. */ + u32 nEntryIndex; + + /** VLAN TCI filter mask mode. + + \remarks + In GSWIP-3.1, this field of first entry in the block will applies to rest + of entries in the same block. */ + GSW_VlanFilterTciMask_t eVlanFilterMask; + + /** This is value for VLAN filtering. It depends on + \ref GSW_VLANFILTER_config_t::eVlanFilterMask. + For GSW_VLAN_FILTER_TCI_MASK_VID, this is 12-bit VLAN ID. + For GSW_VLAN_FILTER_TCI_MASK_PCP, this is 3-bit PCP field of VLAN tag. + For GSW_VLAN_FILTER_TCI_MASK_TCI, this is 16-bit TCI of VLAN tag. */ + u32 nVal; + /** Discard packet if match. */ + ltq_bool_t bDiscardMatched; } GSW_VLANFILTER_config_t; /** \brief CTP Port configuration mask. Used by \ref GSW_CTP_portConfig_t. */ -typedef enum -{ - /** Mask for \ref GSW_CTP_portConfig_t::nBridgePortId */ - GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID = 0x00000001, - /** Mask for \ref GSW_CTP_portConfig_t::bForcedTrafficClass and - \ref GSW_CTP_portConfig_t::nDefaultTrafficClass */ - GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS = 0x00000002, - /** Mask for \ref GSW_CTP_portConfig_t::bIngressExtendedVlanEnable and - \ref GSW_CTP_portConfig_t::nIngressExtendedVlanBlockId */ - GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN = 0x00000004, - /** Mask for \ref GSW_CTP_portConfig_t::bIngressExtendedVlanIgmpEnable and - \ref GSW_CTP_portConfig_t::nIngressExtendedVlanBlockIdIgmp */ - GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP = 0x00000008, - /** Mask for \ref GSW_CTP_portConfig_t::bEgressExtendedVlanEnable and - \ref GSW_CTP_portConfig_t::nEgressExtendedVlanBlockId */ - GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN = 0x00000010, - /** Mask for \ref GSW_CTP_portConfig_t::bEgressExtendedVlanIgmpEnable and - \ref GSW_CTP_portConfig_t::nEgressExtendedVlanBlockIdIgmp */ - GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP = 0x00000020, - /** Mask for \ref GSW_CTP_portConfig_t::bIngressNto1VlanEnable */ - GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN = 0x00000040, - /** Mask for \ref GSW_CTP_portConfig_t::bEgressNto1VlanEnable */ - GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN = 0x00000080, - /** Mask for \ref GSW_CTP_portConfig_t::eIngressMarkingMode */ - GSW_CTP_PORT_CONFIG_INGRESS_MARKING = 0x00000100, - /** Mask for \ref GSW_CTP_portConfig_t::eEgressMarkingMode */ - GSW_CTP_PORT_CONFIG_EGRESS_MARKING = 0x00000200, - /** Mask for \ref GSW_CTP_portConfig_t::bEgressMarkingOverrideEnable and - \ref GSW_CTP_portConfig_t::eEgressMarkingModeOverride */ - GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE = 0x00000400, - /** Mask for \ref GSW_CTP_portConfig_t::eEgressRemarkingMode */ - GSW_CTP_PORT_CONFIG_EGRESS_REMARKING = 0x00000800, - /** Mask for \ref GSW_CTP_portConfig_t::bIngressMeteringEnable and - \ref GSW_CTP_portConfig_t::nIngressTrafficMeterId */ - GSW_CTP_PORT_CONFIG_INGRESS_METER = 0x00001000, - /** Mask for \ref GSW_CTP_portConfig_t::bEgressMeteringEnable and - \ref GSW_CTP_portConfig_t::nEgressTrafficMeterId */ - GSW_CTP_PORT_CONFIG_EGRESS_METER = 0x00002000, - /** Mask for \ref GSW_CTP_portConfig_t::bBridgingBypass, - \ref GSW_CTP_portConfig_t::nDestLogicalPortId, - \ref GSW_CTP_portConfig_t::bPmapperEnable, - \ref GSW_CTP_portConfig_t::nDestSubIfIdGroup, - \ref GSW_CTP_portConfig_t::ePmapperMappingMode and - \ref GSW_CTP_portConfig_t::sPmapper */ - GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS = 0x00004000, - /** Mask for \ref GSW_CTP_portConfig_t::nFirstFlowEntryIndex and - \ref GSW_CTP_portConfig_t::nNumberOfFlowEntries */ - GSW_CTP_PORT_CONFIG_FLOW_ENTRY = 0x00008000, - /** Mask for \ref GSW_CTP_portConfig_t::bIngressLoopbackEnable, - \ref GSW_CTP_portConfig_t::bIngressDaSaSwapEnable, - \ref GSW_CTP_portConfig_t::bEgressLoopbackEnable, - \ref GSW_CTP_portConfig_t::bEgressDaSaSwapEnable, - \ref GSW_CTP_portConfig_t::bIngressMirrorEnable and - \ref GSW_CTP_portConfig_t::bEgressMirrorEnable */ - GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR = 0x00010000, - - /** Enable all fields */ - GSW_CTP_PORT_CONFIG_MASK_ALL = 0x7FFFFFFF, - /** Bypass any check for debug purpose */ - GSW_CTP_PORT_CONFIG_MASK_FORCE = 0x80000000 +typedef enum { + /** Mask for \ref GSW_CTP_portConfig_t::nBridgePortId */ + GSW_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID = 0x00000001, + /** Mask for \ref GSW_CTP_portConfig_t::bForcedTrafficClass and + \ref GSW_CTP_portConfig_t::nDefaultTrafficClass */ + GSW_CTP_PORT_CONFIG_MASK_FORCE_TRAFFIC_CLASS = 0x00000002, + /** Mask for \ref GSW_CTP_portConfig_t::bIngressExtendedVlanEnable and + \ref GSW_CTP_portConfig_t::nIngressExtendedVlanBlockId */ + GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN = 0x00000004, + /** Mask for \ref GSW_CTP_portConfig_t::bIngressExtendedVlanIgmpEnable and + \ref GSW_CTP_portConfig_t::nIngressExtendedVlanBlockIdIgmp */ + GSW_CTP_PORT_CONFIG_MASK_INGRESS_VLAN_IGMP = 0x00000008, + /** Mask for \ref GSW_CTP_portConfig_t::bEgressExtendedVlanEnable and + \ref GSW_CTP_portConfig_t::nEgressExtendedVlanBlockId */ + GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN = 0x00000010, + /** Mask for \ref GSW_CTP_portConfig_t::bEgressExtendedVlanIgmpEnable and + \ref GSW_CTP_portConfig_t::nEgressExtendedVlanBlockIdIgmp */ + GSW_CTP_PORT_CONFIG_MASK_EGRESS_VLAN_IGMP = 0x00000020, + /** Mask for \ref GSW_CTP_portConfig_t::bIngressNto1VlanEnable */ + GSW_CTP_PORT_CONFIG_MASK_INRESS_NTO1_VLAN = 0x00000040, + /** Mask for \ref GSW_CTP_portConfig_t::bEgressNto1VlanEnable */ + GSW_CTP_PORT_CONFIG_MASK_EGRESS_NTO1_VLAN = 0x00000080, + /** Mask for \ref GSW_CTP_portConfig_t::eIngressMarkingMode */ + GSW_CTP_PORT_CONFIG_INGRESS_MARKING = 0x00000100, + /** Mask for \ref GSW_CTP_portConfig_t::eEgressMarkingMode */ + GSW_CTP_PORT_CONFIG_EGRESS_MARKING = 0x00000200, + /** Mask for \ref GSW_CTP_portConfig_t::bEgressMarkingOverrideEnable and + \ref GSW_CTP_portConfig_t::eEgressMarkingModeOverride */ + GSW_CTP_PORT_CONFIG_EGRESS_MARKING_OVERRIDE = 0x00000400, + /** Mask for \ref GSW_CTP_portConfig_t::eEgressRemarkingMode */ + GSW_CTP_PORT_CONFIG_EGRESS_REMARKING = 0x00000800, + /** Mask for \ref GSW_CTP_portConfig_t::bIngressMeteringEnable and + \ref GSW_CTP_portConfig_t::nIngressTrafficMeterId */ + GSW_CTP_PORT_CONFIG_INGRESS_METER = 0x00001000, + /** Mask for \ref GSW_CTP_portConfig_t::bEgressMeteringEnable and + \ref GSW_CTP_portConfig_t::nEgressTrafficMeterId */ + GSW_CTP_PORT_CONFIG_EGRESS_METER = 0x00002000, + /** Mask for \ref GSW_CTP_portConfig_t::bBridgingBypass, + \ref GSW_CTP_portConfig_t::nDestLogicalPortId, + \ref GSW_CTP_portConfig_t::bPmapperEnable, + \ref GSW_CTP_portConfig_t::nDestSubIfIdGroup, + \ref GSW_CTP_portConfig_t::ePmapperMappingMode and + \ref GSW_CTP_portConfig_t::sPmapper */ + GSW_CTP_PORT_CONFIG_BRIDGING_BYPASS = 0x00004000, + /** Mask for \ref GSW_CTP_portConfig_t::nFirstFlowEntryIndex and + \ref GSW_CTP_portConfig_t::nNumberOfFlowEntries */ + GSW_CTP_PORT_CONFIG_FLOW_ENTRY = 0x00008000, + /** Mask for \ref GSW_CTP_portConfig_t::bIngressLoopbackEnable, + \ref GSW_CTP_portConfig_t::bIngressDaSaSwapEnable, + \ref GSW_CTP_portConfig_t::bEgressLoopbackEnable, + \ref GSW_CTP_portConfig_t::bEgressDaSaSwapEnable, + \ref GSW_CTP_portConfig_t::bIngressMirrorEnable and + \ref GSW_CTP_portConfig_t::bEgressMirrorEnable */ + GSW_CTP_PORT_CONFIG_LOOPBACK_AND_MIRROR = 0x00010000, + + /** Enable all fields */ + GSW_CTP_PORT_CONFIG_MASK_ALL = 0x7FFFFFFF, + /** Bypass any check for debug purpose */ + GSW_CTP_PORT_CONFIG_MASK_FORCE = 0x80000000 } GSW_CtpPortConfigMask_t; /** \brief Color Marking Mode Used by \ref GSW_CTP_portConfig_t. */ -typedef enum -{ - /** mark packets (except critical) to green */ - GSW_MARKING_ALL_GREEN = 0, - /** do not change color and priority */ - GSW_MARKING_INTERNAL_MARKING = 1, - /** DEI mark mode */ - GSW_MARKING_DEI = 2, - /** PCP 8P0D mark mode */ - GSW_MARKING_PCP_8P0D = 3, - /** PCP 7P1D mark mode */ - GSW_MARKING_PCP_7P1D = 4, - /** PCP 6P2D mark mode */ - GSW_MARKING_PCP_6P2D = 5, - /** PCP 5P3D mark mode */ - GSW_MARKING_PCP_5P3D = 6, - /** DSCP AF class */ - GSW_MARKING_DSCP_AF = 7 +typedef enum { + /** mark packets (except critical) to green */ + GSW_MARKING_ALL_GREEN = 0, + /** do not change color and priority */ + GSW_MARKING_INTERNAL_MARKING = 1, + /** DEI mark mode */ + GSW_MARKING_DEI = 2, + /** PCP 8P0D mark mode */ + GSW_MARKING_PCP_8P0D = 3, + /** PCP 7P1D mark mode */ + GSW_MARKING_PCP_7P1D = 4, + /** PCP 6P2D mark mode */ + GSW_MARKING_PCP_6P2D = 5, + /** PCP 5P3D mark mode */ + GSW_MARKING_PCP_5P3D = 6, + /** DSCP AF class */ + GSW_MARKING_DSCP_AF = 7 } GSW_ColorMarkingMode_t; /** \brief Color Remarking Mode Used by \ref GSW_CTP_portConfig_t. */ -typedef enum -{ - /** values from last process stage */ - GSW_REMARKING_NONE = 0, - /** DEI mark mode */ - GSW_REMARKING_DEI = 2, - /** PCP 8P0D mark mode */ - GSW_REMARKING_PCP_8P0D = 3, - /** PCP 7P1D mark mode */ - GSW_REMARKING_PCP_7P1D = 4, - /** PCP 6P2D mark mode */ - GSW_REMARKING_PCP_6P2D = 5, - /** PCP 5P3D mark mode */ - GSW_REMARKING_PCP_5P3D = 6, - /** DSCP AF class */ - GSW_REMARKING_DSCP_AF = 7 +typedef enum { + /** values from last process stage */ + GSW_REMARKING_NONE = 0, + /** DEI mark mode */ + GSW_REMARKING_DEI = 2, + /** PCP 8P0D mark mode */ + GSW_REMARKING_PCP_8P0D = 3, + /** PCP 7P1D mark mode */ + GSW_REMARKING_PCP_7P1D = 4, + /** PCP 6P2D mark mode */ + GSW_REMARKING_PCP_6P2D = 5, + /** PCP 5P3D mark mode */ + GSW_REMARKING_PCP_5P3D = 6, + /** DSCP AF class */ + GSW_REMARKING_DSCP_AF = 7 } GSW_ColorRemarkingMode_t; /** \brief P-mapper Mapping Mode Used by \ref GSW_CTP_portConfig_t. */ -typedef enum -{ - /** Use PCP for VLAN tagged packets to derive sub interface ID group. - - \remarks - P-mapper table entry 1-8. */ - GSW_PMAPPER_MAPPING_PCP = 0, - /** Use DSCP for VLAN tagged IP packets to derive sub interface ID group. - - \remarks - P-mapper table entry 9-72. */ - GSW_PMAPPER_MAPPING_DSCP = 1 +typedef enum { + /** Use PCP for VLAN tagged packets to derive sub interface ID group. + + \remarks + P-mapper table entry 1-8. */ + GSW_PMAPPER_MAPPING_PCP = 0, + /** Use DSCP for VLAN tagged IP packets to derive sub interface ID group. + + \remarks + P-mapper table entry 9-72. */ + GSW_PMAPPER_MAPPING_DSCP = 1 } GSW_PmapperMappingMode_t; /** \brief P-mapper Configuration Used by \ref GSW_CTP_portConfig_t. */ -typedef struct -{ - /** Index of P-mapper. */ - u32 nPmapperId; - - /** Sub interface ID group. - - \remarks - Entry 0 is for non-IP and non-VLAN tagged packets. Entries 1-8 are PCP - mapping entries for VLAN tagged packets with \ref GSW_PMAPPER_MAPPING_PCP - selected. Entries 9-72 are DSCP mapping entries for IP packets without - VLAN tag or VLAN tagged packets with \ref GSW_PMAPPER_MAPPING_DSCP - selected */ - u8 nDestSubIfIdGroup[73]; +typedef struct { + /** Index of P-mapper. */ + u32 nPmapperId; + + /** Sub interface ID group. + + \remarks + Entry 0 is for non-IP and non-VLAN tagged packets. Entries 1-8 are PCP + mapping entries for VLAN tagged packets with \ref GSW_PMAPPER_MAPPING_PCP + selected. Entries 9-72 are DSCP mapping entries for IP packets without + VLAN tag or VLAN tagged packets with \ref GSW_PMAPPER_MAPPING_DSCP + selected */ + u8 nDestSubIfIdGroup[73]; } GSW_PMAPPER_t; /** \brief CTP Port Configuration. Used by \ref GSW_CTP_PORT_CONFIG_SET and \ref GSW_CTP_PORT_CONFIG_GET. */ -typedef struct -{ - /** Logical Port Id. The valid range is hardware dependent. - If \ref GSW_CTP_portConfig_t::eMask has - \ref GSW_CtpPortConfigMask_t::GSW_CTP_PORT_CONFIG_MASK_FORCE, this field - is ignored. */ - u32 nLogicalPortId; - - /** Sub interface ID group. The valid range is hardware/protocol dependent. - - \remarks - Sub interface ID group is defined for each of \ref GSW_LogicalPortMode_t. - For both \ref GSW_LOGICAL_PORT_8BIT_WLAN and - \ref GSW_LOGICAL_PORT_9BIT_WLAN, this field is VAP. - For \ref GSW_LOGICAL_PORT_GPON, this field is GEM index. - For \ref GSW_LOGICAL_PORT_EPON, this field is stream index. - For \ref GSW_LOGICAL_PORT_GINT, this field is LLID. - For others, this field is 0. - If \ref GSW_CTP_portConfig_t::eMask has - \ref GSW_CtpPortConfigMask_t::GSW_CTP_PORT_CONFIG_MASK_FORCE, this field - is absolute index of CTP in hardware for debug purpose, bypassing - any check. */ - u32 nSubIfIdGroup; - - /** Mask for updating/retrieving fields. */ - GSW_CtpPortConfigMask_t eMask; - - /** Ingress Bridge Port ID to which this CTP port is associated for ingress - traffic. */ - u32 nBridgePortId; - - /** Default traffic class can not be overridden by other rules (except - traffic flow table and special tag) in processing stages. */ - ltq_bool_t bForcedTrafficClass; - /** Default traffic class associated with all ingress traffic from this CTP - Port. */ - u32 nDefaultTrafficClass; - - /** Enable Extended VLAN processing for ingress non-IGMP traffic. */ - ltq_bool_t bIngressExtendedVlanEnable; - /** Extended VLAN block allocated for ingress non-IGMP traffic. It defines - extended VLAN process for ingress non-IGMP traffic. Valid when - bIngressExtendedVlanEnable is TRUE. */ - u32 nIngressExtendedVlanBlockId; - /** Enable extended VLAN processing for ingress IGMP traffic. */ - ltq_bool_t bIngressExtendedVlanIgmpEnable; - /** Extended VLAN block allocated for ingress IGMP traffic. It defines - extended VLAN process for ingress IGMP traffic. Valid when - bIngressExtendedVlanIgmpEnable is TRUE. */ - u32 nIngressExtendedVlanBlockIdIgmp; - - /** Enable extended VLAN processing for egress non-IGMP traffic. */ - ltq_bool_t bEgressExtendedVlanEnable; - /** Extended VLAN block allocated for egress non-IGMP traffic. It defines - extended VLAN process for egress non-IGMP traffic. Valid when - bEgressExtendedVlanEnable is TRUE. */ - u32 nEgressExtendedVlanBlockId; - /** Enable extended VLAN processing for egress IGMP traffic. */ - ltq_bool_t bEgressExtendedVlanIgmpEnable; - /** Extended VLAN block allocated for egress IGMP traffic. It defines - extended VLAN process for egress IGMP traffic. Valid when - bEgressExtendedVlanIgmpEnable is TRUE. */ - u32 nEgressExtendedVlanBlockIdIgmp; - - /** For WLAN type logical port, this should be FALSE. For other types, if - enabled and ingress packet is VLAN tagged, outer VLAN ID is used for - "nSubIfId" field in MAC table, otherwise, 0 is used for "nSubIfId". */ - ltq_bool_t bIngressNto1VlanEnable; - /** For WLAN type logical port, this should be FALSE. For other types, if - enabled and egress packet is known unicast, outer VLAN ID is from - "nSubIfId" field in MAC table. */ - ltq_bool_t bEgressNto1VlanEnable; - - /** Ingress color marking mode for ingress traffic. */ - GSW_ColorMarkingMode_t eIngressMarkingMode; - /** Egress color marking mode for ingress traffic at egress priority queue - color marking stage */ - GSW_ColorMarkingMode_t eEgressMarkingMode; - /** Egress color marking mode override color marking mode from last stage. */ - ltq_bool_t bEgressMarkingOverrideEnable; - /** Egress color marking mode for egress traffic. Valid only when - bEgressMarkingOverride is TRUE. */ - GSW_ColorMarkingMode_t eEgressMarkingModeOverride; - - /** Color remarking for egress traffic. */ - GSW_ColorRemarkingMode_t eEgressRemarkingMode; - - /** Traffic metering on ingress traffic applies. */ - ltq_bool_t bIngressMeteringEnable; - /** Meter for ingress CTP process. - - \remarks - Meter should be allocated with \ref GSW_QOS_METER_ALLOC before CTP - port configuration. If this CTP port is re-set, the last used meter - should be released. */ - u32 nIngressTrafficMeterId; - /** Traffic metering on egress traffic applies. */ - ltq_bool_t bEgressMeteringEnable; - /** Meter for egress CTP process. - - \remarks - Meter should be allocated with \ref GSW_QOS_METER_ALLOC before CTP - port configuration. If this CTP port is re-set, the last used meter - should be released. */ - u32 nEgressTrafficMeterId; - - /** Ingress traffic bypass bridging/multicast processing. Following - parameters are used to determine destination. Traffic flow table is not - bypassed. */ - ltq_bool_t bBridgingBypass; - /** When bBridgingBypass is TRUE, this field defines destination logical - port. */ - u32 nDestLogicalPortId; - /** When bBridgingBypass is TRUE, this field indicates whether to use - \ref GSW_CTP_portConfig_t::nDestSubIfIdGroup or - \ref GSW_CTP_portConfig_t::ePmapperMappingMode/ - \ref GSW_CTP_portConfig_t::sPmapper. */ - ltq_bool_t bPmapperEnable; - /** When bBridgingBypass is TRUE and bPmapperEnable is FALSE, this field - defines destination sub interface ID group. */ - u32 nDestSubIfIdGroup; - /** When bBridgingBypass is TRUE and bPmapperEnable is TRUE, this field - selects either DSCP or PCP to derive sub interface ID. */ - GSW_PmapperMappingMode_t ePmapperMappingMode; - /** When bBridgingBypass is TRUE and bPmapperEnable is TRUE, P-mapper is - used. API implementation need take care of P-mapper allocation, and - maintain the reference counter of P-mapper used multiple times. */ - GSW_PMAPPER_t sPmapper; - - /** First traffic flow table entry is associated to this CTP port. Ingress - traffic from this CTP port will go through traffic flow table search - starting from nFirstFlowEntryIndex. Should be times of 4. */ - u32 nFirstFlowEntryIndex; - /** Number of traffic flow table entries are associated to this CTP port. - Ingress traffic from this CTP port will go through PCE rules search - ending at (nFirstFlowEntryIndex+nNumberOfFlowEntries)-1. Should - be times of 4. */ - u32 nNumberOfFlowEntries; - - /** Ingress traffic from this CTP port will be redirected to ingress - logical port of this CTP port with source sub interface ID used as - destination sub interface ID. Following processing except traffic - flow table search is bypassed if loopback enabled. */ - ltq_bool_t bIngressLoopbackEnable; - /** Destination/Source MAC address of ingress traffic is swapped before - transmitted (not swapped during PCE processing stages). If destination - is multicast, there is no swap, but source MAC address is replaced - with global configurable value. */ - ltq_bool_t bIngressDaSaSwapEnable; - /** Egress traffic to this CTP port will be redirected to ingress logical - port with same sub interface ID as ingress. */ - ltq_bool_t bEgressLoopbackEnable; - /** Destination/Source MAC address of egress traffic is swapped before - transmitted. */ - ltq_bool_t bEgressDaSaSwapEnable; - - /** If enabled, ingress traffic is mirrored to the monitoring port. - - \remarks - This should be used exclusive with bIngressLoopbackEnable. */ - ltq_bool_t bIngressMirrorEnable; - /** If enabled, egress traffic is mirrored to the monitoring port. - - \remarks - This should be used exclusive with bEgressLoopbackEnable. */ - ltq_bool_t bEgressMirrorEnable; +typedef struct { + /** Logical Port Id. The valid range is hardware dependent. + If \ref GSW_CTP_portConfig_t::eMask has + \ref GSW_CtpPortConfigMask_t::GSW_CTP_PORT_CONFIG_MASK_FORCE, this field + is ignored. */ + u32 nLogicalPortId; + + /** Sub interface ID group. The valid range is hardware/protocol dependent. + + \remarks + Sub interface ID group is defined for each of \ref GSW_LogicalPortMode_t. + For both \ref GSW_LOGICAL_PORT_8BIT_WLAN and + \ref GSW_LOGICAL_PORT_9BIT_WLAN, this field is VAP. + For \ref GSW_LOGICAL_PORT_GPON, this field is GEM index. + For \ref GSW_LOGICAL_PORT_EPON, this field is stream index. + For \ref GSW_LOGICAL_PORT_GINT, this field is LLID. + For others, this field is 0. + If \ref GSW_CTP_portConfig_t::eMask has + \ref GSW_CtpPortConfigMask_t::GSW_CTP_PORT_CONFIG_MASK_FORCE, this field + is absolute index of CTP in hardware for debug purpose, bypassing + any check. */ + u32 nSubIfIdGroup; + + /** Mask for updating/retrieving fields. */ + GSW_CtpPortConfigMask_t eMask; + + /** Ingress Bridge Port ID to which this CTP port is associated for ingress + traffic. */ + u32 nBridgePortId; + + /** Default traffic class can not be overridden by other rules (except + traffic flow table and special tag) in processing stages. */ + ltq_bool_t bForcedTrafficClass; + /** Default traffic class associated with all ingress traffic from this CTP + Port. */ + u32 nDefaultTrafficClass; + + /** Enable Extended VLAN processing for ingress non-IGMP traffic. */ + ltq_bool_t bIngressExtendedVlanEnable; + /** Extended VLAN block allocated for ingress non-IGMP traffic. It defines + extended VLAN process for ingress non-IGMP traffic. Valid when + bIngressExtendedVlanEnable is TRUE. */ + u32 nIngressExtendedVlanBlockId; + /** Extended VLAN block size for ingress non-IGMP traffic. This is optional. + If it is 0, the block size of nIngressExtendedVlanBlockId will be used. + Otherwise, this field will be used. */ + u32 nIngressExtendedVlanBlockSize; + /** Enable extended VLAN processing for ingress IGMP traffic. */ + ltq_bool_t bIngressExtendedVlanIgmpEnable; + /** Extended VLAN block allocated for ingress IGMP traffic. It defines + extended VLAN process for ingress IGMP traffic. Valid when + bIngressExtendedVlanIgmpEnable is TRUE. */ + u32 nIngressExtendedVlanBlockIdIgmp; + /** Extended VLAN block size for ingress IGMP traffic. This is optional. + If it is 0, the block size of nIngressExtendedVlanBlockIdIgmp will be + used. Otherwise, this field will be used. */ + u32 nIngressExtendedVlanBlockSizeIgmp; + + /** Enable extended VLAN processing for egress non-IGMP traffic. */ + ltq_bool_t bEgressExtendedVlanEnable; + /** Extended VLAN block allocated for egress non-IGMP traffic. It defines + extended VLAN process for egress non-IGMP traffic. Valid when + bEgressExtendedVlanEnable is TRUE. */ + u32 nEgressExtendedVlanBlockId; + /** Extended VLAN block size for egress non-IGMP traffic. This is optional. + If it is 0, the block size of nEgressExtendedVlanBlockId will be used. + Otherwise, this field will be used. */ + u32 nEgressExtendedVlanBlockSize; + /** Enable extended VLAN processing for egress IGMP traffic. */ + ltq_bool_t bEgressExtendedVlanIgmpEnable; + /** Extended VLAN block allocated for egress IGMP traffic. It defines + extended VLAN process for egress IGMP traffic. Valid when + bEgressExtendedVlanIgmpEnable is TRUE. */ + u32 nEgressExtendedVlanBlockIdIgmp; + /** Extended VLAN block size for egress IGMP traffic. This is optional. + If it is 0, the block size of nEgressExtendedVlanBlockIdIgmp will be + used. Otherwise, this field will be used. */ + u32 nEgressExtendedVlanBlockSizeIgmp; + + /** For WLAN type logical port, this should be FALSE. For other types, if + enabled and ingress packet is VLAN tagged, outer VLAN ID is used for + "nSubIfId" field in MAC table, otherwise, 0 is used for "nSubIfId". */ + ltq_bool_t bIngressNto1VlanEnable; + /** For WLAN type logical port, this should be FALSE. For other types, if + enabled and egress packet is known unicast, outer VLAN ID is from + "nSubIfId" field in MAC table. */ + ltq_bool_t bEgressNto1VlanEnable; + + /** Ingress color marking mode for ingress traffic. */ + GSW_ColorMarkingMode_t eIngressMarkingMode; + /** Egress color marking mode for ingress traffic at egress priority queue + color marking stage */ + GSW_ColorMarkingMode_t eEgressMarkingMode; + /** Egress color marking mode override color marking mode from last stage. */ + ltq_bool_t bEgressMarkingOverrideEnable; + /** Egress color marking mode for egress traffic. Valid only when + bEgressMarkingOverride is TRUE. */ + GSW_ColorMarkingMode_t eEgressMarkingModeOverride; + + /** Color remarking for egress traffic. */ + GSW_ColorRemarkingMode_t eEgressRemarkingMode; + + /** Traffic metering on ingress traffic applies. */ + ltq_bool_t bIngressMeteringEnable; + /** Meter for ingress CTP process. + + \remarks + Meter should be allocated with \ref GSW_QOS_METER_ALLOC before CTP + port configuration. If this CTP port is re-set, the last used meter + should be released. */ + u32 nIngressTrafficMeterId; + /** Traffic metering on egress traffic applies. */ + ltq_bool_t bEgressMeteringEnable; + /** Meter for egress CTP process. + + \remarks + Meter should be allocated with \ref GSW_QOS_METER_ALLOC before CTP + port configuration. If this CTP port is re-set, the last used meter + should be released. */ + u32 nEgressTrafficMeterId; + + /** Ingress traffic bypass bridging/multicast processing. Following + parameters are used to determine destination. Traffic flow table is not + bypassed. */ + ltq_bool_t bBridgingBypass; + /** When bBridgingBypass is TRUE, this field defines destination logical + port. */ + u32 nDestLogicalPortId; + /** When bBridgingBypass is TRUE, this field indicates whether to use + \ref GSW_CTP_portConfig_t::nDestSubIfIdGroup or + \ref GSW_CTP_portConfig_t::ePmapperMappingMode/ + \ref GSW_CTP_portConfig_t::sPmapper. */ + ltq_bool_t bPmapperEnable; + /** When bBridgingBypass is TRUE and bPmapperEnable is FALSE, this field + defines destination sub interface ID group. */ + u32 nDestSubIfIdGroup; + /** When bBridgingBypass is TRUE and bPmapperEnable is TRUE, this field + selects either DSCP or PCP to derive sub interface ID. */ + GSW_PmapperMappingMode_t ePmapperMappingMode; + /** When bBridgingBypass is TRUE and bPmapperEnable is TRUE, P-mapper is + used. API implementation need take care of P-mapper allocation, and + maintain the reference counter of P-mapper used multiple times. */ + GSW_PMAPPER_t sPmapper; + + /** First traffic flow table entry is associated to this CTP port. Ingress + traffic from this CTP port will go through traffic flow table search + starting from nFirstFlowEntryIndex. Should be times of 4. */ + u32 nFirstFlowEntryIndex; + /** Number of traffic flow table entries are associated to this CTP port. + Ingress traffic from this CTP port will go through PCE rules search + ending at (nFirstFlowEntryIndex+nNumberOfFlowEntries)-1. Should + be times of 4. */ + u32 nNumberOfFlowEntries; + + /** Ingress traffic from this CTP port will be redirected to ingress + logical port of this CTP port with source sub interface ID used as + destination sub interface ID. Following processing except traffic + flow table search is bypassed if loopback enabled. */ + ltq_bool_t bIngressLoopbackEnable; + /** Destination/Source MAC address of ingress traffic is swapped before + transmitted (not swapped during PCE processing stages). If destination + is multicast, there is no swap, but source MAC address is replaced + with global configurable value. */ + ltq_bool_t bIngressDaSaSwapEnable; + /** Egress traffic to this CTP port will be redirected to ingress logical + port with same sub interface ID as ingress. */ + ltq_bool_t bEgressLoopbackEnable; + /** Destination/Source MAC address of egress traffic is swapped before + transmitted. */ + ltq_bool_t bEgressDaSaSwapEnable; + + /** If enabled, ingress traffic is mirrored to the monitoring port. + + \remarks + This should be used exclusive with bIngressLoopbackEnable. */ + ltq_bool_t bIngressMirrorEnable; + /** If enabled, egress traffic is mirrored to the monitoring port. + + \remarks + This should be used exclusive with bEgressLoopbackEnable. */ + ltq_bool_t bEgressMirrorEnable; } GSW_CTP_portConfig_t; /** \brief Bridge Port configuration mask. Used by \ref GSW_BRIDGE_portConfig_t. */ -typedef enum -{ - /** Mask for \ref GSW_BRIDGE_portConfig_t::nBridgeId */ - GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID = 0x00000001, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressExtendedVlanEnable and - \ref GSW_BRIDGE_portConfig_t::nIngressExtendedVlanBlockId */ - GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN = 0x00000002, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressExtendedVlanEnable and - \ref GSW_BRIDGE_portConfig_t::nEgressExtendedVlanBlockId */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN = 0x00000004, - /** Mask for \ref GSW_BRIDGE_portConfig_t::eIngressMarkingMode */ - GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING = 0x00000008, - /** Mask for \ref GSW_BRIDGE_portConfig_t::eEgressRemarkingMode */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING = 0x00000010, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressMeteringEnable and - \ref GSW_BRIDGE_portConfig_t::nIngressTrafficMeterId */ - GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER = 0x00000020, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressSubMeteringEnable and - \ref GSW_BRIDGE_portConfig_t::nEgressTrafficSubMeterId */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER = 0x00000040, - /** Mask for \ref GSW_BRIDGE_portConfig_t::nDestLogicalPortId, - \ref GSW_BRIDGE_portConfig_t::bPmapperEnable, - \ref GSW_BRIDGE_portConfig_t::nDestSubIfIdGroup, - \ref GSW_BRIDGE_portConfig_t::ePmapperMappingMode and - \ref GSW_BRIDGE_portConfig_t::sPmapper. */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING = 0x00000080, - /** Mask for \ref GSW_BRIDGE_portConfig_t::nBridgePortMap */ - GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP = 0x00000100, - - /** Mask for \ref GSW_BRIDGE_portConfig_t::bMcDestIpLookupEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP = 0x00000200, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bMcSrcIpLookupEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP = 0x00000400, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bDestMacLookupEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP = 0x00000800, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bSrcMacLearningEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING = 0x00001000, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bMacSpoofingDetectEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING = 0x00002000, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bPortLockEnable. */ - GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK = 0x00004000, - - /** Mask for \ref GSW_BRIDGE_portConfig_t::bMacLearningLimitEnable and - \ref GSW_BRIDGE_portConfig_t::nMacLearningLimit. */ - GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT = 0x00008000, - /** Mask for \ref GSW_BRIDGE_portConfig_t::nMacLearningCount */ - GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNED_COUNT = 0x00010000, - - /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressVlanFilterEnable and - \ref GSW_BRIDGE_portConfig_t::nIngressVlanFilterBlockId. */ - GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER = 0x00020000, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bBypassEgressVlanFilter1, - \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter1Enable - and \ref GSW_BRIDGE_portConfig_t::nEgressVlanFilter1BlockId. */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1 = 0x00040000, - /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter2Enable and - \ref GSW_BRIDGE_portConfig_t::nEgressVlanFilter2BlockId. */ - GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2 = 0x00080000, - - /** Enable all */ - GSW_BRIDGE_PORT_CONFIG_MASK_ALL = 0x7FFFFFFF, - /** Bypass any check for debug purpose */ - GSW_BRIDGE_PORT_CONFIG_MASK_FORCE = 0x80000000 +typedef enum { + /** Mask for \ref GSW_BRIDGE_portConfig_t::nBridgeId */ + GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID = 0x00000001, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressExtendedVlanEnable and + \ref GSW_BRIDGE_portConfig_t::nIngressExtendedVlanBlockId */ + GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN = 0x00000002, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressExtendedVlanEnable and + \ref GSW_BRIDGE_portConfig_t::nEgressExtendedVlanBlockId */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN = 0x00000004, + /** Mask for \ref GSW_BRIDGE_portConfig_t::eIngressMarkingMode */ + GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_MARKING = 0x00000008, + /** Mask for \ref GSW_BRIDGE_portConfig_t::eEgressRemarkingMode */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_REMARKING = 0x00000010, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressMeteringEnable and + \ref GSW_BRIDGE_portConfig_t::nIngressTrafficMeterId */ + GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_METER = 0x00000020, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressSubMeteringEnable and + \ref GSW_BRIDGE_portConfig_t::nEgressTrafficSubMeterId */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER = 0x00000040, + /** Mask for \ref GSW_BRIDGE_portConfig_t::nDestLogicalPortId, + \ref GSW_BRIDGE_portConfig_t::bPmapperEnable, + \ref GSW_BRIDGE_portConfig_t::nDestSubIfIdGroup, + \ref GSW_BRIDGE_portConfig_t::ePmapperMappingMode and + \ref GSW_BRIDGE_portConfig_t::sPmapper. */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_CTP_MAPPING = 0x00000080, + /** Mask for \ref GSW_BRIDGE_portConfig_t::nBridgePortMap */ + GSW_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP = 0x00000100, + + /** Mask for \ref GSW_BRIDGE_portConfig_t::bMcDestIpLookupEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_IP_LOOKUP = 0x00000200, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bMcSrcIpLookupEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_IP_LOOKUP = 0x00000400, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bDestMacLookupEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MC_DEST_MAC_LOOKUP = 0x00000800, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bSrcMacLearningEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING = 0x00001000, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bMacSpoofingDetectEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MAC_SPOOFING = 0x00002000, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bPortLockEnable. */ + GSW_BRIDGE_PORT_CONFIG_MASK_PORT_LOCK = 0x00004000, + + /** Mask for \ref GSW_BRIDGE_portConfig_t::bMacLearningLimitEnable and + \ref GSW_BRIDGE_portConfig_t::nMacLearningLimit. */ + GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNING_LIMIT = 0x00008000, + /** Mask for \ref GSW_BRIDGE_portConfig_t::nMacLearningCount */ + GSW_BRIDGE_PORT_CONFIG_MASK_MAC_LEARNED_COUNT = 0x00010000, + + /** Mask for \ref GSW_BRIDGE_portConfig_t::bIngressVlanFilterEnable and + \ref GSW_BRIDGE_portConfig_t::nIngressVlanFilterBlockId. */ + GSW_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER = 0x00020000, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bBypassEgressVlanFilter1, + \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter1Enable + and \ref GSW_BRIDGE_portConfig_t::nEgressVlanFilter1BlockId. */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1 = 0x00040000, + /** Mask for \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter2Enable and + \ref GSW_BRIDGE_portConfig_t::nEgressVlanFilter2BlockId. */ + GSW_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER2 = 0x00080000, + + /** Enable all */ + GSW_BRIDGE_PORT_CONFIG_MASK_ALL = 0x7FFFFFFF, + /** Bypass any check for debug purpose */ + GSW_BRIDGE_PORT_CONFIG_MASK_FORCE = 0x80000000 } GSW_BridgePortConfigMask_t; /** \brief Meters for various egress traffic type. Used by \ref GSW_BRIDGE_portConfig_t. */ -typedef enum -{ - /** Index of broadcast traffic meter */ - GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST = 0, - /** Index of known multicast traffic meter */ - GSW_BRIDGE_PORT_EGRESS_METER_MULTICAST = 1, - /** Index of unknown multicast IP traffic meter */ - GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP = 2, - /** Index of unknown multicast non-IP traffic meter */ - GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP = 3, - /** Index of unknown unicast traffic meter */ - GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC = 4, - /** Index of traffic meter for other types */ - GSW_BRIDGE_PORT_EGRESS_METER_OTHERS = 5, - /** Number of index */ - GSW_BRIDGE_PORT_EGRESS_METER_MAX = 6 +typedef enum { + /** Index of broadcast traffic meter */ + GSW_BRIDGE_PORT_EGRESS_METER_BROADCAST = 0, + /** Index of known multicast traffic meter */ + GSW_BRIDGE_PORT_EGRESS_METER_MULTICAST = 1, + /** Index of unknown multicast IP traffic meter */ + GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP = 2, + /** Index of unknown multicast non-IP traffic meter */ + GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP = 3, + /** Index of unknown unicast traffic meter */ + GSW_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC = 4, + /** Index of traffic meter for other types */ + GSW_BRIDGE_PORT_EGRESS_METER_OTHERS = 5, + /** Number of index */ + GSW_BRIDGE_PORT_EGRESS_METER_MAX = 6 } GSW_BridgePortEgressMeter_t; /** \brief Bridge forwarding type of packet. Used by \ref GSW_BRIDGE_portConfig_t. */ -typedef enum -{ - /** Packet is flooded to port members of ingress bridge port */ - GSW_BRIDGE_FORWARD_FLOOD = 0, - /** Packet is dscarded */ - GSW_BRIDGE_FORWARD_DISCARD = 1, - /** Packet is forwarded to logical port 0 CTP port 0 bridge port 0 */ - GSW_BRIDGE_FORWARD_CPU = 2 +typedef enum { + /** Packet is flooded to port members of ingress bridge port */ + GSW_BRIDGE_FORWARD_FLOOD = 0, + /** Packet is dscarded */ + GSW_BRIDGE_FORWARD_DISCARD = 1, + /** Packet is forwarded to logical port 0 CTP port 0 bridge port 0 */ + GSW_BRIDGE_FORWARD_CPU = 2 } GSW_BridgeForwardMode_t; /** \brief Bridge Port Allocation. Used by \ref GSW_BRIDGE_PORT_ALLOC and \ref GSW_BRIDGE_PORT_FREE. */ -typedef struct -{ - /** If \ref GSW_BRIDGE_PORT_ALLOC is successful, a valid ID will be returned - in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. - For \ref GSW_BRIDGE_PORT_FREE, this field should be valid ID returned by - \ref GSW_BRIDGE_PORT_ALLOC. ID 0 is special for CPU port in Falcon-Mx - by mapping to CTP 0 (Logical Port 0 with Sub-interface ID 0), and - pre-alloced during initialization. */ - u32 nBridgePortId; +typedef struct { + /** If \ref GSW_BRIDGE_PORT_ALLOC is successful, a valid ID will be returned + in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. + For \ref GSW_BRIDGE_PORT_FREE, this field should be valid ID returned by + \ref GSW_BRIDGE_PORT_ALLOC. ID 0 is special for CPU port in Falcon-Mx + by mapping to CTP 0 (Logical Port 0 with Sub-interface ID 0), and + pre-alloced during initialization. */ + u32 nBridgePortId; } GSW_BRIDGE_portAlloc_t; /** \brief Bridge Port Configuration. Used by \ref GSW_BRIDGE_PORT_CONFIG_SET and \ref GSW_BRIDGE_PORT_CONFIG_GET. */ -typedef struct -{ - /** Bridge Port ID allocated by \ref GSW_BRIDGE_PORT_ALLOC. - - \remarks - If \ref GSW_BRIDGE_portConfig_t::eMask has - \ref GSW_BridgePortConfigMask_t::GSW_BRIDGE_PORT_CONFIG_MASK_FORCE, this - field is absolute index of Bridge Port in hardware for debug purpose, - bypassing any check. */ - u32 nBridgePortId; - - /** Mask for updating/retrieving fields. */ - GSW_BridgePortConfigMask_t eMask; - - /** Bridge ID (FID) to which this bridge port is associated. A default - bridge (ID 0) should be always available. */ - u32 nBridgeId; - - /** Enable extended VLAN processing for ingress non-IGMP traffic. */ - ltq_bool_t bIngressExtendedVlanEnable; - /** Extended VLAN block allocated for ingress non-IGMP traffic. It defines - extended VLAN process for ingress non-IGMP traffic. Valid when - bIngressExtendedVlanEnable is TRUE. */ - u32 nIngressExtendedVlanBlockId; - - /** Enable extended VLAN processing enabled for egress non-IGMP traffic. */ - ltq_bool_t bEgressExtendedVlanEnable; - /** Extended VLAN block allocated for egress non-IGMP traffic. It defines - extended VLAN process for egress non-IGMP traffic. Valid when - bEgressExtendedVlanEnable is TRUE. */ - u32 nEgressExtendedVlanBlockId; - - /** Ingress color marking mode for ingress traffic. */ - GSW_ColorMarkingMode_t eIngressMarkingMode; - - /** Color remarking for egress traffic. */ - GSW_ColorRemarkingMode_t eEgressRemarkingMode; - - /** Traffic metering on ingress traffic applies. */ - ltq_bool_t bIngressMeteringEnable; - /** Meter for ingress Bridge Port process. - - \remarks - Meter should be allocated with \ref GSW_QOS_METER_ALLOC before Bridge - port configuration. If this Bridge port is re-set, the last used meter - should be released. */ - u32 nIngressTrafficMeterId; - - /** Traffic metering on various types of egress traffic (such as broadcast, - multicast, unknown unicast, etc) applies. */ - ltq_bool_t bEgressSubMeteringEnable[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; - /** Meter for egress Bridge Port process with specific type (such as - broadcast, multicast, unknown unicast, etc). Need pre-allocated for each - type. */ - u32 nEgressTrafficSubMeterId[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; - - /** This field defines destination logical port. */ - u32 nDestLogicalPortId; - /** This field indicates whether to enable P-mapper. */ - ltq_bool_t bPmapperEnable; - /** When bPmapperEnable is FALSE, this field defines destination sub - interface ID group. */ - u32 nDestSubIfIdGroup; - /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to - derive sub interface ID. */ - GSW_PmapperMappingMode_t ePmapperMappingMode; - /** When bPmapperEnable is TRUE, P-mapper is used. API implementation need - take care of P-mapper allocation, and maintain the reference counter of - P-mapper used multiple times. */ - GSW_PMAPPER_t sPmapper; - - /** Port map define broadcast domain. - - \remarks - Each bit is one bridge port. Bridge port ID is index * 16 + bit offset. - For example, bit 1 of nBridgePortMap[1] is bridge port ID 17. */ - u16 nBridgePortMap[16]; - - /** Multicast IP table is searched if this field is FALSE and traffic is IP - multicast. */ - ltq_bool_t bMcDestIpLookupDisable; - /** Multicast IP table is searched if this field is TRUE and traffic is IP - multicast. */ - ltq_bool_t bMcSrcIpLookupEnable; - - /** Default is FALSE. Packet is treated as "unknown" if it's not - broadcast/multicast packet. */ - ltq_bool_t bDestMacLookupDisable; - - /** Default is FALSE. Source MAC address is learned. */ - ltq_bool_t bSrcMacLearningDisable; - - /** If this field is TRUE and MAC address which is already learned in another - bridge port appears on this bridge port, port locking violation is - detected. */ - ltq_bool_t bMacSpoofingDetectEnable; - - /** If this field is TRUE and MAC address which is already learned in this - bridge port appears on another bridge port, port locking violation is - detected. */ - ltq_bool_t bPortLockEnable; - - /** Enable MAC learning limitation. */ - ltq_bool_t bMacLearningLimitEnable; - /** Max number of MAC can be learned from this bridge port. */ - u32 nMacLearningLimit; - - /** Get number of MAC address learned from this bridge port. */ - u32 nMacLearningCount; - - /** Enable ingress VLAN filter */ - ltq_bool_t bIngressVlanFilterEnable; - /** VLAN filter block of ingress traffic if - \ref GSW_BRIDGE_portConfig_t::bIngressVlanFilterEnable is TRUE. */ - u32 nIngressVlanFilterBlockId; - /** For ingress traffic, bypass VLAN filter 2 during egress bridge port - process. */ - ltq_bool_t bBypassEgressVlanFilter1; - /** Enable egress VLAN filter 1 */ - ltq_bool_t bEgressVlanFilter1Enable; - /** VLAN filter block 1 of egress traffic if - \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter1Enable is TRUE. */ - u32 nEgressVlanFilter1BlockId; - /** Enable egress VLAN filter 2 */ - ltq_bool_t bEgressVlanFilter2Enable; - /** VLAN filter block 2 of egress traffic if - \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter2Enable is TRUE. */ - u32 nEgressVlanFilter2BlockId; +typedef struct { + /** Bridge Port ID allocated by \ref GSW_BRIDGE_PORT_ALLOC. + + \remarks + If \ref GSW_BRIDGE_portConfig_t::eMask has + \ref GSW_BridgePortConfigMask_t::GSW_BRIDGE_PORT_CONFIG_MASK_FORCE, this + field is absolute index of Bridge Port in hardware for debug purpose, + bypassing any check. */ + u32 nBridgePortId; + + /** Mask for updating/retrieving fields. */ + GSW_BridgePortConfigMask_t eMask; + + /** Bridge ID (FID) to which this bridge port is associated. A default + bridge (ID 0) should be always available. */ + u32 nBridgeId; + + /** Enable extended VLAN processing for ingress non-IGMP traffic. */ + ltq_bool_t bIngressExtendedVlanEnable; + /** Extended VLAN block allocated for ingress non-IGMP traffic. It defines + extended VLAN process for ingress non-IGMP traffic. Valid when + bIngressExtendedVlanEnable is TRUE. */ + u32 nIngressExtendedVlanBlockId; + /** Extended VLAN block size for ingress non-IGMP traffic. This is optional. + If it is 0, the block size of nIngressExtendedVlanBlockId will be used. + Otherwise, this field will be used. */ + u32 nIngressExtendedVlanBlockSize; + + /** Enable extended VLAN processing enabled for egress non-IGMP traffic. */ + ltq_bool_t bEgressExtendedVlanEnable; + /** Extended VLAN block allocated for egress non-IGMP traffic. It defines + extended VLAN process for egress non-IGMP traffic. Valid when + bEgressExtendedVlanEnable is TRUE. */ + u32 nEgressExtendedVlanBlockId; + /** Extended VLAN block size for egress non-IGMP traffic. This is optional. + If it is 0, the block size of nEgressExtendedVlanBlockId will be used. + Otherwise, this field will be used. */ + u32 nEgressExtendedVlanBlockSize; + + /** Ingress color marking mode for ingress traffic. */ + GSW_ColorMarkingMode_t eIngressMarkingMode; + + /** Color remarking for egress traffic. */ + GSW_ColorRemarkingMode_t eEgressRemarkingMode; + + /** Traffic metering on ingress traffic applies. */ + ltq_bool_t bIngressMeteringEnable; + /** Meter for ingress Bridge Port process. + + \remarks + Meter should be allocated with \ref GSW_QOS_METER_ALLOC before Bridge + port configuration. If this Bridge port is re-set, the last used meter + should be released. */ + u32 nIngressTrafficMeterId; + + /** Traffic metering on various types of egress traffic (such as broadcast, + multicast, unknown unicast, etc) applies. */ + ltq_bool_t bEgressSubMeteringEnable[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; + /** Meter for egress Bridge Port process with specific type (such as + broadcast, multicast, unknown unicast, etc). Need pre-allocated for each + type. */ + u32 nEgressTrafficSubMeterId[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; + + /** This field defines destination logical port. */ + u32 nDestLogicalPortId; + /** This field indicates whether to enable P-mapper. */ + ltq_bool_t bPmapperEnable; + /** When bPmapperEnable is FALSE, this field defines destination sub + interface ID group. */ + u32 nDestSubIfIdGroup; + /** When bPmapperEnable is TRUE, this field selects either DSCP or PCP to + derive sub interface ID. */ + GSW_PmapperMappingMode_t ePmapperMappingMode; + /** When bPmapperEnable is TRUE, P-mapper is used. API implementation need + take care of P-mapper allocation, and maintain the reference counter of + P-mapper used multiple times. */ + GSW_PMAPPER_t sPmapper; + + /** Port map define broadcast domain. + + \remarks + Each bit is one bridge port. Bridge port ID is index * 16 + bit offset. + For example, bit 1 of nBridgePortMap[1] is bridge port ID 17. */ + u16 nBridgePortMap[16]; + + /** Multicast IP table is searched if this field is FALSE and traffic is IP + multicast. */ + ltq_bool_t bMcDestIpLookupDisable; + /** Multicast IP table is searched if this field is TRUE and traffic is IP + multicast. */ + ltq_bool_t bMcSrcIpLookupEnable; + + /** Default is FALSE. Packet is treated as "unknown" if it's not + broadcast/multicast packet. */ + ltq_bool_t bDestMacLookupDisable; + + /** Default is FALSE. Source MAC address is learned. */ + ltq_bool_t bSrcMacLearningDisable; + + /** If this field is TRUE and MAC address which is already learned in another + bridge port appears on this bridge port, port locking violation is + detected. */ + ltq_bool_t bMacSpoofingDetectEnable; + + /** If this field is TRUE and MAC address which is already learned in this + bridge port appears on another bridge port, port locking violation is + detected. */ + ltq_bool_t bPortLockEnable; + + /** Enable MAC learning limitation. */ + ltq_bool_t bMacLearningLimitEnable; + /** Max number of MAC can be learned from this bridge port. */ + u32 nMacLearningLimit; + + /** Get number of MAC address learned from this bridge port. */ + u32 nMacLearningCount; + + /** Enable ingress VLAN filter */ + ltq_bool_t bIngressVlanFilterEnable; + /** VLAN filter block of ingress traffic if + \ref GSW_BRIDGE_portConfig_t::bIngressVlanFilterEnable is TRUE. */ + u32 nIngressVlanFilterBlockId; + /** VLAN filter block size. This is optional. + If it is 0, the block size of nIngressVlanFilterBlockId will be used. + Otherwise, this field will be used. */ + u32 nIngressVlanFilterBlockSize; + /** For ingress traffic, bypass VLAN filter 1 at egress bridge port + processing. */ + ltq_bool_t bBypassEgressVlanFilter1; + /** Enable egress VLAN filter 1 */ + ltq_bool_t bEgressVlanFilter1Enable; + /** VLAN filter block 1 of egress traffic if + \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter1Enable is TRUE. */ + u32 nEgressVlanFilter1BlockId; + /** VLAN filter block 1 size. This is optional. + If it is 0, the block size of nEgressVlanFilter1BlockId will be used. + Otherwise, this field will be used. */ + u32 nEgressVlanFilter1BlockSize; + /** Enable egress VLAN filter 2 */ + ltq_bool_t bEgressVlanFilter2Enable; + /** VLAN filter block 2 of egress traffic if + \ref GSW_BRIDGE_portConfig_t::bEgressVlanFilter2Enable is TRUE. */ + u32 nEgressVlanFilter2BlockId; + /** VLAN filter block 2 size. This is optional. + If it is 0, the block size of nEgressVlanFilter2BlockId will be used. + Otherwise, this field will be used. */ + u32 nEgressVlanFilter2BlockSize; } GSW_BRIDGE_portConfig_t; /** \brief Bridge configuration mask. Used by \ref GSW_BRIDGE_config_t. */ -typedef enum -{ - /** Mask for \ref GSW_BRIDGE_config_t::bMacLearningLimitEnable - and \ref GSW_BRIDGE_config_t::nMacLearningLimit. */ - GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT = 0x00000001, - /** Mask for \ref GSW_BRIDGE_config_t::nMacLearningCount */ - GSW_BRIDGE_CONFIG_MASK_MAC_LEARNED_COUNT = 0x00000002, - /** Mask for \ref GSW_BRIDGE_config_t::nLearningDiscardEvent */ - GSW_BRIDGE_CONFIG_MASK_MAC_DISCARD_COUNT = 0x00000004, - /** Mask for \ref GSW_BRIDGE_config_t::bSubMeteringEnable and - \ref GSW_BRIDGE_config_t::nTrafficSubMeterId */ - GSW_BRIDGE_CONFIG_MASK_SUB_METER = 0x00000008, - /** Mask for \ref GSW_BRIDGE_config_t::eForwardBroadcast, - \ref GSW_BRIDGE_config_t::eForwardUnknownMulticastIp, - \ref GSW_BRIDGE_config_t::eForwardUnknownMulticastNonIp, - and \ref GSW_BRIDGE_config_t::eForwardUnknownUnicast. */ - GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE = 0x00000010, - - /** Enable all */ - GSW_BRIDGE_CONFIG_MASK_ALL = 0x7FFFFFFF, - /** Bypass any check for debug purpose */ - GSW_BRIDGE_CONFIG_MASK_FORCE = 0x80000000 +typedef enum { + /** Mask for \ref GSW_BRIDGE_config_t::bMacLearningLimitEnable + and \ref GSW_BRIDGE_config_t::nMacLearningLimit. */ + GSW_BRIDGE_CONFIG_MASK_MAC_LEARNING_LIMIT = 0x00000001, + /** Mask for \ref GSW_BRIDGE_config_t::nMacLearningCount */ + GSW_BRIDGE_CONFIG_MASK_MAC_LEARNED_COUNT = 0x00000002, + /** Mask for \ref GSW_BRIDGE_config_t::nLearningDiscardEvent */ + GSW_BRIDGE_CONFIG_MASK_MAC_DISCARD_COUNT = 0x00000004, + /** Mask for \ref GSW_BRIDGE_config_t::bSubMeteringEnable and + \ref GSW_BRIDGE_config_t::nTrafficSubMeterId */ + GSW_BRIDGE_CONFIG_MASK_SUB_METER = 0x00000008, + /** Mask for \ref GSW_BRIDGE_config_t::eForwardBroadcast, + \ref GSW_BRIDGE_config_t::eForwardUnknownMulticastIp, + \ref GSW_BRIDGE_config_t::eForwardUnknownMulticastNonIp, + and \ref GSW_BRIDGE_config_t::eForwardUnknownUnicast. */ + GSW_BRIDGE_CONFIG_MASK_FORWARDING_MODE = 0x00000010, + + /** Enable all */ + GSW_BRIDGE_CONFIG_MASK_ALL = 0x7FFFFFFF, + /** Bypass any check for debug purpose */ + GSW_BRIDGE_CONFIG_MASK_FORCE = 0x80000000 } GSW_BridgeConfigMask_t; /** \brief Bridge Allocation. Used by \ref GSW_BRIDGE_ALLOC and \ref GSW_BRIDGE_FREE. */ -typedef struct -{ - /** If \ref GSW_BRIDGE_ALLOC is successful, a valid ID will be returned - in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. - For \ref GSW_BRIDGE_FREE, this field should be valid ID returned by - \ref GSW_BRIDGE_ALLOC. ID 0 is special Bridge created during - initialization. */ - u32 nBridgeId; +typedef struct { + /** If \ref GSW_BRIDGE_ALLOC is successful, a valid ID will be returned + in this field. Otherwise, \ref INVALID_HANDLE is returned in this field. + For \ref GSW_BRIDGE_FREE, this field should be valid ID returned by + \ref GSW_BRIDGE_ALLOC. ID 0 is special Bridge created during + initialization. */ + u32 nBridgeId; } GSW_BRIDGE_alloc_t; /** \brief Bridge Configuration. Used by \ref GSW_BRIDGE_CONFIG_SET and \ref GSW_BRIDGE_CONFIG_GET. */ -typedef struct -{ - /** Bridge ID (FID) allocated by \ref GSW_BRIDGE_ALLOC. - - \remarks - If \ref GSW_BRIDGE_config_t::eMask has - \ref GSW_BridgeConfigMask_t::GSW_BRIDGE_CONFIG_MASK_FORCE, this field is - absolute index of Bridge (FID) in hardware for debug purpose, bypassing - any check. */ - u32 nBridgeId; - - /** Mask for updating/retrieving fields. */ - GSW_BridgeConfigMask_t eMask; - - /** Enable MAC learning limitation. */ - ltq_bool_t bMacLearningLimitEnable; - /** Max number of MAC can be learned in this bridge (all bridge ports). */ - u32 nMacLearningLimit; - - /** Get number of MAC address learned from this bridge port. */ - u32 nMacLearningCount; - - /** Number of learning discard event due to hardware resource not available. - - \remarks - This is discard event due to either MAC table full or Hash collision. - Discard due to nMacLearningCount reached is not counted in this field. */ - u32 nLearningDiscardEvent; - - /** Traffic metering on type of traffic (such as broadcast, multicast, - unknown unicast, etc) applies. */ - ltq_bool_t bSubMeteringEnable[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; - /** Meter for bridge process with specific type (such as broadcast, - multicast, unknown unicast, etc). Need pre-allocated for each type. */ - u32 nTrafficSubMeterId[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; - - /** Forwarding mode of broadcast traffic. */ - GSW_BridgeForwardMode_t eForwardBroadcast; - /** Forwarding mode of unknown multicast IP traffic. */ - GSW_BridgeForwardMode_t eForwardUnknownMulticastIp; - /** Forwarding mode of unknown multicast non-IP traffic. */ - GSW_BridgeForwardMode_t eForwardUnknownMulticastNonIp; - /** Forwarding mode of unknown unicast traffic. */ - GSW_BridgeForwardMode_t eForwardUnknownUnicast; +typedef struct { + /** Bridge ID (FID) allocated by \ref GSW_BRIDGE_ALLOC. + + \remarks + If \ref GSW_BRIDGE_config_t::eMask has + \ref GSW_BridgeConfigMask_t::GSW_BRIDGE_CONFIG_MASK_FORCE, this field is + absolute index of Bridge (FID) in hardware for debug purpose, bypassing + any check. */ + u32 nBridgeId; + + /** Mask for updating/retrieving fields. */ + GSW_BridgeConfigMask_t eMask; + + /** Enable MAC learning limitation. */ + ltq_bool_t bMacLearningLimitEnable; + /** Max number of MAC can be learned in this bridge (all bridge ports). */ + u32 nMacLearningLimit; + + /** Get number of MAC address learned from this bridge port. */ + u32 nMacLearningCount; + + /** Number of learning discard event due to hardware resource not available. + + \remarks + This is discard event due to either MAC table full or Hash collision. + Discard due to nMacLearningCount reached is not counted in this field. */ + u32 nLearningDiscardEvent; + + /** Traffic metering on type of traffic (such as broadcast, multicast, + unknown unicast, etc) applies. */ + ltq_bool_t bSubMeteringEnable[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; + /** Meter for bridge process with specific type (such as broadcast, + multicast, unknown unicast, etc). Need pre-allocated for each type. */ + u32 nTrafficSubMeterId[GSW_BRIDGE_PORT_EGRESS_METER_MAX]; + + /** Forwarding mode of broadcast traffic. */ + GSW_BridgeForwardMode_t eForwardBroadcast; + /** Forwarding mode of unknown multicast IP traffic. */ + GSW_BridgeForwardMode_t eForwardUnknownMulticastIp; + /** Forwarding mode of unknown multicast non-IP traffic. */ + GSW_BridgeForwardMode_t eForwardUnknownMulticastNonIp; + /** Forwarding mode of unknown unicast traffic. */ + GSW_BridgeForwardMode_t eForwardUnknownUnicast; } GSW_BRIDGE_config_t; /** \brief Logical port mode. Used by \ref GSW_CTP_portAssignment_t. */ -typedef enum -{ - /** WLAN with 8-bit station ID */ - GSW_LOGICAL_PORT_8BIT_WLAN = 0, - /** WLAN with 9-bit station ID */ - GSW_LOGICAL_PORT_9BIT_WLAN = 1, - /** GPON OMCI context */ - GSW_LOGICAL_PORT_GPON = 2, - /** EPON context */ - GSW_LOGICAL_PORT_EPON = 3, - /** G.INT context */ - GSW_LOGICAL_PORT_GINT = 4, - /** Others (sub interface ID is 0 by default) */ - GSW_LOGICAL_PORT_OTHER = 0xFF, +typedef enum { + /** WLAN with 8-bit station ID */ + GSW_LOGICAL_PORT_8BIT_WLAN = 0, + /** WLAN with 9-bit station ID */ + GSW_LOGICAL_PORT_9BIT_WLAN = 1, + /** GPON OMCI context */ + GSW_LOGICAL_PORT_GPON = 2, + /** EPON context */ + GSW_LOGICAL_PORT_EPON = 3, + /** G.INT context */ + GSW_LOGICAL_PORT_GINT = 4, + /** Others (sub interface ID is 0 by default) */ + GSW_LOGICAL_PORT_OTHER = 0xFF, } GSW_LogicalPortMode_t; /** \brief CTP Port Assignment/association with logical port. Used by \ref GSW_CTP_PORT_ASSIGNMENT_ALLOC, \ref GSW_CTP_PORT_ASSIGNMENT_SET and \ref GSW_CTP_PORT_ASSIGNMENT_GET. */ -typedef struct -{ - /** Logical Port Id. The valid range is hardware dependent. */ - u32 nLogicalPortId; - - /** First CTP Port ID mapped to above logical port ID. - - \remarks - For \ref GSW_CTP_PORT_ASSIGNMENT_ALLOC, this is output when CTP - allocation is successful. For other APIs, this is input. */ - u32 nFirstCtpPortId; - /** Total number of CTP Ports mapped above logical port ID. */ - u32 nNumberOfCtpPort; - - /** Logical port mode to define sub interface ID format. */ - GSW_LogicalPortMode_t eMode; - - /** Bridge ID (FID) - - \remarks - For \ref GSW_CTP_PORT_ASSIGNMENT_ALLOC, this is input. Each CTP allocated - is mapped to Bridge Port given by this field. The Bridge Port will be - configured to use first CTP - (\ref GSW_CTP_portAssignment_t::nFirstCtpPortId) as egress CTP. - For other APIs, this is ignored. */ - u32 nBridgePortId; +typedef struct { + /** Logical Port Id. The valid range is hardware dependent. */ + u32 nLogicalPortId; + + /** First CTP Port ID mapped to above logical port ID. + + \remarks + For \ref GSW_CTP_PORT_ASSIGNMENT_ALLOC, this is output when CTP + allocation is successful. For other APIs, this is input. */ + u32 nFirstCtpPortId; + /** Total number of CTP Ports mapped above logical port ID. */ + u32 nNumberOfCtpPort; + + /** Logical port mode to define sub interface ID format. */ + GSW_LogicalPortMode_t eMode; + + /** Bridge ID (FID) + + \remarks + For \ref GSW_CTP_PORT_ASSIGNMENT_ALLOC, this is input. Each CTP allocated + is mapped to Bridge Port given by this field. The Bridge Port will be + configured to use first CTP + (\ref GSW_CTP_portAssignment_t::nFirstCtpPortId) as egress CTP. + For other APIs, this is ignored. */ + u32 nBridgePortId; } GSW_CTP_portAssignment_t; /** \brief Color Marking Table. @@ -4236,23 +4248,22 @@ typedef struct \ref GSW_QOS_COLOR_MARKING_TABLE_SET to initialize the table before color marking happens. \ref GSW_QOS_COLOR_MARKING_TABLE_GET is used to get the marking table, mainly for debug purpose. */ -typedef struct -{ - /** Mode of color marking. */ - GSW_ColorMarkingMode_t eMode; - - /** If eMode is GSW_REMARKING_DSCP_AF, index stands for 6-bit DSCP value. - If eMode is one of GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, - GSW_REMARKING_PCP_6P2D and GSW_REMARKING_PCP_5P3D, index 0-7 is - 3-bit PCP value with DEI is 0, and index 8-15 is 3-bit PCP value with - DEI is 1. Ignored in other modes. */ - u8 nPriority[64]; - /** If eMode is GSW_REMARKING_DSCP_AF, index stands for 6-bit DSCP value. - If eMode is one of GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, - GSW_REMARKING_PCP_6P2D and GSW_REMARKING_PCP_5P3D, index 0-7 is 3-bit - PCP value with DEI is 0, and index 8-15 is 3-bit PCP value with DEI is 1. - Ignored in other modes. */ - GSW_QoS_DropPrecedence_t nColor[64]; +typedef struct { + /** Mode of color marking. */ + GSW_ColorMarkingMode_t eMode; + + /** If eMode is GSW_REMARKING_DSCP_AF, index stands for 6-bit DSCP value. + If eMode is one of GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, + GSW_REMARKING_PCP_6P2D and GSW_REMARKING_PCP_5P3D, index 0-7 is + 3-bit PCP value with DEI is 0, and index 8-15 is 3-bit PCP value with + DEI is 1. Ignored in other modes. */ + u8 nPriority[64]; + /** If eMode is GSW_REMARKING_DSCP_AF, index stands for 6-bit DSCP value. + If eMode is one of GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, + GSW_REMARKING_PCP_6P2D and GSW_REMARKING_PCP_5P3D, index 0-7 is 3-bit + PCP value with DEI is 0, and index 8-15 is 3-bit PCP value with DEI is 1. + Ignored in other modes. */ + GSW_QoS_DropPrecedence_t nColor[64]; } GSW_QoS_colorMarkingEntry_t; /** \brief Color Remarking Table. @@ -4260,55 +4271,51 @@ typedef struct \ref GSW_QOS_COLOR_REMARKING_TABLE_SET to initialize the table before color remarking happens. \ref GSW_QOS_COLOR_REMARKING_TABLE_GET is used to get the remarking table, mainly for debug purpose. */ -typedef struct -{ - /** Mode of color remarking. */ - GSW_ColorRemarkingMode_t eMode; - - /** Index stands for color and priority. Index 0-7 is green color with - priority (traffic class) 0-7. Index 8-15 is yellow color with priority - (traffic class) 0-7. Value is DSCP if eMode is GSW_REMARKING_DSCP_AF. - Value bit 0 is DEI and bit 1-3 is PCP if eMode is one of - GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, GSW_REMARKING_PCP_6P2D - and GSW_REMARKING_PCP_5P3D. Value is ignored for other mode. */ - u8 nVal[16]; +typedef struct { + /** Mode of color remarking. */ + GSW_ColorRemarkingMode_t eMode; + + /** Index stands for color and priority. Index 0-7 is green color with + priority (traffic class) 0-7. Index 8-15 is yellow color with priority + (traffic class) 0-7. Value is DSCP if eMode is GSW_REMARKING_DSCP_AF. + Value bit 0 is DEI and bit 1-3 is PCP if eMode is one of + GSW_REMARKING_PCP_8P0D, GSW_REMARKING_PCP_7P1D, GSW_REMARKING_PCP_6P2D + and GSW_REMARKING_PCP_5P3D. Value is ignored for other mode. */ + u8 nVal[16]; } GSW_QoS_colorRemarkingEntry_t; /** \brief DSCP to PCP Mapping. Used by \ref GSW_DSCP2PCP_MAP_GET. */ -typedef struct -{ - /** Index of entry in mapping table. */ - u32 nIndex; - - /** The index of array stands for DSCP value. Each byte of the array is 3-bit - PCP value. */ - u8 nMap[64]; +typedef struct { + /** Index of entry in mapping table. */ + u32 nIndex; + + /** The index of array stands for DSCP value. Each byte of the array is 3-bit + PCP value. */ + u8 nMap[64]; } GSW_DSCP2PCP_map_t; /** \brief MAC Address Filter Type. Used by \ref GSW_MACFILTER_default_t */ -typedef enum -{ - /** Source MAC Address Filter */ - GSW_MACFILTERTYPE_SRC = 0, - /** Destination MAC Address Filter */ - GSW_MACFILTERTYPE_DEST = 1 +typedef enum { + /** Source MAC Address Filter */ + GSW_MACFILTERTYPE_SRC = 0, + /** Destination MAC Address Filter */ + GSW_MACFILTERTYPE_DEST = 1 } GSW_MacFilterType_t; /** \brief Default MAC Address Filter. Used by \ref GSW_DEFAUL_MAC_FILTER_SET and \ref GSW_DEFAUL_MAC_FILTER_GET */ -typedef struct -{ - /** MAC Filter Type */ - GSW_MacFilterType_t eType; +typedef struct { + /** MAC Filter Type */ + GSW_MacFilterType_t eType; - /** Destination bridge port map. For GSWIP-3.1 only. + /** Destination bridge port map. For GSWIP-3.1 only. - \remarks - Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), - only index 0-7 is valid. */ - u16 nPortmap[16]; + \remarks + Each bit stands for 1 bridge port. For Falcon-Mx (GSWIP-3.1 integrated), + only index 0-7 is valid. */ + u16 nPortmap[16]; } GSW_MACFILTER_default_t; /*@}*/ /* GSW_IOCTL_GSWIP31 */ @@ -6620,7 +6627,7 @@ typedef struct \brief Sets TFLOW counter mode type. \param GSW_TflowCmodeConf_t Pointer to a pre-allocated - \ref GSW_RMON_clear_t structure. + \ref GSW_RMON_clear_t structure. \return Return value as follows: - GSW_statusOk: if successful @@ -6632,7 +6639,7 @@ typedef struct \brief Sets TFLOW counter mode type. \param GSW_TflowCmodeConf_t Pointer to a pre-allocated - \ref GSW_RMON_clear_t structure. + \ref GSW_RMON_clear_t structure. \return Return value as follows: - GSW_statusOk: if successful @@ -6751,7 +6758,7 @@ typedef struct - GSW_statusOk: if successful - An error code in case an error occurs */ -#define GSW_PMAC_BM_CFG_SET _IOW(GSW_MAGIC, 0x04, GSW_PMAC_BM_Cfg_t) +#define GSW_PMAC_BM_CFG_SET _IOW(GSW_PMAC_MAGIC, 0x04, GSW_PMAC_BM_Cfg_t) /** \brief Queries the Backpressure Mapping Table for PMAC. @@ -6883,23 +6890,6 @@ typedef struct */ #define GSW_PMAC_GLBL_CFG_GET _IOR(GSW_PMAC_MAGIC, 0x03, GSW_PMAC_Glbl_Cfg_t) -#if 0 -/** - \brief Reads the Egresss Counters for given PMAC port. - It is used to read egress statistics counters providing checksum-error-ed packets and bytes on given PMAC port. - - \param GSW_PMAC_Eg_cnt_t Pointer to a - Egress counters of a given PMAC Port \ref GSW_PMAC_Eg_Cnt_t. - - \remarks The function returns an error code in case an error occurs. - The error code is described in \ref GSW_return_t. - - \return Return value as follows: - - GSW_statusOk: if successful - - An error code in case an error occurs -*/ -//#define GSW_PMAC_EG_COUNT_GET _IOWR(GSW_MAGIC, 0x9C, GSW_PMAC_Eg_Cnt_t) -#endif /*@}*/ /* GSW_IOCTL_PMAC */ @@ -7431,4 +7421,39 @@ typedef struct */ #define GSW_LMAC_CFG _IOWR(GSW_DEBUG_MAGIC, 0x12, GSW_MAC_cfg_t) +/** + \brief MACSEC Cfg Commands to Read and write operation + GSW_MACSEC_CFG. + \remarks The function returns an error code in case an error occurs. + The error code is described in \ref GSW_return_t. + \return Return value as follows: + - GSW_statusOk: if successful + - An error code in case an error occurs +*/ +#define GSW_MACSEC_CFG _IOWR(GSW_DEBUG_MAGIC, 0x13, GSW_MAC_cfg_t) +/** + \brief DUMP MEM operation + GSW_DUMP_MEM. + \remarks The function returns an error code in case an error occurs. + The error code is described in \ref GSW_return_t. + \return Return value as follows: + - GSW_statusOk: if successful + - An error code in case an error occurs +*/ +#define GSW_DUMP_MEM _IOWR(GSW_DEBUG_MAGIC, 0x14, GSW_table_t) + +#define GSW_DEBUG_PRINT_PCEIRQ_LIST _IO(GSW_DEBUG_MAGIC, 0x15) +#define GSW_DEBUG_RMON_PORT_GET _IOWR(GSW_DEBUG_MAGIC, 0x16, GSW_Debug_RMON_Port_cnt_t) + +/** + \brief Following are for GSWIP IRQ operation + + \param GSW_Irq_Op_t Pointer to \ref GSW_Irq_Op_t. +*/ + +#define GSW_IRQ_REGISTER _IOWR(GSW_IRQ_MAGIC, 0x01, GSW_Irq_Op_t) +#define GSW_IRQ_UNREGISTER _IOWR(GSW_IRQ_MAGIC, 0x02, GSW_Irq_Op_t) +#define GSW_IRQ_ENABLE _IOWR(GSW_IRQ_MAGIC, 0x03, GSW_Irq_Op_t) +#define GSW_IRQ_DISBALE _IOWR(GSW_IRQ_MAGIC, 0x04, GSW_Irq_Op_t) + #endif /* _LANTIQ_GSW_H_ */ diff --git a/include/net/switch_api/lantiq_gsw_api.h b/include/net/switch_api/lantiq_gsw_api.h index 78c9732fa059d657032533c4d8277d4a0b803118..a51f510c5d7280d7f963b03343cecf95e3034021 100644 --- a/include/net/switch_api/lantiq_gsw_api.h +++ b/include/net/switch_api/lantiq_gsw_api.h @@ -9,7 +9,7 @@ this software module. ******************************************************************************/ - + #ifndef _LTQ_GSW_KERNEL_API_H_ #define _LTQ_GSW_KERNEL_API_H_ @@ -17,6 +17,10 @@ #include "lantiq_gsw.h" #include "lantiq_gsw_flow.h" #include "lantiq_gsw_routing.h" +#include "gsw_irq.h" +#include "gsw_tbl_rw.h" + + /* Group definitions for Doxygen */ /** \defgroup ETHSW_KERNELAPI Ethernet Switch Linux Kernel Interface This chapter describes the entire interface to access and diff --git a/include/net/switch_api/lantiq_gsw_flow.h b/include/net/switch_api/lantiq_gsw_flow.h index d86c0e7db4836d908adab0c57c9227c5349972ef..eef7c2b3b3f0490431610f7d97df012b67311995 100644 --- a/include/net/switch_api/lantiq_gsw_flow.h +++ b/include/net/switch_api/lantiq_gsw_flow.h @@ -53,13 +53,12 @@ /** \brief Register access parameter to directly read or write switch internal registers. Used by \ref GSW_REGISTER_SET and \ref GSW_REGISTER_GET. */ -typedef struct -{ - /** Register Address Offset for read or write access. */ - u16 nRegAddr; - /** Value to write to or read from 'nRegAddr'. */ - u16 nData; -}GSW_register_t; +typedef struct { + /** Register Address Offset for read or write access. */ + u16 nRegAddr; + /** Value to write to or read from 'nRegAddr'. */ + u16 nData; +} GSW_register_t; /*@}*/ /* GSW_IOCTL_DEBUG */ @@ -68,37 +67,35 @@ typedef struct /** \brief Interrupt Source Selector. Used by \ref GSW_irq_t. */ -typedef enum -{ - /** Wake-on-LAN Interrupt. The configured packet flow will trigger WoL interrupt. - The parameter 'nPortId' specifies the relative MAC port. */ - GSW_IRQ_WOL = 0, - /** Port Limit Alert Interrupt. This interrupt is asserted when the number - of learned MAC addresses exceeds the configured limit for - the ingress port. - The parameter 'nPortId' specifies the relative MAC port. */ - GSW_IRQ_LIMIT_ALERT = 1, - /** Port Lock Alert Interrupt. - This interrupt is asserted when a source MAC address is learned on a - locked port and is received on another port. - The parameter 'nPortId' specifies the relative MAC port. */ - GSW_IRQ_LOCK_ALERT = 2 -}GSW_irqSrc_t; +typedef enum { + /** Wake-on-LAN Interrupt. The configured packet flow will trigger WoL interrupt. + The parameter 'nPortId' specifies the relative MAC port. */ + GSW_IRQ_WOL = 0, + /** Port Limit Alert Interrupt. This interrupt is asserted when the number + of learned MAC addresses exceeds the configured limit for + the ingress port. + The parameter 'nPortId' specifies the relative MAC port. */ + GSW_IRQ_LIMIT_ALERT = 1, + /** Port Lock Alert Interrupt. + This interrupt is asserted when a source MAC address is learned on a + locked port and is received on another port. + The parameter 'nPortId' specifies the relative MAC port. */ + GSW_IRQ_LOCK_ALERT = 2 +} GSW_irqSrc_t; /** \brief Interrupt bits. Depending on the hardware device type, not all interrupts might be available. Used by \ref GSW_IRQ_MASK_GET, \ref GSW_IRQ_MASK_SET, \ref GSW_IRQ_GET and \ref GSW_IRQ_STATUS_CLEAR. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware dependent. - An error code is delivered if the selected port is not - available. This port parameter is needed for some interrupts - that are specified by 'nIrqSrc'. For all other interrupts, this - parameter is "don't care". */ - u32 nPortId; - /** Interrupt Source Type. */ - GSW_irqSrc_t eIrqSrc; -}GSW_irq_t; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware dependent. + An error code is delivered if the selected port is not + available. This port parameter is needed for some interrupts + that are specified by 'nIrqSrc'. For all other interrupts, this + parameter is "don't care". */ + u32 nPortId; + /** Interrupt Source Type. */ + GSW_irqSrc_t eIrqSrc; +} GSW_irq_t; /*@}*/ /* GSW_IOCTL_IRQ */ @@ -107,830 +104,810 @@ typedef struct /** \brief Rule selection for IPv4/IPv6. Used by \ref GSW_PCE_pattern_t. */ -typedef enum -{ - /** Rule Pattern for IP selection disabled. */ - GSW_PCE_IP_DISABLED = 0, - /** Rule Pattern for IPv4. */ - GSW_PCE_IP_V4 = 1, - /** Rule Pattern for IPv6. */ - GSW_PCE_IP_V6 = 2 -}GSW_PCE_IP_t; +typedef enum { + /** Rule Pattern for IP selection disabled. */ + GSW_PCE_IP_DISABLED = 0, + /** Rule Pattern for IPv4. */ + GSW_PCE_IP_V4 = 1, + /** Rule Pattern for IPv6. */ + GSW_PCE_IP_V6 = 2 +} GSW_PCE_IP_t; /** \brief Select Mode of Sub-Interface ID Field. Used by \ref GSW_PCE_pattern_t. */ -typedef enum -{ - /** Sub Interface ID as defined by GSWIP-3.0. */ - GSW_PCE_SUBIFID_TYPE_SUBIFID = 0, - /** Sub Interface ID group as defined by GSWIP-3.1. */ - GSW_PCE_SUBIFID_TYPE_GROUP = 1, - /** Bridge Port ID as defined by GSWIP-3.1. */ - GSW_PCE_SUBIFID_TYPE_BRIDGEPORT = 2 +typedef enum { + /** Sub Interface ID as defined by GSWIP-3.0. */ + GSW_PCE_SUBIFID_TYPE_SUBIFID = 0, + /** Sub Interface ID group as defined by GSWIP-3.1. */ + GSW_PCE_SUBIFID_TYPE_GROUP = 1, + /** Bridge Port ID as defined by GSWIP-3.1. */ + GSW_PCE_SUBIFID_TYPE_BRIDGEPORT = 2 } GSW_PCE_SUBIFID_TYPE_t; /** \brief Packet Classification Engine Pattern Configuration. GSWIP-3.0 has additional patterns such as Inner IP, Inner DSCP, Inner Protocol, Exclude Mode etc. Used by \ref GSW_PCE_rule_t. */ -typedef struct -{ - /** PCE Rule Index (Upto 512 rules supported in GSWIP-3.0, whereas 64 rules supported in GSWIP-2.x) */ - int nIndex; - - /** Index is used (enabled) or set to unused (disabled) */ - ltq_bool_t bEnable; - - /** Port ID used for ingress packet classification */ - ltq_bool_t bPortIdEnable; - /** Port ID value of incoming packets used for classification */ - u8 nPortId; - /** Exclude Port Id Value - When set exclusion of specified nPortId takes effect. Available for GSWIP-3.0 only */ - ltq_bool_t bPortId_Exclude; - - /** Select mode of sub-interface ID field */ - GSW_PCE_SUBIFID_TYPE_t eSubIfIdType; - /** Incoming Sub-Interface ID Enable - used for GSWIP-3.0 only */ - ltq_bool_t bSubIfIdEnable; - /** Incoming Sub-Interface ID value - used for GSWIP-3.0 only */ - u16 nSubIfId; - /** Exclude of specified Sub-Interface Id value in nSubIfId - used for GSWIP-3.0 only */ - ltq_bool_t bSubIfId_Exclude; - - /** DSCP value used (Outer for GSWIP-3.0) */ - ltq_bool_t bDSCP_Enable; - /** DSCP value (Outer for GSWIP-3.0) */ - u8 nDSCP; - /** Exclude (Outer) DSCP value used for GSWIP-3.0 only */ - ltq_bool_t bDSCP_Exclude; - - /** Inner DSCP value used for GSWIP-3.0 only */ - ltq_bool_t bInner_DSCP_Enable; - /** Inner DSCP value for GSWIP-3.0 only */ - u8 nInnerDSCP; - /** Exclude of Inner DSCP (nInnerDSCP) value used for GSWIP-3.0 only */ - ltq_bool_t bInnerDSCP_Exclude; - - /** CTAG VLAN PCP n DEI value used */ - ltq_bool_t bPCP_Enable; - /** CTAG VLAN PCP n DEI value */ - u8 nPCP; - /* Exclude CTAG value used for GSWIP-3.0 only */ +typedef struct { + /** PCE Rule Index (Upto 512 rules supported in GSWIP-3.0, whereas 64 rules supported in GSWIP-2.x) */ + int nIndex; + + /** Index is used (enabled) or set to unused (disabled) */ + ltq_bool_t bEnable; + + /** Port ID used for ingress packet classification */ + ltq_bool_t bPortIdEnable; + /** Port ID value of incoming packets used for classification */ + u8 nPortId; + /** Exclude Port Id Value - When set exclusion of specified nPortId takes effect. Available for GSWIP-3.0 only */ + ltq_bool_t bPortId_Exclude; + + /** Select mode of sub-interface ID field */ + GSW_PCE_SUBIFID_TYPE_t eSubIfIdType; + /** Incoming Sub-Interface ID Enable - used for GSWIP-3.0 only */ + ltq_bool_t bSubIfIdEnable; + /** Incoming Sub-Interface ID value - used for GSWIP-3.0 only */ + u16 nSubIfId; + /** Exclude of specified Sub-Interface Id value in nSubIfId - used for GSWIP-3.0 only */ + ltq_bool_t bSubIfId_Exclude; + + /** DSCP value used (Outer for GSWIP-3.0) */ + ltq_bool_t bDSCP_Enable; + /** DSCP value (Outer for GSWIP-3.0) */ + u8 nDSCP; + /** Exclude (Outer) DSCP value used for GSWIP-3.0 only */ + ltq_bool_t bDSCP_Exclude; + + /** Inner DSCP value used for GSWIP-3.0 only */ + ltq_bool_t bInner_DSCP_Enable; + /** Inner DSCP value for GSWIP-3.0 only */ + u8 nInnerDSCP; + /** Exclude of Inner DSCP (nInnerDSCP) value used for GSWIP-3.0 only */ + ltq_bool_t bInnerDSCP_Exclude; + + /** CTAG VLAN PCP n DEI value used */ + ltq_bool_t bPCP_Enable; + /** CTAG VLAN PCP n DEI value */ + u8 nPCP; + /* Exclude CTAG value used for GSWIP-3.0 only */ // ltq_bool_t bCTAG_Exclude; - /** Exclude CTAG PCP & DEI value used for GSWIP-3.0 only */ - ltq_bool_t bCTAG_PCP_DEI_Exclude; - - /** STAG VLAN PCP/DEI value used */ - ltq_bool_t bSTAG_PCP_DEI_Enable; - /** STAG VLAN PCP value */ - u8 nSTAG_PCP_DEI; - /* Exclude STAG value used for GSWIP-3.0 only */ + /** Exclude CTAG PCP & DEI value used for GSWIP-3.0 only */ + ltq_bool_t bCTAG_PCP_DEI_Exclude; + + /** STAG VLAN PCP/DEI value used */ + ltq_bool_t bSTAG_PCP_DEI_Enable; + /** STAG VLAN PCP value */ + u8 nSTAG_PCP_DEI; + /* Exclude STAG value used for GSWIP-3.0 only */ // ltq_bool_t bSTAG_Exclude; - /** Exclude STAG PCP & DEI value used for GSWIP-3.0 only */ - ltq_bool_t bSTAG_PCP_DEI_Exclude; - - /** Packet length used for classification */ - ltq_bool_t bPktLngEnable; - /** Packet length in bytes */ - u16 nPktLng; - /** Packet length Range (from nPktLng to nPktLngRange) */ - u16 nPktLngRange; - /** Exclude of Packet Length or range value used for GSWIP-3.0 only */ - ltq_bool_t bPktLng_Exclude; - - /** Destination MAC address used */ - ltq_bool_t bMAC_DstEnable; - /** Destination MAC address */ - u8 nMAC_Dst[6]; - /** Destination MAC address nibble mask. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u16 nMAC_DstMask; - /** Exclude Destination MAC Address used for GSWIP-3.0 only */ - ltq_bool_t bDstMAC_Exclude; - - /** Source MAC address used */ - ltq_bool_t bMAC_SrcEnable; - /** Source MAC address */ - u8 nMAC_Src[6]; - /** Source MAC address nibble mask. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u16 nMAC_SrcMask; - /** Exclude Source MAC Address used for GSWIP-3.0 only */ - ltq_bool_t bSrcMAC_Exclude; - - /** MSB Application field used */ - ltq_bool_t bAppDataMSB_Enable; - /** MSB Application field. - The first 2 bytes of the packet content following the IP header - for TCP/UDP packets (source port field), or the first 2 bytes of packet content - following the Ethertype for non-IP packets. Any part of this - content can be masked-out by a programmable bit - mask 'nAppMaskRangeMSB'. */ - u16 nAppDataMSB; - /** MSB Application mask/range selection. - If set to LTQ_TRUE, the field 'nAppMaskRangeMSB' is used as a - range parameter, otherwise it is used as a nibble mask field. */ - ltq_bool_t bAppMaskRangeMSB_Select; - /** MSB Application mask/range. When used as a range parameter, - 1 bit represents 1 nibble mask of the 'nAppDataMSB' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u16 nAppMaskRangeMSB; - /** MSB Application Data Exclude - for GSWIP-3.0 only */ - ltq_bool_t bAppMSB_Exclude; - - /** LSB Application used */ - ltq_bool_t bAppDataLSB_Enable; - /** LSB Application field. - The following 2 bytes of the packet behind the 'nAppDataMSB' field. - This is the destination port field for TCP/UDP packets, - or byte 3 and byte 4 of the packet content following the Ethertype - for non-IP packets. Any part of this content can be masked-out - by a programmable bit mask 'nAppMaskRangeLSB'. */ - u16 nAppDataLSB; - /** LSB Application mask/range selection. - If set to LTQ_TRUE, the field 'nAppMaskRangeLSB' is used as - a range parameter, otherwise it is used as a nibble mask field. */ - ltq_bool_t bAppMaskRangeLSB_Select; - /** LSB Application mask/range. When used as a range parameter, - 1 bit represents 1 nibble mask of the 'nAppDataLSB' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u16 nAppMaskRangeLSB; - /** LSB Application Data Exclude - for GSWIP-3.0 only */ - ltq_bool_t bAppLSB_Exclude; - - /** Destination IP Selection (Outer for GSWIP-3.0). */ - GSW_PCE_IP_t eDstIP_Select; - /** Destination IP (Outer for GSWIP-3.0) */ - GSW_IP_t nDstIP; - /** Destination IP Nibble Mask. - 1 bit represents 1 nibble mask of the 'nDstIP' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u32 nDstIP_Mask; - /** Exclude Destination IP Value - used for GSWIP-3.0 only */ - ltq_bool_t bDstIP_Exclude; - - /** Inner Destination IP Selection - for GSWIP-3.0 only. */ - GSW_PCE_IP_t eInnerDstIP_Select; - /** Inner Destination IP - for GSWIP-3.0 only.*/ - GSW_IP_t nInnerDstIP; - /** Inner Destination IP Nibble Mask - for GSWIP-3.0 only. - 1 bit represents 1 nibble mask of the 'nInnerDstIP' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u32 nInnerDstIP_Mask; - /** Exclude Inner Destination IP Value - used for GSWIP-3.0 only */ - ltq_bool_t bInnerDstIP_Exclude; - - /** Source IP Selection (Outer for GSWIP-3.0). */ - GSW_PCE_IP_t eSrcIP_Select; - /** Source IP (Outer for GSWIP-3.0) */ - GSW_IP_t nSrcIP; - /** Source IP Nibble Mask (Outer for GSWIP-3.0). - 1 bit represents 1 nibble mask of the 'nSrcIP' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u32 nSrcIP_Mask; - /** Exclude Source IP Value - used for GSWIP-3.0 only */ - ltq_bool_t bSrcIP_Exclude; - - /** Inner Source IP Selection - for GSWIP-3.0 only. */ - GSW_PCE_IP_t eInnerSrcIP_Select; - /** Inner Source IP - for GSWIP-3.0 only*/ - GSW_IP_t nInnerSrcIP; - /** Inner Src IP Nibble Mask - for GSWIP-3.0 only. - 1 bit represents 1 nibble mask of the 'nInnerSrcIP' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u32 nInnerSrcIP_Mask; - /** Exclude Inner Source IP Value - used for GSWIP-3.0 only */ - ltq_bool_t bInnerSrcIP_Exclude; - - /** Ethertype used. */ - ltq_bool_t bEtherTypeEnable; - /** Ethertype */ - u16 nEtherType; - /** Ethertype Mask. - 1 bit represents 1 nibble mask of the 'nEtherType' field. - Please clear the bits of the nibbles that are not marked out and set all other bits. - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u16 nEtherTypeMask; - /** Exclude for Ether Type Value - used for GSWIP-3.0 only. */ - ltq_bool_t bEtherType_Exclude; - - /** IP protocol used */ - ltq_bool_t bProtocolEnable; - /** IP protocol Value */ - u8 nProtocol; - /** IP protocol Mask. - 1 bit represents 1 nibble mask of the 'nProtocol' field. - Please clear the bits of the nibbles that are not marked out and set all other bits i.e. a set bit 1 indicates that bit is masked out (not compared). - The LSB bit represents the lowest data nibble, the next bit the next nibble, - and so on. */ - u8 nProtocolMask; - /** Exclude for IP Protocol Value - used for GSWIP-3.0 only. */ - ltq_bool_t bProtocol_Exclude; - - /** Inner IP protocol used - for GSWIP-3.0 only. */ - ltq_bool_t bInnerProtocolEnable; - /** Inner IP protocol Value - for GSWIP-3.0 only. */ - u8 nInnerProtocol; - /** Inner IP protocol Bit Mask - for GSWIP-3.0 only. */ - u8 nInnerProtocolMask; - /** Exclude for Inner IP Protocol Value - used for GSWIP-3.0 only. */ - ltq_bool_t bInnerProtocol_Exclude; - - /** PPPoE used. */ - ltq_bool_t bSessionIdEnable; - /** PPPoE Session Id */ - u16 nSessionId; - /** Exclude for PPPoE Session Value - used for GSWIP-3.0 only. */ - ltq_bool_t bSessionId_Exclude; - - /** PPP Protocol used - used for GSWIP-3.0 only */ - ltq_bool_t bPPP_ProtocolEnable; - /** PPP Protocol Value - used for GSWIP-3.0 only*/ - u16 nPPP_Protocol; - /** PPP protocol Bit Mask (Positional bit 1 signifies masking of corresponding bit value in nPPP_Protocol) - for GSWIP-3.0 only. */ - u16 nPPP_ProtocolMask; - /** Exclude for PPP Protocol Value - used for GSWIP-3.0 only. */ - ltq_bool_t bPPP_Protocol_Exclude; - - /** VLAN ID (CVID) used. - - \remarks - CVID is inner VLAN as defined in GSWIP-3.1 */ - ltq_bool_t bVid; - /** VLAN ID (CVID) */ - u16 nVid; - /** VID mask/range selection. - If set to 1, the field 'nVidRange' is used as - a range parameter, otherwise it is used as a mask field. - - \remarks - This must be range in GSWIP-3.1 */ - ltq_bool_t bVidRange_Select; - /** VLAN ID Range (CVID). Gets used as mask to nVid in case bVidRange_Select is set to 0 */ - u16 nVidRange; - /** Exclude for VLAN Id (CVLAN) - used for GSWIP-3.0 only. */ - ltq_bool_t bVid_Exclude; - /** If this field is TRUE, use original VLAN ID as key even it's modified in - any stage before flow table process. Used for GSWIP-3.1 only. */ - ltq_bool_t bVid_Original; - - /** STAG VLAN ID used. - - \remarks - SLAN is outer VLAN as defined GSWIP-3.1 */ - ltq_bool_t bSLAN_Vid; - /** STAG VLAN ID */ - u16 nSLAN_Vid; - /** Exclude for SVLAN Id (SVLAN) - used for GSWIP-3.0 only. */ - ltq_bool_t bSLANVid_Exclude; - /** VID mask/range selection. - If set to 1, the field 'nVidRange' is used as - a range parameter, otherwise it is used as a mask field. - - \remarks - This must be range in GSWIP-3.1 */ - ltq_bool_t bSVidRange_Select; - /** VLAN ID Range for outer VLAN tag. Used for GSWIP-3.1 only. */ - u16 nOuterVidRange; - /** If this field is TRUE, use original VLAN ID as key even it's modified in - any stage before flow table process. Used for GSWIP-3.1 only. */ - ltq_bool_t bOuterVid_Original; - - /** Payload-1 used - for GSWIP-3.0 PAE only */ - ltq_bool_t bPayload1_SrcEnable; - /** Payload-1 Value (16-bits) - for GSWIP-3.0 PAE only */ - u16 nPayload1; - /** Payload1 mask/range selection. - If set to LTQ_TRUE, the field 'nPayload1' is used as - a range parameter, otherwise it is used as a bit mask field. */ - ltq_bool_t bPayload1MaskRange_Select; - /** Payload-1 Bit mask - for GSWIP-3.0 PAE only */ - u16 nPayload1_Mask; - /** Exclude Payload-1 used for GSWIP-3.0 PAE only */ - ltq_bool_t bPayload1_Exclude; - - /** Payload-2 used - for GSWIP-3.0 PAE only */ - ltq_bool_t bPayload2_SrcEnable; - /** Payload-2 Value (16-bits) - for GSWIP-3.0 PAE only */ - u16 nPayload2; - /** Payload2 mask/range selection. - If set to LTQ_TRUE, the field 'nPayload2' is used as - a range parameter, otherwise it is used as a bit mask field. */ - ltq_bool_t bPayload2MaskRange_Select; - /** Payload-2 Bit mask - for GSWIP-3.0 PAE only */ - u16 nPayload2_Mask; - /** Exclude Payload-2 used for GSWIP-3.0 PAE only */ - ltq_bool_t bPayload2_Exclude; - - /** Parser Flag LSW (Bit position 15 to 0) is used - for GSWIP 3.0 only */ - ltq_bool_t bParserFlagLSB_Enable; - /** Parser Flag LSW Value - each bit indicates specific parsed result */ - u16 nParserFlagLSB; - /** Corresponding LSW Parser Flag Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ - u16 nParserFlagLSB_Mask; - /** Exclude for Parser Flag LSW specified in nParserFlagLSB */ - ltq_bool_t bParserFlagLSB_Exclude; - - /** Parser Flag MSW (Bit 31 to 16) is used - for GSWIP 3.0 only */ - ltq_bool_t bParserFlagMSB_Enable; - /** Parser Flag MSW Value - each bit indicates specific parsed result */ - u16 nParserFlagMSB; - /** Corresponding Parser Flag MSW Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ - u16 nParserFlagMSB_Mask; - /** Exclude for Parser Flag MSW specified in nParserFlagMSB */ - ltq_bool_t bParserFlagMSB_Exclude; - - /** Parser Flag LSW (Bit position 47 to 32) is used - for GSWIP 3.1 only */ - ltq_bool_t bParserFlag1LSB_Enable; - /** Parser Flag LSW Value - each bit indicates specific parsed result */ - u16 nParserFlag1LSB; - /** Corresponding LSW Parser Flag Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ - u16 nParserFlag1LSB_Mask; - /** Exclude for Parser Flag LSW specified in nParserFlagLSB */ - ltq_bool_t bParserFlag1LSB_Exclude; - - /** Parser Flag MSW (Bit 63 to 48) is used - for GSWIP 3.1 only */ - ltq_bool_t bParserFlag1MSB_Enable; - /** Parser Flag MSW Value - each bit indicates specific parsed result */ - u16 nParserFlag1MSB; - /** Corresponding Parser Flag MSW Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ - u16 nParserFlag1MSB_Mask; - /** Exclude for Parser Flag MSW specified in nParserFlagMSB */ - ltq_bool_t bParserFlag1MSB_Exclude; - - /** nInsertionFlag is used. For GSWIP-3.1 only */ - ltq_bool_t bInsertionFlag_Enable; - /** Inserted packet by CPU to data path. For GSWIP-3.1 only */ - u16 nInsertionFlag; -}GSW_PCE_pattern_t; + /** Exclude STAG PCP & DEI value used for GSWIP-3.0 only */ + ltq_bool_t bSTAG_PCP_DEI_Exclude; + + /** Packet length used for classification */ + ltq_bool_t bPktLngEnable; + /** Packet length in bytes */ + u16 nPktLng; + /** Packet length Range (from nPktLng to nPktLngRange) */ + u16 nPktLngRange; + /** Exclude of Packet Length or range value used for GSWIP-3.0 only */ + ltq_bool_t bPktLng_Exclude; + + /** Destination MAC address used */ + ltq_bool_t bMAC_DstEnable; + /** Destination MAC address */ + u8 nMAC_Dst[6]; + /** Destination MAC address nibble mask. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u16 nMAC_DstMask; + /** Exclude Destination MAC Address used for GSWIP-3.0 only */ + ltq_bool_t bDstMAC_Exclude; + + /** Source MAC address used */ + ltq_bool_t bMAC_SrcEnable; + /** Source MAC address */ + u8 nMAC_Src[6]; + /** Source MAC address nibble mask. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u16 nMAC_SrcMask; + /** Exclude Source MAC Address used for GSWIP-3.0 only */ + ltq_bool_t bSrcMAC_Exclude; + + /** MSB Application field used */ + ltq_bool_t bAppDataMSB_Enable; + /** MSB Application field. + The first 2 bytes of the packet content following the IP header + for TCP/UDP packets (source port field), or the first 2 bytes of packet content + following the Ethertype for non-IP packets. Any part of this + content can be masked-out by a programmable bit + mask 'nAppMaskRangeMSB'. */ + u16 nAppDataMSB; + /** MSB Application mask/range selection. + If set to LTQ_TRUE, the field 'nAppMaskRangeMSB' is used as a + range parameter, otherwise it is used as a nibble mask field. */ + ltq_bool_t bAppMaskRangeMSB_Select; + /** MSB Application mask/range. When used as a range parameter, + 1 bit represents 1 nibble mask of the 'nAppDataMSB' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u16 nAppMaskRangeMSB; + /** MSB Application Data Exclude - for GSWIP-3.0 only */ + ltq_bool_t bAppMSB_Exclude; + + /** LSB Application used */ + ltq_bool_t bAppDataLSB_Enable; + /** LSB Application field. + The following 2 bytes of the packet behind the 'nAppDataMSB' field. + This is the destination port field for TCP/UDP packets, + or byte 3 and byte 4 of the packet content following the Ethertype + for non-IP packets. Any part of this content can be masked-out + by a programmable bit mask 'nAppMaskRangeLSB'. */ + u16 nAppDataLSB; + /** LSB Application mask/range selection. + If set to LTQ_TRUE, the field 'nAppMaskRangeLSB' is used as + a range parameter, otherwise it is used as a nibble mask field. */ + ltq_bool_t bAppMaskRangeLSB_Select; + /** LSB Application mask/range. When used as a range parameter, + 1 bit represents 1 nibble mask of the 'nAppDataLSB' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u16 nAppMaskRangeLSB; + /** LSB Application Data Exclude - for GSWIP-3.0 only */ + ltq_bool_t bAppLSB_Exclude; + + /** Destination IP Selection (Outer for GSWIP-3.0). */ + GSW_PCE_IP_t eDstIP_Select; + /** Destination IP (Outer for GSWIP-3.0) */ + GSW_IP_t nDstIP; + /** Destination IP Nibble Mask. + 1 bit represents 1 nibble mask of the 'nDstIP' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u32 nDstIP_Mask; + /** Exclude Destination IP Value - used for GSWIP-3.0 only */ + ltq_bool_t bDstIP_Exclude; + + /** Inner Destination IP Selection - for GSWIP-3.0 only. */ + GSW_PCE_IP_t eInnerDstIP_Select; + /** Inner Destination IP - for GSWIP-3.0 only.*/ + GSW_IP_t nInnerDstIP; + /** Inner Destination IP Nibble Mask - for GSWIP-3.0 only. + 1 bit represents 1 nibble mask of the 'nInnerDstIP' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u32 nInnerDstIP_Mask; + /** Exclude Inner Destination IP Value - used for GSWIP-3.0 only */ + ltq_bool_t bInnerDstIP_Exclude; + + /** Source IP Selection (Outer for GSWIP-3.0). */ + GSW_PCE_IP_t eSrcIP_Select; + /** Source IP (Outer for GSWIP-3.0) */ + GSW_IP_t nSrcIP; + /** Source IP Nibble Mask (Outer for GSWIP-3.0). + 1 bit represents 1 nibble mask of the 'nSrcIP' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u32 nSrcIP_Mask; + /** Exclude Source IP Value - used for GSWIP-3.0 only */ + ltq_bool_t bSrcIP_Exclude; + + /** Inner Source IP Selection - for GSWIP-3.0 only. */ + GSW_PCE_IP_t eInnerSrcIP_Select; + /** Inner Source IP - for GSWIP-3.0 only*/ + GSW_IP_t nInnerSrcIP; + /** Inner Src IP Nibble Mask - for GSWIP-3.0 only. + 1 bit represents 1 nibble mask of the 'nInnerSrcIP' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u32 nInnerSrcIP_Mask; + /** Exclude Inner Source IP Value - used for GSWIP-3.0 only */ + ltq_bool_t bInnerSrcIP_Exclude; + + /** Ethertype used. */ + ltq_bool_t bEtherTypeEnable; + /** Ethertype */ + u16 nEtherType; + /** Ethertype Mask. + 1 bit represents 1 nibble mask of the 'nEtherType' field. + Please clear the bits of the nibbles that are not marked out and set all other bits. + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u16 nEtherTypeMask; + /** Exclude for Ether Type Value - used for GSWIP-3.0 only. */ + ltq_bool_t bEtherType_Exclude; + + /** IP protocol used */ + ltq_bool_t bProtocolEnable; + /** IP protocol Value */ + u8 nProtocol; + /** IP protocol Mask. + 1 bit represents 1 nibble mask of the 'nProtocol' field. + Please clear the bits of the nibbles that are not marked out and set all other bits i.e. a set bit 1 indicates that bit is masked out (not compared). + The LSB bit represents the lowest data nibble, the next bit the next nibble, + and so on. */ + u8 nProtocolMask; + /** Exclude for IP Protocol Value - used for GSWIP-3.0 only. */ + ltq_bool_t bProtocol_Exclude; + + /** Inner IP protocol used - for GSWIP-3.0 only. */ + ltq_bool_t bInnerProtocolEnable; + /** Inner IP protocol Value - for GSWIP-3.0 only. */ + u8 nInnerProtocol; + /** Inner IP protocol Bit Mask - for GSWIP-3.0 only. */ + u8 nInnerProtocolMask; + /** Exclude for Inner IP Protocol Value - used for GSWIP-3.0 only. */ + ltq_bool_t bInnerProtocol_Exclude; + + /** PPPoE used. */ + ltq_bool_t bSessionIdEnable; + /** PPPoE Session Id */ + u16 nSessionId; + /** Exclude for PPPoE Session Value - used for GSWIP-3.0 only. */ + ltq_bool_t bSessionId_Exclude; + + /** PPP Protocol used - used for GSWIP-3.0 only */ + ltq_bool_t bPPP_ProtocolEnable; + /** PPP Protocol Value - used for GSWIP-3.0 only*/ + u16 nPPP_Protocol; + /** PPP protocol Bit Mask (Positional bit 1 signifies masking of corresponding bit value in nPPP_Protocol) - for GSWIP-3.0 only. */ + u16 nPPP_ProtocolMask; + /** Exclude for PPP Protocol Value - used for GSWIP-3.0 only. */ + ltq_bool_t bPPP_Protocol_Exclude; + + /** VLAN ID (CVID) used. + + \remarks + CVID is inner VLAN as defined in GSWIP-3.1 */ + ltq_bool_t bVid; + /** VLAN ID (CVID) */ + u16 nVid; + /** VID mask/range selection. + If set to 1, the field 'nVidRange' is used as + a range parameter, otherwise it is used as a mask field. + + \remarks + This must be range in GSWIP-3.1 */ + ltq_bool_t bVidRange_Select; + /** VLAN ID Range (CVID). Gets used as mask to nVid in case bVidRange_Select is set to 0 */ + u16 nVidRange; + /** Exclude for VLAN Id (CVLAN) - used for GSWIP-3.0 only. */ + ltq_bool_t bVid_Exclude; + /** If this field is TRUE, use original VLAN ID as key even it's modified in + any stage before flow table process. Used for GSWIP-3.1 only. */ + ltq_bool_t bVid_Original; + + /** STAG VLAN ID used. + + \remarks + SLAN is outer VLAN as defined GSWIP-3.1 */ + ltq_bool_t bSLAN_Vid; + /** STAG VLAN ID */ + u16 nSLAN_Vid; + /** Exclude for SVLAN Id (SVLAN) - used for GSWIP-3.0 only. */ + ltq_bool_t bSLANVid_Exclude; + /** VID mask/range selection. + If set to 1, the field 'nVidRange' is used as + a range parameter, otherwise it is used as a mask field. + + \remarks + This must be range in GSWIP-3.1 */ + ltq_bool_t bSVidRange_Select; + /** VLAN ID Range for outer VLAN tag. Used for GSWIP-3.1 only. */ + u16 nOuterVidRange; + /** If this field is TRUE, use original VLAN ID as key even it's modified in + any stage before flow table process. Used for GSWIP-3.1 only. */ + ltq_bool_t bOuterVid_Original; + + /** Payload-1 used - for GSWIP-3.0 PAE only */ + ltq_bool_t bPayload1_SrcEnable; + /** Payload-1 Value (16-bits) - for GSWIP-3.0 PAE only */ + u16 nPayload1; + /** Payload1 mask/range selection. + If set to LTQ_TRUE, the field 'nPayload1' is used as + a range parameter, otherwise it is used as a bit mask field. */ + ltq_bool_t bPayload1MaskRange_Select; + /** Payload-1 Bit mask - for GSWIP-3.0 PAE only */ + u16 nPayload1_Mask; + /** Exclude Payload-1 used for GSWIP-3.0 PAE only */ + ltq_bool_t bPayload1_Exclude; + + /** Payload-2 used - for GSWIP-3.0 PAE only */ + ltq_bool_t bPayload2_SrcEnable; + /** Payload-2 Value (16-bits) - for GSWIP-3.0 PAE only */ + u16 nPayload2; + /** Payload2 mask/range selection. + If set to LTQ_TRUE, the field 'nPayload2' is used as + a range parameter, otherwise it is used as a bit mask field. */ + ltq_bool_t bPayload2MaskRange_Select; + /** Payload-2 Bit mask - for GSWIP-3.0 PAE only */ + u16 nPayload2_Mask; + /** Exclude Payload-2 used for GSWIP-3.0 PAE only */ + ltq_bool_t bPayload2_Exclude; + + /** Parser Flag LSW (Bit position 15 to 0) is used - for GSWIP 3.0 only */ + ltq_bool_t bParserFlagLSB_Enable; + /** Parser Flag LSW Value - each bit indicates specific parsed result */ + u16 nParserFlagLSB; + /** Corresponding LSW Parser Flag Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ + u16 nParserFlagLSB_Mask; + /** Exclude for Parser Flag LSW specified in nParserFlagLSB */ + ltq_bool_t bParserFlagLSB_Exclude; + + /** Parser Flag MSW (Bit 31 to 16) is used - for GSWIP 3.0 only */ + ltq_bool_t bParserFlagMSB_Enable; + /** Parser Flag MSW Value - each bit indicates specific parsed result */ + u16 nParserFlagMSB; + /** Corresponding Parser Flag MSW Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ + u16 nParserFlagMSB_Mask; + /** Exclude for Parser Flag MSW specified in nParserFlagMSB */ + ltq_bool_t bParserFlagMSB_Exclude; + + /** Parser Flag LSW (Bit position 47 to 32) is used - for GSWIP 3.1 only */ + ltq_bool_t bParserFlag1LSB_Enable; + /** Parser Flag LSW Value - each bit indicates specific parsed result */ + u16 nParserFlag1LSB; + /** Corresponding LSW Parser Flag Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ + u16 nParserFlag1LSB_Mask; + /** Exclude for Parser Flag LSW specified in nParserFlagLSB */ + ltq_bool_t bParserFlag1LSB_Exclude; + + /** Parser Flag MSW (Bit 63 to 48) is used - for GSWIP 3.1 only */ + ltq_bool_t bParserFlag1MSB_Enable; + /** Parser Flag MSW Value - each bit indicates specific parsed result */ + u16 nParserFlag1MSB; + /** Corresponding Parser Flag MSW Mask - when the bit is set to 1 corresponding flag gets masked out (ignored). */ + u16 nParserFlag1MSB_Mask; + /** Exclude for Parser Flag MSW specified in nParserFlagMSB */ + ltq_bool_t bParserFlag1MSB_Exclude; + + /** nInsertionFlag is used. For GSWIP-3.1 only */ + ltq_bool_t bInsertionFlag_Enable; + /** Inserted packet by CPU to data path. For GSWIP-3.1 only */ + u16 nInsertionFlag; +} GSW_PCE_pattern_t; /** \brief IGMP Snooping Control. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disabled. IGMP Snooping is disabled. */ - GSW_PCE_ACTION_IGMP_SNOOP_DISABLE = 0, - /** Default. Regular Packet. No IGMP Snooping action required. */ - GSW_PCE_ACTION_IGMP_SNOOP_REGULAR = 1, - /** IGMP Report/Join Message. */ - GSW_PCE_ACTION_IGMP_SNOOP_REPORT = 2, - /** IGMP Leave Message. */ - GSW_PCE_ACTION_IGMP_SNOOP_LEAVE = 3, - /** Router Solicitation/Advertisement message. */ - GSW_PCE_ACTION_IGMP_SNOOP_AD = 4, - /** IGMP Query Message. */ - GSW_PCE_ACTION_IGMP_SNOOP_QUERY = 5, - /** IGMP Group Specific Query Message. */ - GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP = 6, - /** IGMP General Query message without Router Solicitation. */ - GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER = 7 -}GSW_PCE_ActionIGMP_Snoop_t; +typedef enum { + /** Disabled. IGMP Snooping is disabled. */ + GSW_PCE_ACTION_IGMP_SNOOP_DISABLE = 0, + /** Default. Regular Packet. No IGMP Snooping action required. */ + GSW_PCE_ACTION_IGMP_SNOOP_REGULAR = 1, + /** IGMP Report/Join Message. */ + GSW_PCE_ACTION_IGMP_SNOOP_REPORT = 2, + /** IGMP Leave Message. */ + GSW_PCE_ACTION_IGMP_SNOOP_LEAVE = 3, + /** Router Solicitation/Advertisement message. */ + GSW_PCE_ACTION_IGMP_SNOOP_AD = 4, + /** IGMP Query Message. */ + GSW_PCE_ACTION_IGMP_SNOOP_QUERY = 5, + /** IGMP Group Specific Query Message. */ + GSW_PCE_ACTION_IGMP_SNOOP_QUERY_GROUP = 6, + /** IGMP General Query message without Router Solicitation. */ + GSW_PCE_ACTION_IGMP_SNOOP_QUERY_NO_ROUTER = 7 +} GSW_PCE_ActionIGMP_Snoop_t; /** \brief MAC Address Learning control. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Learning is based on the forwarding decision. If the packet is discarded, - the address is not learned. If the packet is forwarded to any egress port, - the address is learned. */ - GSW_PCE_ACTION_LEARNING_DISABLE = 0, - /** Reserved */ - GSW_PCE_ACTION_LEARNING_REGULAR = 1, - /** Force No Learning. The address is not learned; forwarding decision - ignored. */ - GSW_PCE_ACTION_LEARNING_FORCE_NOT = 2, - /** Force Learning. The address is learned, the forwarding decision ignored. - Note: The MAC Learning Control signals delivered to Port-Map filtering - and combined with Final Forwarding Decision. The result is used as a - feedback for MAC Address learning in the Bridging Table. */ - GSW_PCE_ACTION_LEARNING_FORCE = 3 -}GSW_PCE_ActionLearning_t; +typedef enum { + /** Learning is based on the forwarding decision. If the packet is discarded, + the address is not learned. If the packet is forwarded to any egress port, + the address is learned. */ + GSW_PCE_ACTION_LEARNING_DISABLE = 0, + /** Reserved */ + GSW_PCE_ACTION_LEARNING_REGULAR = 1, + /** Force No Learning. The address is not learned; forwarding decision + ignored. */ + GSW_PCE_ACTION_LEARNING_FORCE_NOT = 2, + /** Force Learning. The address is learned, the forwarding decision ignored. + Note: The MAC Learning Control signals delivered to Port-Map filtering + and combined with Final Forwarding Decision. The result is used as a + feedback for MAC Address learning in the Bridging Table. */ + GSW_PCE_ACTION_LEARNING_FORCE = 3 +} GSW_PCE_ActionLearning_t; /** \brief Flow Meter Assignment control. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Action Disable. */ - GSW_PCE_ACTION_METER_DISABLE = 0, - /** Action Enable. - The action is enabled but no dedicated metering instance is assigned by the rule. */ - GSW_PCE_ACTION_METER_REGULAR = 1, - /** Action Enable. Assign one meter instance as given in parameter "nMeterId". */ - GSW_PCE_ACTION_METER_1 = 2, - /** Action Enable. Assign pair of meter instances. - These instances are "nMeterId" and the next following meter instance index. */ - GSW_PCE_ACTION_METER_1_2 = 3 -}GSW_PCE_ActionMeter_t; +typedef enum { + /** Action Disable. */ + GSW_PCE_ACTION_METER_DISABLE = 0, + /** Action Enable. + The action is enabled but no dedicated metering instance is assigned by the rule. */ + GSW_PCE_ACTION_METER_REGULAR = 1, + /** Action Enable. Assign one meter instance as given in parameter "nMeterId". */ + GSW_PCE_ACTION_METER_1 = 2, + /** Action Enable. Assign pair of meter instances. + These instances are "nMeterId" and the next following meter instance index. */ + GSW_PCE_ACTION_METER_1_2 = 3 +} GSW_PCE_ActionMeter_t; /** \brief Traffic Class Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disabled. Traffic class action is disabled. */ - GSW_PCE_ACTION_TRAFFIC_CLASS_DISABLE = 0, - /** Regular Class. Traffic class action is enabled and the CoS - classification traffic class is used. */ - GSW_PCE_ACTION_TRAFFIC_CLASS_REGULAR = 1, - /** Alternative Class. Traffic class action is enabled and the - class of the 'nTrafficClassAlter' field is used. */ - GSW_PCE_ACTION_TRAFFIC_CLASS_ALTERNATIVE = 2, -}GSW_PCE_ActionTrafficClass_t; +typedef enum { + /** Disabled. Traffic class action is disabled. */ + GSW_PCE_ACTION_TRAFFIC_CLASS_DISABLE = 0, + /** Regular Class. Traffic class action is enabled and the CoS + classification traffic class is used. */ + GSW_PCE_ACTION_TRAFFIC_CLASS_REGULAR = 1, + /** Alternative Class. Traffic class action is enabled and the + class of the 'nTrafficClassAlter' field is used. */ + GSW_PCE_ACTION_TRAFFIC_CLASS_ALTERNATIVE = 2, +} GSW_PCE_ActionTrafficClass_t; /** \brief Interrupt Control Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disabled. Interrupt Control Action is disabled for this rule. */ - GSW_PCE_ACTION_IRQ_DISABLE = 0, - /** Regular Packet. The Interrupt Control Action is enabled, the packet is - treated as a regular packet and no interrupt event is generated. */ - GSW_PCE_ACTION_IRQ_REGULAR = 1, - /** Interrupt Event. The Interrupt Control Action is enabled and an - interrupt event is generated. */ - GSW_PCE_ACTION_IRQ_EVENT = 2 -}GSW_PCE_ActionIrq_t; +typedef enum { + /** Disabled. Interrupt Control Action is disabled for this rule. */ + GSW_PCE_ACTION_IRQ_DISABLE = 0, + /** Regular Packet. The Interrupt Control Action is enabled, the packet is + treated as a regular packet and no interrupt event is generated. */ + GSW_PCE_ACTION_IRQ_REGULAR = 1, + /** Interrupt Event. The Interrupt Control Action is enabled and an + interrupt event is generated. */ + GSW_PCE_ACTION_IRQ_EVENT = 2 +} GSW_PCE_ActionIrq_t; /** \brief Cross State Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disable. The Cross State Action is disabled. */ - GSW_PCE_ACTION_CROSS_STATE_DISABLE = 0, - /** Regular Packet. The Cross State Action is enabled and the packet is - treated as a non-Cross-State packet (regular packet). Therefore it does - not ignore Port-State filtering rules. */ - GSW_PCE_ACTION_CROSS_STATE_REGULAR = 1, - /** Cross-State packet. The Cross State Action is enabled and the packet is - treated as a Cross-State packet. It ignores the Port-State - filtering rules. */ - GSW_PCE_ACTION_CROSS_STATE_CROSS = 2 -}GSW_PCE_ActionCrossState_t; +typedef enum { + /** Disable. The Cross State Action is disabled. */ + GSW_PCE_ACTION_CROSS_STATE_DISABLE = 0, + /** Regular Packet. The Cross State Action is enabled and the packet is + treated as a non-Cross-State packet (regular packet). Therefore it does + not ignore Port-State filtering rules. */ + GSW_PCE_ACTION_CROSS_STATE_REGULAR = 1, + /** Cross-State packet. The Cross State Action is enabled and the packet is + treated as a Cross-State packet. It ignores the Port-State + filtering rules. */ + GSW_PCE_ACTION_CROSS_STATE_CROSS = 2 +} GSW_PCE_ActionCrossState_t; /** \brief Critical Frame Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disable. The Critical Frame Action is disabled. */ - GSW_PCE_ACTION_CRITICAL_FRAME_DISABLE = 0, - /** Regular Packet. The Critical Frame Action is enabled and the packet is - treated as a non-Critical Frame. */ - GSW_PCE_ACTION_CRITICAL_FRAME_REGULAR = 1, - /** Critical Packet. The Critical Frame Action is enabled and the packet is - treated as a Critical Frame. */ - GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL = 2 -}GSW_PCE_ActionCriticalFrame_t; +typedef enum { + /** Disable. The Critical Frame Action is disabled. */ + GSW_PCE_ACTION_CRITICAL_FRAME_DISABLE = 0, + /** Regular Packet. The Critical Frame Action is enabled and the packet is + treated as a non-Critical Frame. */ + GSW_PCE_ACTION_CRITICAL_FRAME_REGULAR = 1, + /** Critical Packet. The Critical Frame Action is enabled and the packet is + treated as a Critical Frame. */ + GSW_PCE_ACTION_CRITICAL_FRAME_CRITICAL = 2 +} GSW_PCE_ActionCriticalFrame_t; /** \brief Color Frame Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disable. No color frame action. */ - GSW_PCE_ACTION_COLOR_FRAME_DISABLE = 0, - /** Do not change color. */ - GSW_PCE_ACTION_COLOR_FRAME_NO_CHANGE = 1, - /** Idendity packet as critical which bypass active congestion - management (ACM). */ - GSW_PCE_ACTION_COLOR_FRAME_CRITICAL = 2, - /** Change to green color. */ - GSW_PCE_ACTION_COLOR_FRAME_GREEN = 3, - /** Change to yellow color. */ - GSW_PCE_ACTION_COLOR_FRAME_YELLOW = 4, - /** Change to red color. */ - GSW_PCE_ACTION_COLOR_FRAME_RED = 5 +typedef enum { + /** Disable. No color frame action. */ + GSW_PCE_ACTION_COLOR_FRAME_DISABLE = 0, + /** Do not change color. */ + GSW_PCE_ACTION_COLOR_FRAME_NO_CHANGE = 1, + /** Idendity packet as critical which bypass active congestion + management (ACM). */ + GSW_PCE_ACTION_COLOR_FRAME_CRITICAL = 2, + /** Change to green color. */ + GSW_PCE_ACTION_COLOR_FRAME_GREEN = 3, + /** Change to yellow color. */ + GSW_PCE_ACTION_COLOR_FRAME_YELLOW = 4, + /** Change to red color. */ + GSW_PCE_ACTION_COLOR_FRAME_RED = 5 } GSW_PCE_ActionColorFrame_t; /** \brief Timestamp Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disable. Timestamp Action is disabled for this rule. */ - GSW_PCE_ACTION_TIMESTAMP_DISABLE = 0, - /** Regular Packet. The Timestamp Action is enabled for this rule. - The packet is treated as a regular packet and no timing information - is stored. */ - GSW_PCE_ACTION_TIMESTAMP_REGULAR = 1, - /** Receive/Transmit Timing packet. Ingress and Egress Timestamps for - this packet should be stored. */ - GSW_PCE_ACTION_TIMESTAMP_STORED = 2 -}GSW_PCE_ActionTimestamp_t; +typedef enum { + /** Disable. Timestamp Action is disabled for this rule. */ + GSW_PCE_ACTION_TIMESTAMP_DISABLE = 0, + /** Regular Packet. The Timestamp Action is enabled for this rule. + The packet is treated as a regular packet and no timing information + is stored. */ + GSW_PCE_ACTION_TIMESTAMP_REGULAR = 1, + /** Receive/Transmit Timing packet. Ingress and Egress Timestamps for + this packet should be stored. */ + GSW_PCE_ACTION_TIMESTAMP_STORED = 2 +} GSW_PCE_ActionTimestamp_t; /** \brief Forwarding Group Action Selector. This flow table action and the 'bFlowID_Action' action can be used exclusively. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disable. Forwarding Group Action is disabled. */ - GSW_PCE_ACTION_PORTMAP_DISABLE = 0, - /** Regular Packet. Forwarding Action enabled. Select Default - Port-Map (result of Default Forwarding Classification). */ - GSW_PCE_ACTION_PORTMAP_REGULAR = 1, - /** Discard. Discard the packets. */ - GSW_PCE_ACTION_PORTMAP_DISCARD = 2, - /** Forward to the CPU port. This requires that the CPU port is previously - set by calling \ref GSW_CPU_PORT_CFG_SET. */ - GSW_PCE_ACTION_PORTMAP_CPU = 3, - /** Forward to a portmap, selected by the parameter 'nForwardPortMap'. - Please note that this feature is not supported by all - hardware platforms. */ - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE = 4, - /** The packet is treated as Multicast Router - Solicitation/Advertisement or Query packet. */ - GSW_PCE_ACTION_PORTMAP_MULTICAST_ROUTER = 5, - /** The packet is interpreted as Multicast packet and learned in the - multicast group table. */ - GSW_PCE_ACTION_PORTMAP_MULTICAST_HW_TABLE = 6, - /** The CTAG VLAN portmap classification result is replaced by the - portmap parameter 'nForwardPortMap'. All other classification - results stay unchanged and will be combined together with - the overwritten portmap. */ - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE_VLAN = 7, - /** Add STAG VLAN portmap 'nForwardPortMap' to the overall portmap - classification result (AND'ed with the portmap). */ - GSW_PCE_ACTION_PORTMAP_ALTERNATIVE_STAG_VLAN = 8 -}GSW_PCE_ActionPortmap_t; +typedef enum { + /** Disable. Forwarding Group Action is disabled. */ + GSW_PCE_ACTION_PORTMAP_DISABLE = 0, + /** Regular Packet. Forwarding Action enabled. Select Default + Port-Map (result of Default Forwarding Classification). */ + GSW_PCE_ACTION_PORTMAP_REGULAR = 1, + /** Discard. Discard the packets. */ + GSW_PCE_ACTION_PORTMAP_DISCARD = 2, + /** Forward to the CPU port. This requires that the CPU port is previously + set by calling \ref GSW_CPU_PORT_CFG_SET. */ + GSW_PCE_ACTION_PORTMAP_CPU = 3, + /** Forward to a portmap, selected by the parameter 'nForwardPortMap'. + Please note that this feature is not supported by all + hardware platforms. */ + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE = 4, + /** The packet is treated as Multicast Router + Solicitation/Advertisement or Query packet. */ + GSW_PCE_ACTION_PORTMAP_MULTICAST_ROUTER = 5, + /** The packet is interpreted as Multicast packet and learned in the + multicast group table. */ + GSW_PCE_ACTION_PORTMAP_MULTICAST_HW_TABLE = 6, + /** The CTAG VLAN portmap classification result is replaced by the + portmap parameter 'nForwardPortMap'. All other classification + results stay unchanged and will be combined together with + the overwritten portmap. */ + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE_VLAN = 7, + /** Add STAG VLAN portmap 'nForwardPortMap' to the overall portmap + classification result (AND'ed with the portmap). */ + GSW_PCE_ACTION_PORTMAP_ALTERNATIVE_STAG_VLAN = 8 +} GSW_PCE_ActionPortmap_t; /** \brief VLAN Group Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disabled. The VLAN Action is disabled. */ - GSW_PCE_ACTION_VLAN_DISABLE = 0, - /** Regular VLAN. VLAN Action enabled. Select Default VLAN ID. */ - GSW_PCE_ACTION_VLAN_REGULAR = 1, - /** Alternative VLAN. VLAN Action enabled. - Select Alternative VLAN as configured in 'nVLAN_Id' - or 'nSVLAN_Id'. For CTAG VLAN it requires that this VLAN ID - is configured by calling - \ref GSW_VLAN_ID_CREATE in advance. - This additional call is not required for STAG VLAN. */ - GSW_PCE_ACTION_VLAN_ALTERNATIVE = 2 -}GSW_PCE_ActionVLAN_t; +typedef enum { + /** Disabled. The VLAN Action is disabled. */ + GSW_PCE_ACTION_VLAN_DISABLE = 0, + /** Regular VLAN. VLAN Action enabled. Select Default VLAN ID. */ + GSW_PCE_ACTION_VLAN_REGULAR = 1, + /** Alternative VLAN. VLAN Action enabled. + Select Alternative VLAN as configured in 'nVLAN_Id' + or 'nSVLAN_Id'. For CTAG VLAN it requires that this VLAN ID + is configured by calling + \ref GSW_VLAN_ID_CREATE in advance. + This additional call is not required for STAG VLAN. */ + GSW_PCE_ACTION_VLAN_ALTERNATIVE = 2 +} GSW_PCE_ActionVLAN_t; /** \brief Cross VLAN Action Selector. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Disabled. The Cross VLAN Action is disabled. */ - GSW_PCE_ACTION_CROSS_VLAN_DISABLE = 0, - /** Regular VLAN Packet. Do not ignore VLAN filtering rules. */ - GSW_PCE_ACTION_CROSS_VLAN_REGULAR = 1, - /** Cross-VLAN packet. Ignore VLAN filtering rules.*/ - GSW_PCE_ACTION_CROSS_VLAN_CROSS = 2 -}GSW_PCE_ActionCrossVLAN_t; +typedef enum { + /** Disabled. The Cross VLAN Action is disabled. */ + GSW_PCE_ACTION_CROSS_VLAN_DISABLE = 0, + /** Regular VLAN Packet. Do not ignore VLAN filtering rules. */ + GSW_PCE_ACTION_CROSS_VLAN_REGULAR = 1, + /** Cross-VLAN packet. Ignore VLAN filtering rules.*/ + GSW_PCE_ACTION_CROSS_VLAN_CROSS = 2 +} GSW_PCE_ActionCrossVLAN_t; /** \brief Port Filter Action-1/2/3/4/5/6 Selector - used for GSWIP-3.0 only. This can be used only along with PortMember config. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Port Filter Action is Unused. */ - GSW_PCE_PORT_FILTER_ACTION_UNUSED = 0, - /** Port Filter Action Type-1 is used. */ - GSW_PCE_PORT_FILTER_ACTION_1 = 1, - /** Port Filter Action Type-2 is used. */ - GSW_PCE_PORT_FILTER_ACTION_2 = 2, - /** Port Filter Action Type-3 is used. */ - GSW_PCE_PORT_FILTER_ACTION_3 = 3, - /** Port Filter Action Type-4 is used. */ - GSW_PCE_PORT_FILTER_ACTION_4 = 4, - /** Port Filter Action Type-5 (Unknown Unicast) is used. */ - GSW_PCE_PORT_FILTER_ACTION_5 = 5, - /** Port Filter Action Type-6 (Unknown Multicast) is used. */ - GSW_PCE_PORT_FILTER_ACTION_6 = 6 +typedef enum { + /** Port Filter Action is Unused. */ + GSW_PCE_PORT_FILTER_ACTION_UNUSED = 0, + /** Port Filter Action Type-1 is used. */ + GSW_PCE_PORT_FILTER_ACTION_1 = 1, + /** Port Filter Action Type-2 is used. */ + GSW_PCE_PORT_FILTER_ACTION_2 = 2, + /** Port Filter Action Type-3 is used. */ + GSW_PCE_PORT_FILTER_ACTION_3 = 3, + /** Port Filter Action Type-4 is used. */ + GSW_PCE_PORT_FILTER_ACTION_4 = 4, + /** Port Filter Action Type-5 (Unknown Unicast) is used. */ + GSW_PCE_PORT_FILTER_ACTION_5 = 5, + /** Port Filter Action Type-6 (Unknown Multicast) is used. */ + GSW_PCE_PORT_FILTER_ACTION_6 = 6 } GSW_PCE_PortFilterAction_t; /** \brief MPE Processing Path Assignment Selector - used for GSWIP-3.0 only. Used by \ref GSW_PCE_action_t. */ -typedef enum -{ - /** Processing Path is not enabled. */ - GSW_PCE_PROCESSING_PATH_UNUSED = 0, - /** Processing Path-1 is used for MPE-1. */ - GSW_PCE_PROCESSING_PATH_1 = 1, - /** Processing Path-2 is used for MPE-2. */ - GSW_PCE_PROCESSING_PATH_2 = 2, - /** Processing Path-1 and -2 are used for MPE-1 & MPE-2. */ - GSW_PCE_PROCESSING_PATH_BOTH = 3, +typedef enum { + /** Processing Path is not enabled. */ + GSW_PCE_PROCESSING_PATH_UNUSED = 0, + /** Processing Path-1 is used for MPE-1. */ + GSW_PCE_PROCESSING_PATH_1 = 1, + /** Processing Path-2 is used for MPE-2. */ + GSW_PCE_PROCESSING_PATH_2 = 2, + /** Processing Path-1 and -2 are used for MPE-1 & MPE-2. */ + GSW_PCE_PROCESSING_PATH_BOTH = 3, } GSW_PCE_ProcessingPathAction_t; /** \brief Packet Classification Engine Action Configuration. GSWIP-3.0 extension actions are explicitly indicated. Used by \ref GSW_PCE_rule_t. */ -typedef struct -{ - /** Action "Traffic Class" Group. - Traffic class action enable */ - GSW_PCE_ActionTrafficClass_t eTrafficClassAction; - /** Alternative Traffic class - used when eTrafficClassAction is set to 2. */ - u8 nTrafficClassAlternate; - - /** Action "IGMP Snooping" Group. - IGMP Snooping control and enable. Please note that the 'nPortMapAction' - configuration is ignored in case the IGMP snooping is enabled. - Here, on read operations, - 'nPortMapAction = GSW_PCE_ACTION_PORTMAP_DISABLE' is returned. */ - GSW_PCE_ActionIGMP_Snoop_t eSnoopingTypeAction; - - /** Action "Learning" Group. - Learning action control and enable */ - GSW_PCE_ActionLearning_t eLearningAction; - - /** Action "Interrupt" Group. - Interrupt action generate and enable */ - GSW_PCE_ActionIrq_t eIrqAction; - - /** Action "Cross State" Group. - Cross state action control and enable */ - GSW_PCE_ActionCrossState_t eCrossStateAction; - - /** Action "Critical Frames" Group. - Critical Frame action control and enable */ - GSW_PCE_ActionCriticalFrame_t eCritFrameAction; - - /** Action "Color Frames" Group. - This is replacement of eCritFrameAction in GSWIP-3.1. */ - GSW_PCE_ActionColorFrame_t eColorFrameAction; - - /** Action "Timestamp" Group. Time stamp action control and enable */ - GSW_PCE_ActionTimestamp_t eTimestampAction; - - /** Action "Forwarding" Group. - Port map action enable. This port forwarding configuration is ignored - in case the action "IGMP Snooping" is enabled via the - parameter 'nSnoopingTypeAction'. */ - GSW_PCE_ActionPortmap_t ePortMapAction; - /** Target portmap for forwarded packets, only used if selected by - 'ePortMapAction'. Forwarding is done - if 'ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE'. - Every bit in the portmap represents one port (port 0 = LSB bit). */ - u16 nForwardPortMap[16]; - - /** Target Sub-Interface Id (GSWIP-3.0 only) for forwarded packets, - only used if selected by 'ePortMapAction'. Forwarding is done - if 'ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE'. */ - u16 nForwardSubIfId; - - /** Action "Remarking" Group. Remarking action enable. Reserved in - GSWIP-3.1. */ - ltq_bool_t bRemarkAction; - /** CTAG VLAN PCP remarking enable. Reserved in GSWIP-3.1. - Remarking enabling means that remarking is possible in case - the port configuration or metering enables remarking on that - packet. Disabling remarking means that it is forced to - not remarking this packet, independent of any port remarking of - metering configuration. */ - ltq_bool_t bRemarkPCP; - /** STAG VLAN PCP remarking enable. Reserved in GSWIP-3.1. - Remarking enabling means that remarking is possible in case - the port configuration or metering enables remarking on that - packet. Disabling remarking means that it is forced to - not remarking this packet, independent of any port remarking of - metering configuration. */ - ltq_bool_t bRemarkSTAG_PCP; - /** STAG VLAN DEI remarking enable. Reserved in GSWIP-3.1. - Remarking enabling means that remarking is possible in case - the port configuration or metering enables remarking on that - packet. Disabling remarking means that it is forced to - not remarking this packet, independent of any port remarking of - metering configuration. */ - ltq_bool_t bRemarkSTAG_DEI; - /** DSCP remarking enable. Reserved in GSWIP-3.1. - Remarking enabling means that remarking is possible in case - the port configuration or metering enables remarking on that - packet. Disabling remarking means that it is forced to - not remarking this packet, independent of any port remarking of - metering configuration. */ - ltq_bool_t bRemarkDSCP; - /** Class remarking enable. Reserved in GSWIP-3.1. - Remarking enabling means that remarking is possible in case - the port configuration or metering enables remarking on that - packet. Disabling remarking means that it is forced to - not remarking this packet, independent of any port remarking of - metering configuration. */ - ltq_bool_t bRemarkClass; - - /** Action "Meter" Group. Meter action control and enable. - If metering action enabled, specified metering instance number - overrules any other metering assignment. - Up to two metering instances can be applied to a single packet. */ - GSW_PCE_ActionMeter_t eMeterAction; - /** Meter ID */ - u8 nMeterId; - - /** Action "RMON" Group. RMON action enable. Reserved in GSWIP-3.1. */ - ltq_bool_t bRMON_Action; - /** Counter ID (The index starts counting from zero). */ - u8 nRMON_Id; - - /** Action "CTAG VLAN" Group. VLAN action enable */ - GSW_PCE_ActionVLAN_t eVLAN_Action; - /** Alternative CTAG VLAN Id */ - u16 nVLAN_Id; - /** Enable alternative FID */ - ltq_bool_t bFidEnable; - /** Alternative FID. Valid when bFidEnable is TRUE. */ - u8 nFId; - /** Enable extended VLAN operation for traffic match this flow entry. */ - ltq_bool_t bExtendedVlanEnable; - /** Extended VLAN block allocated for traffic match this flow entry. Valid - when bExtendedVlanEnable is TRUE. Only FIRST VLAN operation in this block - is used for flow process. */ - u32 nExtendedVlanBlockId; - /** Action "STAG VLAN" Group. VLAN action enable */ - GSW_PCE_ActionVLAN_t eSVLAN_Action; - /** Alternative STAG VLAN Id */ - u16 nSVLAN_Id; - /** Action "Cross VLAN" Group. Cross VLAN action enable */ - GSW_PCE_ActionCrossVLAN_t eVLAN_CrossAction; +typedef struct { + /** Action "Traffic Class" Group. + Traffic class action enable */ + GSW_PCE_ActionTrafficClass_t eTrafficClassAction; + /** Alternative Traffic class - used when eTrafficClassAction is set to 2. */ + u8 nTrafficClassAlternate; + + /** Action "IGMP Snooping" Group. + IGMP Snooping control and enable. Please note that the 'nPortMapAction' + configuration is ignored in case the IGMP snooping is enabled. + Here, on read operations, + 'nPortMapAction = GSW_PCE_ACTION_PORTMAP_DISABLE' is returned. */ + GSW_PCE_ActionIGMP_Snoop_t eSnoopingTypeAction; + + /** Action "Learning" Group. + Learning action control and enable */ + GSW_PCE_ActionLearning_t eLearningAction; + + /** Action "Interrupt" Group. + Interrupt action generate and enable */ + GSW_PCE_ActionIrq_t eIrqAction; + + /** Action "Cross State" Group. + Cross state action control and enable */ + GSW_PCE_ActionCrossState_t eCrossStateAction; + + /** Action "Critical Frames" Group. + Critical Frame action control and enable */ + GSW_PCE_ActionCriticalFrame_t eCritFrameAction; + + /** Action "Color Frames" Group. + This is replacement of eCritFrameAction in GSWIP-3.1. */ + GSW_PCE_ActionColorFrame_t eColorFrameAction; + + /** Action "Timestamp" Group. Time stamp action control and enable */ + GSW_PCE_ActionTimestamp_t eTimestampAction; + + /** Action "Forwarding" Group. + Port map action enable. This port forwarding configuration is ignored + in case the action "IGMP Snooping" is enabled via the + parameter 'nSnoopingTypeAction'. */ + GSW_PCE_ActionPortmap_t ePortMapAction; + /** Target portmap for forwarded packets, only used if selected by + 'ePortMapAction'. Forwarding is done + if 'ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE'. + Every bit in the portmap represents one port (port 0 = LSB bit). */ + u16 nForwardPortMap[16]; + + /** Target Sub-Interface Id (GSWIP-3.0 only) for forwarded packets, + only used if selected by 'ePortMapAction'. Forwarding is done + if 'ePortMapAction = GSW_PCE_ACTION_PORTMAP_ALTERNATIVE'. */ + u16 nForwardSubIfId; + + /** Action "Remarking" Group. Remarking action enable. Reserved in + GSWIP-3.1. */ + ltq_bool_t bRemarkAction; + /** CTAG VLAN PCP remarking enable. Reserved in GSWIP-3.1. + Remarking enabling means that remarking is possible in case + the port configuration or metering enables remarking on that + packet. Disabling remarking means that it is forced to + not remarking this packet, independent of any port remarking of + metering configuration. */ + ltq_bool_t bRemarkPCP; + /** STAG VLAN PCP remarking enable. Reserved in GSWIP-3.1. + Remarking enabling means that remarking is possible in case + the port configuration or metering enables remarking on that + packet. Disabling remarking means that it is forced to + not remarking this packet, independent of any port remarking of + metering configuration. */ + ltq_bool_t bRemarkSTAG_PCP; + /** STAG VLAN DEI remarking enable. Reserved in GSWIP-3.1. + Remarking enabling means that remarking is possible in case + the port configuration or metering enables remarking on that + packet. Disabling remarking means that it is forced to + not remarking this packet, independent of any port remarking of + metering configuration. */ + ltq_bool_t bRemarkSTAG_DEI; + /** DSCP remarking enable. Reserved in GSWIP-3.1. + Remarking enabling means that remarking is possible in case + the port configuration or metering enables remarking on that + packet. Disabling remarking means that it is forced to + not remarking this packet, independent of any port remarking of + metering configuration. */ + ltq_bool_t bRemarkDSCP; + /** Class remarking enable. Reserved in GSWIP-3.1. + Remarking enabling means that remarking is possible in case + the port configuration or metering enables remarking on that + packet. Disabling remarking means that it is forced to + not remarking this packet, independent of any port remarking of + metering configuration. */ + ltq_bool_t bRemarkClass; + + /** Action "Meter" Group. Meter action control and enable. + If metering action enabled, specified metering instance number + overrules any other metering assignment. + Up to two metering instances can be applied to a single packet. */ + GSW_PCE_ActionMeter_t eMeterAction; + /** Meter ID */ + u8 nMeterId; + + /** Action "RMON" Group. RMON action enable. Reserved in GSWIP-3.1. */ + ltq_bool_t bRMON_Action; + /** Counter ID (The index starts counting from zero). */ + u8 nRMON_Id; + + /** Action "CTAG VLAN" Group. VLAN action enable */ + GSW_PCE_ActionVLAN_t eVLAN_Action; + /** Alternative CTAG VLAN Id */ + u16 nVLAN_Id; + /** Enable alternative FID */ + ltq_bool_t bFidEnable; + /** Alternative FID. Valid when bFidEnable is TRUE. */ + u8 nFId; + /** Enable extended VLAN operation for traffic match this flow entry. */ + ltq_bool_t bExtendedVlanEnable; + /** Extended VLAN block allocated for traffic match this flow entry. Valid + when bExtendedVlanEnable is TRUE. Only FIRST VLAN operation in this block + is used for flow process. */ + u32 nExtendedVlanBlockId; + /** Action "STAG VLAN" Group. VLAN action enable */ + GSW_PCE_ActionVLAN_t eSVLAN_Action; + /** Alternative STAG VLAN Id */ + u16 nSVLAN_Id; + /** Action "Cross VLAN" Group. Cross VLAN action enable */ + GSW_PCE_ActionCrossVLAN_t eVLAN_CrossAction; /** CVLAN Ignore control */ - ltq_bool_t bCVLAN_Ignore_Control; - /** Port BitMap Mux control */ - ltq_bool_t bPortBitMapMuxControl; - /** Trunking action enable */ - ltq_bool_t bPortTrunkAction; - /** Port Link Selection control */ - ltq_bool_t bPortLinkSelection; - /** Action "Flow ID". - The Switch supports enhancing the egress packets by a device specific - special tag header. This header contains detailed switch classification - results. One header file is a 'Flow ID', which can be explicitly set as - flow table action when hitting a table rule. - If selected, the Flow ID is given by the parameter 'nFlowID'. */ - ltq_bool_t bFlowID_Action; - /** Flow ID */ - u16 nFlowID; - - /** Routing Extension Id Action Selector - for GSWIP-3.0 only. - When enabled, it expects a valid nRoutExtId value to be supplied. */ - ltq_bool_t bRoutExtId_Action; - /** Routing Extension Id Value - for GSWIP-3.0 only. (8-bits range) */ - u8 nRoutExtId; - /** Routing Destination Port Mask Comparison - for GSWIP-3.0 only. If not enabled this field is not considered for routing session pattern lookup.*/ - ltq_bool_t bRtDstPortMaskCmp_Action; - /** Routing Source Port Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ - ltq_bool_t bRtSrcPortMaskCmp_Action; - /** Routing Destination IP Address Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ - ltq_bool_t bRtDstIpMaskCmp_Action; - /** Routing Source IP Address Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ - ltq_bool_t bRtSrcIpMaskCmp_Action; - /** Selector of IP in Tunneled IP header (Outer or Inner) - for GSWIP-3.0 only. */ - ltq_bool_t bRtInnerIPasKey_Action; - /** Routing Acceleration Enable Action - for GSWIP-3.0 only. This variable decides whether to accelerate the Routing session or not */ - ltq_bool_t bRtAccelEna_Action; - /** Routing Control Enable Action - for GSWIP-3.0 only. This variable is selector of Routing Accelerate action*/ - ltq_bool_t bRtCtrlEna_Action; - /** Assignment of flow to MPE Processing Path-1 or -2 or both - for GSWIP-3.0 only. */ - GSW_PCE_ProcessingPathAction_t eProcessPath_Action; - /** Port Filter Action Config for this flow - for GSWIP-3.0 only. */ - GSW_PCE_PortFilterAction_t ePortFilterType_Action; - - /** Enable Extraction. For GSWIP-3.1 only. - Packet is identified to be extracted at extraction point defined by - nRecordId. */ - ltq_bool_t bExtractEnable; - /** Enable OAM. For GSWIP-3.1 only. - Packet is identified for OAM process. */ - ltq_bool_t bOamEnable; - /** Record ID is information used by extraction (bExtractEnable is set) - and/or OAM process (bOamEnable is set). For GSWIP-3.1 only. Refer to - GSWIP-3.1 Hardware Architecture Spec (HAS) for more detail. */ - u32 nRecordId; + ltq_bool_t bCVLAN_Ignore_Control; + /** Port BitMap Mux control */ + ltq_bool_t bPortBitMapMuxControl; + /** Trunking action enable */ + ltq_bool_t bPortTrunkAction; + /** Port Link Selection control */ + ltq_bool_t bPortLinkSelection; + /** Action "Flow ID". + The Switch supports enhancing the egress packets by a device specific + special tag header. This header contains detailed switch classification + results. One header file is a 'Flow ID', which can be explicitly set as + flow table action when hitting a table rule. + If selected, the Flow ID is given by the parameter 'nFlowID'. */ + ltq_bool_t bFlowID_Action; + /** Flow ID */ + u16 nFlowID; + + /** Routing Extension Id Action Selector - for GSWIP-3.0 only. + When enabled, it expects a valid nRoutExtId value to be supplied. */ + ltq_bool_t bRoutExtId_Action; + /** Routing Extension Id Value - for GSWIP-3.0 only. (8-bits range) */ + u8 nRoutExtId; + /** Routing Destination Port Mask Comparison - for GSWIP-3.0 only. If not enabled this field is not considered for routing session pattern lookup.*/ + ltq_bool_t bRtDstPortMaskCmp_Action; + /** Routing Source Port Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ + ltq_bool_t bRtSrcPortMaskCmp_Action; + /** Routing Destination IP Address Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ + ltq_bool_t bRtDstIpMaskCmp_Action; + /** Routing Source IP Address Mask Comparison - for GSWIP-3.0 only. If not enabled, this field is not considered for routing session pattern lookup.*/ + ltq_bool_t bRtSrcIpMaskCmp_Action; + /** Selector of IP in Tunneled IP header (Outer or Inner) - for GSWIP-3.0 only. */ + ltq_bool_t bRtInnerIPasKey_Action; + /** Routing Acceleration Enable Action - for GSWIP-3.0 only. This variable decides whether to accelerate the Routing session or not */ + ltq_bool_t bRtAccelEna_Action; + /** Routing Control Enable Action - for GSWIP-3.0 only. This variable is selector of Routing Accelerate action*/ + ltq_bool_t bRtCtrlEna_Action; + /** Assignment of flow to MPE Processing Path-1 or -2 or both - for GSWIP-3.0 only. */ + GSW_PCE_ProcessingPathAction_t eProcessPath_Action; + /** Port Filter Action Config for this flow - for GSWIP-3.0 only. */ + GSW_PCE_PortFilterAction_t ePortFilterType_Action; + + /** Enable Extraction. For GSWIP-3.1 only. + Packet is identified to be extracted at extraction point defined by + nRecordId. */ + ltq_bool_t bExtractEnable; + /** Enable OAM. For GSWIP-3.1 only. + Packet is identified for OAM process. */ + ltq_bool_t bOamEnable; + /** Record ID is information used by extraction (bExtractEnable is set) + and/or OAM process (bOamEnable is set). For GSWIP-3.1 only. Refer to + GSWIP-3.1 Hardware Architecture Spec (HAS) for more detail. */ + u32 nRecordId; } GSW_PCE_action_t; /** \brief Parameter to add/read a rule to/from the packet classification engine. Used by \ref GSW_PCE_RULE_WRITE and \ref GSW_PCE_RULE_READ. */ -typedef struct -{ - /** PCE Rule Pattern Part. */ - GSW_PCE_pattern_t pattern; - /** PCE Rule Action Part. */ - GSW_PCE_action_t action; -}GSW_PCE_rule_t; +typedef struct { + /** PCE Rule Pattern Part. */ + GSW_PCE_pattern_t pattern; + /** PCE Rule Action Part. */ + GSW_PCE_action_t action; +} GSW_PCE_rule_t; /** \brief Parameter to delete a rule from the packet classification engine. Used by \ref GSW_PCE_RULE_DELETE. */ -typedef struct -{ - /** Rule Index in the PCE Table. */ - u32 nIndex; -}GSW_PCE_ruleDelete_t; +typedef struct { + /** Rule Index in the PCE Table. */ + u32 nIndex; +} GSW_PCE_ruleDelete_t; /*@}*/ /* GSW_IOCTL_CLASS */ @@ -939,21 +916,19 @@ typedef struct /** \brief Reset selection. Used by \ref GSW_reset_t. */ -typedef enum -{ - /** Switch Macro reset */ - GSW_RESET_SWITCH = 0, - /** MDIO master interface reset */ - GSW_RESET_MDIO = 1, -}GSW_resetMode_t; +typedef enum { + /** Switch Macro reset */ + GSW_RESET_SWITCH = 0, + /** MDIO master interface reset */ + GSW_RESET_MDIO = 1, +} GSW_resetMode_t; /** \brief Reset selection. Used by \ref GSW_RESET. */ -typedef struct -{ - /** Reset selection. */ - GSW_resetMode_t eReset; -}GSW_reset_t; +typedef struct { + /** Reset selection. */ + GSW_resetMode_t eReset; +} GSW_reset_t; /** Number of extended RMON counter. */ #define GSW_RMON_EXTEND_NUM 24 @@ -965,15 +940,14 @@ typedef struct These counters can be used by the packet classification engine and can be freely assigned to dedicated packet rules and flows. Used by \ref GSW_RMON_EXTEND_GET. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u8 nPortId; - /** Traffic flow counters */ - u32 nTrafficFlowCnt[GSW_RMON_EXTEND_NUM]; -}GSW_RMON_extendGet_t; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u8 nPortId; + /** Traffic flow counters */ + u32 nTrafficFlowCnt[GSW_RMON_EXTEND_NUM]; +} GSW_RMON_extendGet_t; /** \brief Hardware platform extended RMON Counters. GSWIP-3.1 only. @@ -981,34 +955,32 @@ typedef struct used by the packet classification engine and can be freely assigned to dedicated packet rules and flows. Used by \ref GSW_RMON_FLOW_GET. */ -typedef struct -{ - /** If TRUE, use \ref GSW_RMON_flowGet_t::nIndex to access the Flow Counter, - otherwise, use \ref GSW_TFLOW_COUNT_MODE_GET to determine mode and use - \ref GSW_RMON_flowGet_t::nPortId and \ref GSW_RMON_flowGet_t::nFlowId - to calculate index of the Flow Counter. */ - ltq_bool_t bIndex; - /** Absolute index of Flow Counter. */ - u16 nIndex; - /** Port ID. This could be Logical Port, CTP or Bridge Port. It depends - on the mode set by \ref GSW_TFLOW_COUNT_MODE_SET. */ - u16 nPortId; - /** \ref GSW_PCE_action_t::nFlowID. The range depends on the mode set - by \ref GSW_TFLOW_COUNT_MODE_SET. */ - u16 nFlowId; - - /** Rx Packet Counter */ - u32 nRxPkts; - /** Tx Packet Counter (non-PCE-Bypass) */ - u32 nTxPkts; - /** Tx Packet Counter (PCE-Bypass) */ - u32 nTxPceBypassPkts; +typedef struct { + /** If TRUE, use \ref GSW_RMON_flowGet_t::nIndex to access the Flow Counter, + otherwise, use \ref GSW_TFLOW_COUNT_MODE_GET to determine mode and use + \ref GSW_RMON_flowGet_t::nPortId and \ref GSW_RMON_flowGet_t::nFlowId + to calculate index of the Flow Counter. */ + ltq_bool_t bIndex; + /** Absolute index of Flow Counter. */ + u16 nIndex; + /** Port ID. This could be Logical Port, CTP or Bridge Port. It depends + on the mode set by \ref GSW_TFLOW_COUNT_MODE_SET. */ + u16 nPortId; + /** \ref GSW_PCE_action_t::nFlowID. The range depends on the mode set + by \ref GSW_TFLOW_COUNT_MODE_SET. */ + u16 nFlowId; + + /** Rx Packet Counter */ + u32 nRxPkts; + /** Tx Packet Counter (non-PCE-Bypass) */ + u32 nTxPkts; + /** Tx Packet Counter (PCE-Bypass) */ + u32 nTxPceBypassPkts; } GSW_RMON_flowGet_t; /** \brief Used for getting metering RMON counters. Used by \ref GSW_RMON_METER_GET */ -typedef enum -{ +typedef enum { /* Resereved */ GSW_RMON_METER_COLOR_RES = 0, /* Green color */ @@ -1016,7 +988,7 @@ typedef enum /* Yellow color */ GSW_RMON_METER_COLOR_YELLOW = 2, /* Red color */ - GSW_RMON_METER_COLOR_RED = 3, + GSW_RMON_METER_COLOR_RED = 3, } GSW_RmonMeterColor_t; /** @@ -1024,8 +996,7 @@ typedef enum Supported modes include, Global (default), Logical, CTP, Bridge port mode. The number of counters that can be assigned varies based these mode type. Used by \ref GSW_TFLOW_COUNT_MODE_SET and GSW_TFLOW_COUNT_MODE_GET. */ -typedef struct -{ +typedef struct { //Counter type. PCE Rx/Tx/Bp-Tx. GSW_TflowCountConfType_t eCountType; //Counter mode. Global/Logical/CTP/BrP. @@ -1034,45 +1005,43 @@ typedef struct //A group of ports matching MS (9-n) bits. n is nCtpLsb or nBrpLsb. u16 nPortMsb; //Number of valid bits in CTP port counter mode. - GSW_TflowCtpValBits_t nCtpLsb; - //Number of valid bits in bridge port counter mode. - GSW_TflowBrpValBits_t nBrpLsb; -}GSW_TflowCmodeConf_t; + GSW_TflowCtpValBits_t nCtpLsb; + //Number of valid bits in bridge port counter mode. + GSW_TflowBrpValBits_t nBrpLsb; +} GSW_TflowCmodeConf_t; /** \brief This structure describes the second, nano second and fractional nano second counterpart of the switch reference timer. This reference counter can be read by using \ref GSW_TIMESTAMP_TIMER_GET , and it can be modified by using \ref GSW_TIMESTAMP_TIMER_SET . */ -typedef struct -{ - /** Second. Absolute second timer count. */ - u32 nSec; - /** Nano Second. Absolute nanosecond timer count. */ - u32 nNanoSec; - /** Fractional NanoSecond. Absolute fractional nanosecond timer count. - This counter specifis a 2^32 fractional 'nNanoSec'. */ - u32 nFractionalNanoSec; -}GSW_TIMESTAMP_Timer_t; +typedef struct { + /** Second. Absolute second timer count. */ + u32 nSec; + /** Nano Second. Absolute nanosecond timer count. */ + u32 nNanoSec; + /** Fractional NanoSecond. Absolute fractional nanosecond timer count. + This counter specifis a 2^32 fractional 'nNanoSec'. */ + u32 nFractionalNanoSec; +} GSW_TIMESTAMP_Timer_t; /** \brief This structure describes the port related time stamp. Used by \ref GSW_TIMESTAMP_PORT_READ. */ -typedef struct -{ - /** Ethernet Port number (zero-based counting). The valid range is hardware - dependent. An error code is delivered if the selected port is not - available. */ - u8 nPortId; - /** Second. Absolute second timer count. */ - u32 nIngressSec; - /** Nano Second. Absolute nano second timer count. */ - u32 nIngressNanoSec; - /** Second. Absolute second timer count. */ - u32 nEgressSec; - /** Nano Second. Absolute nano second timer count. */ - u32 nEgressNanoSec; -}GSW_TIMESTAMP_PortRead_t; +typedef struct { + /** Ethernet Port number (zero-based counting). The valid range is hardware + dependent. An error code is delivered if the selected port is not + available. */ + u8 nPortId; + /** Second. Absolute second timer count. */ + u32 nIngressSec; + /** Nano Second. Absolute nano second timer count. */ + u32 nIngressNanoSec; + /** Second. Absolute second timer count. */ + u32 nEgressSec; + /** Nano Second. Absolute nano second timer count. */ + u32 nEgressNanoSec; +} GSW_TIMESTAMP_PortRead_t; /*@}*/ /* GSW_IOCTL_SYS */ @@ -1271,7 +1240,7 @@ typedef struct /** \brief Read out additional traffic flow (RMON) counters. The zero-based 'nPortId' structure element describes the physical switch - port for the requested statistic information. + port for the requested statistic information. This API is replaced by \ref GSW_RMON_FLOW_GET for GSWIP-3.1. diff --git a/include/net/switch_api/lantiq_gsw_routing.h b/include/net/switch_api/lantiq_gsw_routing.h index 60c2ece035c8a2146570c0ece33d2e3914699a53..c9e491df65d5355ba5f9fc1481fdad963624d29b 100644 --- a/include/net/switch_api/lantiq_gsw_routing.h +++ b/include/net/switch_api/lantiq_gsw_routing.h @@ -12,19 +12,13 @@ #ifndef _LANTIQ_GSW_ROUTE_H_ #define _LANTIQ_GSW_ROUTE_H_ -//#include "lantiq_types.h" -//#include "lantiq_gsw.h" + #include "gsw_types.h" -/** \defgroup PAE_API GSWIP-Routing/PAE specific APIs - \brief GSWIP-Routing (PAE) APIs definition applicable to GSWIP-3.0 only. -*/ -#if 0 -/** \defgroup GSWIP_ROUTE_API GSWIP-R Kernel APIs - \brief GSWIP-Routing (PAE) Kernel API definition. +/** \defgroup PAE_API GSWIP-Routing/PAE specific APIs + \brief GSWIP-Routing (PAE) APIs definition applicable to GSWIP-3.0 only. */ -#endif /** \addtogroup PAE_API */ /*@{*/ @@ -54,50 +48,48 @@ */ typedef struct { GSW_IP_t nSrcIP4Addr; /*!< 6rd tunnel Source IPv4 address */ - GSW_IP_t nDstIP4Addr; /*!< 6rd tunnel Dest IPv4 address */ + GSW_IP_t nDstIP4Addr; /*!< 6rd tunnel Dest IPv4 address */ } GSW_ROUTE_Tunnel_6rd; /*! \brief This is the data structure for PAE DSLite tunnel interface - Outer IPv6. */ typedef struct { - GSW_IP_t nSrcIP6Addr; /*!< DS-Lite tunnel Source IPv6 address */ - GSW_IP_t nDstIP6Addr; /*!< DS-Lite tunnel Dest IPv6 address */ + GSW_IP_t nSrcIP6Addr; /*!< DS-Lite tunnel Source IPv6 address */ + GSW_IP_t nDstIP6Addr; /*!< DS-Lite tunnel Dest IPv6 address */ } GSW_ROUTE_Tunnel_DSLite; /*! \brief This is the data structure for PAE Tunnel type selector. Used by \ref GSW_ROUTE_Session_action_t. */ -typedef enum -{ - GSW_ROUTE_TUNL_NULL = 0, /*!< Session routing tunnel type is No Tunnel action */ - GSW_ROUTE_TUNL_6RD = 1, /*!< Session routing tunnel type is 6rd */ - GSW_ROUTE_TUNL_DSLITE = 2, /*!< Session routing tunnel type is DSlite */ - GSW_ROUTE_TUNL_L2TP = 3, /*!< Session routing tunnel type is L2TP */ - GSW_ROUTE_TUNL_IPSEC = 4, /*!< Session routing tunnel type is IPsec */ - -} GSW_ROUTE_Session_Tunmode_t; +typedef enum { + GSW_ROUTE_TUNL_NULL = 0, /*!< Session routing tunnel type is No Tunnel action */ + GSW_ROUTE_TUNL_6RD = 1, /*!< Session routing tunnel type is 6rd */ + GSW_ROUTE_TUNL_DSLITE = 2, /*!< Session routing tunnel type is DSlite */ + GSW_ROUTE_TUNL_L2TP = 3, /*!< Session routing tunnel type is L2TP */ + GSW_ROUTE_TUNL_IPSEC = 4, /*!< Session routing tunnel type is IPsec */ + +} GSW_ROUTE_Session_Tunmode_t; /*! \brief This is the data structure for GSWIP Tunnel entry configuration Interface. */ -typedef struct -{ - /*@{*/ - GSW_ROUTE_Session_Tunmode_t eTunnelType; /*!< Tunnel type enum for DSLite, 6RD, IPSec, L2TP */ - /*@}*/ - /** - * @name Union tunnel - */ - - /*@{*/ - union { - GSW_ROUTE_Tunnel_6rd tun6RD; /*!< 6RD tunnel configuration */ - u32 nTunL2TP; /*!< L2TP tunnel configuration. Just a placeholder in union, since PAE only supports L2TP detunneling only */ - u32 nTunIPsec; /*!< IPsec crypto context configuration. GSWIP action not defined */ - GSW_ROUTE_Tunnel_DSLite tunDSlite; /*!< DSlite tunnel configuration */ - } t; - /*@}*/ +typedef struct { + /*@{*/ + GSW_ROUTE_Session_Tunmode_t eTunnelType; /*!< Tunnel type enum for DSLite, 6RD, IPSec, L2TP */ + /*@}*/ + /** + * @name Union tunnel + */ + + /*@{*/ + union { + GSW_ROUTE_Tunnel_6rd tun6RD; /*!< 6RD tunnel configuration */ + u32 nTunL2TP; /*!< L2TP tunnel configuration. Just a placeholder in union, since PAE only supports L2TP detunneling only */ + u32 nTunIPsec; /*!< IPsec crypto context configuration. GSWIP action not defined */ + GSW_ROUTE_Tunnel_DSLite tunDSlite; /*!< DSlite tunnel configuration */ + } t; + /*@}*/ } GSW_ROUTE_Tunnel_t; @@ -105,89 +97,83 @@ typedef struct /*! \brief This is the data structure for GSWIP Routing Session Direction. Used by \ref GSW_ROUTE_Session_action_t. */ -typedef enum -{ - GSW_ROUTE_DIRECTION_DNSTREAM = 0, /*!< Session is LAN egress i.e WAN Downstream */ - GSW_ROUTE_DIRECTION_UPSTREAM = 1, /*!< Session is LAN ingress i.e. WAN Upstream session */ -} GSW_ROUTE_Session_Direction_t; +typedef enum { + GSW_ROUTE_DIRECTION_DNSTREAM = 0, /*!< Session is LAN egress i.e WAN Downstream */ + GSW_ROUTE_DIRECTION_UPSTREAM = 1, /*!< Session is LAN ingress i.e. WAN Upstream session */ +} GSW_ROUTE_Session_Direction_t; /*! \brief This is the data structure for GSWIP Routing mode. Used by \ref GSW_ROUTE_Session_action_t. */ -typedef enum -{ - GSW_ROUTE_MODE_NULL = 0, /*!< Session routing type NULL. Can be used for Bridge sessions in RT table. */ - GSW_ROUTE_MODE_ROUTING = 1, /*!< Session routing type plain routing without NAT/NAPT*/ - GSW_ROUTE_MODE_NAT = 2, /*!< Session routing type is Src IP address NAT*/ - GSW_ROUTE_MODE_NAPT = 3, /*!< Session routing type is Src IP/Port NAT */ +typedef enum { + GSW_ROUTE_MODE_NULL = 0, /*!< Session routing type NULL. Can be used for Bridge sessions in RT table. */ + GSW_ROUTE_MODE_ROUTING = 1, /*!< Session routing type plain routing without NAT/NAPT*/ + GSW_ROUTE_MODE_NAT = 2, /*!< Session routing type is Src IP address NAT*/ + GSW_ROUTE_MODE_NAPT = 3, /*!< Session routing type is Src IP/Port NAT */ -} GSW_ROUTE_Session_Routmode_t; +} GSW_ROUTE_Session_Routmode_t; /*! \brief This is the data structure for GSWIP Routing Outer DSCP remarking action. Used by \ref GSW_ROUTE_Session_action_t. */ -typedef enum -{ - GSW_ROUTE_OUT_DSCP_NULL = 0, /*!< Session routing no outer DSCP remarking action */ - GSW_ROUTE_OUT_DSCP_INNER = 1, /*!< Session routing outer DSCP from inner IP header */ - GSW_ROUTE_OUT_DSCP_SESSION = 2, /*!< Session routing outer DSCP from session action table */ - GSW_ROUTE_OUT_DSCP_RES = 3, /*!< Session routing outer DSCP action reserved */ - +typedef enum { + GSW_ROUTE_OUT_DSCP_NULL = 0, /*!< Session routing no outer DSCP remarking action */ + GSW_ROUTE_OUT_DSCP_INNER = 1, /*!< Session routing outer DSCP from inner IP header */ + GSW_ROUTE_OUT_DSCP_SESSION = 2, /*!< Session routing outer DSCP from session action table */ + GSW_ROUTE_OUT_DSCP_RES = 3, /*!< Session routing outer DSCP action reserved */ + } GSW_ROUTE_Session_Outer_DSCP_Remarking_t; /** \brief Routing Session selection for IP Address - IPv4/IPv6/Unused. Used by \ref GSW_PCE_pattern_t. */ -typedef enum -{ - GSW_RT_IP_DISABLED = 0, /*!< Routing IP selection disabled. */ - GSW_RT_IP_V4 = 1, /*!< Routing IP selection type is IPv4. */ - GSW_RT_IP_V6 = 2 /*!< Routing IP selection type is IPv6. */ +typedef enum { + GSW_RT_IP_DISABLED = 0, /*!< Routing IP selection disabled. */ + GSW_RT_IP_V4 = 1, /*!< Routing IP selection type is IPv4. */ + GSW_RT_IP_V6 = 2 /*!< Routing IP selection type is IPv6. */ } GSW_RT_IP_t; /*! \brief This is the data structure for GSWIP Routing Session Pattern Interface. SrcIP, DstIP, SrcPort, DstPort & RoutingExtensionId together is used as input keys for lookup of Routing sessions. Except RoutingExtensionId other fields in pattern are optional and decided through PCE rule - IP and Port Compare Selector. */ -typedef struct -{ - GSW_RT_IP_t eIpType; /*!< IP Address Type - IPv4 or IPv6 or Unused */ - GSW_IP_t nSrcIP; /*!< The session source IPv4/v6 address used for hash computation. Internally this gets mapped to Routing IP Addr table. */ - GSW_IP_t nDstIP; /*!< The session destination IPv4/v6 address for hash computation. Internally this gets mapped to Routing IP Addr table. */ - u16 nSrcPort; /*!< TCP/UDP source port information - used in hash computation*/ - u16 nDstPort; /*!< TCP/UDP destination port information - used in hash computation*/ - u8 nRoutExtId; /*!< Routing extension Id from Flow Table action. Valid value any 8-bit integer also matching to output of Flow rule. Used in hash index computation */ - ltq_bool_t bValid; /*!< Indicate, if a particular routing entry is valid or not */ +typedef struct { + GSW_RT_IP_t eIpType; /*!< IP Address Type - IPv4 or IPv6 or Unused */ + GSW_IP_t nSrcIP; /*!< The session source IPv4/v6 address used for hash computation. Internally this gets mapped to Routing IP Addr table. */ + GSW_IP_t nDstIP; /*!< The session destination IPv4/v6 address for hash computation. Internally this gets mapped to Routing IP Addr table. */ + u16 nSrcPort; /*!< TCP/UDP source port information - used in hash computation*/ + u16 nDstPort; /*!< TCP/UDP destination port information - used in hash computation*/ + u8 nRoutExtId; /*!< Routing extension Id from Flow Table action. Valid value any 8-bit integer also matching to output of Flow rule. Used in hash index computation */ + ltq_bool_t bValid; /*!< Indicate, if a particular routing entry is valid or not */ } GSW_ROUTE_Session_pattern_t; /*! \brief This is the data structure for GSWIP Routing Session Action Interface. */ -typedef struct -{ +typedef struct { - u32 nDstPortMap; /*!< Session destination port map specified in form of bitmask. E.g. Starting with least significant - 0th Bit position denotes port no. 0, 1st bit position denotes port no. 1 and so on. Bit vale of 1 indicates port is specified and 0 indicates port is not specified*/ + u32 nDstPortMap; /*!< Session destination port map specified in form of bitmask. E.g. Starting with least significant - 0th Bit position denotes port no. 0, 1st bit position denotes port no. 1 and so on. Bit vale of 1 indicates port is specified and 0 indicates port is not specified*/ u16 nDstSubIfId; /*!< Session destination sub-interace Id. For multicast stream this field's GroupIndex part may carry the corresponding Group Id value. */ GSW_RT_IP_t eIpType; /*!< IP Address Type - IPv4 or IPv6 or Unused */ GSW_IP_t nNATIPaddr; /*!< Session new IP address after NAT for eIPType. */ - u16 nTcpUdpPort; /*!< Session new TCP/UDP port number. Used if eSessionRoutingMode is NAPT */ + u16 nTcpUdpPort; /*!< Session new TCP/UDP port number. Used if eSessionRoutingMode is NAPT */ u16 nMTUvalue; /*!< Session MTU value.*/ ltq_bool_t bMAC_SrcEnable; /*!< Source MAC address used */ u8 nSrcMAC[6]; /*!< New source MAC address for the session. */ ltq_bool_t bMAC_DstEnable; /*!< Destination MAC address used */ - u8 nDstMAC[6]; /*!< New destination MAC address for the session */ - ltq_bool_t bPPPoEmode; /*!< Session PPPoE mode. Value + u8 nDstMAC[6]; /*!< New destination MAC address for the session */ + ltq_bool_t bPPPoEmode; /*!< Session PPPoE mode. Value 0:PPPoE Mode transparent. 1:PPPoE Mode Termination*/ u16 nPPPoESessId; /*!< Session PPPoE Session Identifier used */ ltq_bool_t bTunnel_Enable; /*!< Tunnel used selector */ GSW_ROUTE_Session_Tunmode_t eTunType; /*!< Session Tunnel type used*/ u8 nTunnelIndex; /*!< Preconfigured tunnel Index. The tunnel Index maps to Tunnel table. First configure Tunnel entry and then set Index here (0..15) */ - ltq_bool_t bMeterAssign; /*!< MeterId assignment action. Value + ltq_bool_t bMeterAssign; /*!< MeterId assignment action. Value 0:Assignment disabled. 1:Assignment Enabled */ u8 nMeterId; /*!< Meter Id used for the session. The metering configuration can be done using differnt switch api function */ - ltq_bool_t bRTPMeasEna; /*!< RTP Multicast session's sequence number counter Action. Value + ltq_bool_t bRTPMeasEna; /*!< RTP Multicast session's sequence number counter Action. Value 0:Counting Disabled . 1:Counting Enabled */ u16 nRTPSeqNumber; /*!< 16 bit RTP sequence number for which the multicast packet will be counted */ @@ -195,18 +181,18 @@ typedef struct u8 nFID; /*!< Session FID. Value 0-63, Session FID is used for Egress VLAN action */ u8 nFlowId; /*!< Flow Id value. Value 0-255. Default value is 0. */ GSW_ROUTE_Session_Outer_DSCP_Remarking_t eOutDSCPAction; /*!< Outer DSCP remarking action - Valid for Tunnel associated entries */ - ltq_bool_t bInnerDSCPRemark; /*!< Session routing inner DSCP remarking action. Value + ltq_bool_t bInnerDSCPRemark; /*!< Session routing inner DSCP remarking action. Value 0: No remarking. - 1: remarking based on session */ + 1: remarking based on session */ u8 nDSCP; /*!< DSCP remarking value for the session */ - ltq_bool_t bTCremarking; /*!< Routing session traffic class remarking action. Value - 0: No remarking. + ltq_bool_t bTCremarking; /*!< Routing session traffic class remarking action. Value + 0: No remarking. 1: TC remarking enabled */ u8 nTrafficClass; /*!< Traffic class remarking value for the session */ - u32 nSessionCtrs; /*!< Session MIB Counters. - R-O */ + u32 nSessionCtrs; /*!< Session MIB Counters. - R-O */ GSW_ROUTE_Session_Direction_t eSessDirection; /*!<Session direction WAN-Downnstream or WAN-Upstream */ - GSW_ROUTE_Session_Routmode_t eSessRoutingMode; /*!< Session routing action mode */ - ltq_bool_t bTTLDecrement; /*!< Enable TTL decrement action for the session. Value + GSW_ROUTE_Session_Routmode_t eSessRoutingMode; /*!< Session routing action mode */ + ltq_bool_t bTTLDecrement; /*!< Enable TTL decrement action for the session. Value 0: TTL decrement disabled. 1: TTL decrement enabled.*/ ltq_bool_t bHitStatus; /*!< Session hit Status - RW.*/ @@ -216,203 +202,80 @@ typedef struct /*! \brief This is the data structure for GSWIP Routing Session Destination Information. */ -typedef struct -{ - u16 nRtIdx; /*!< Session Index */ - u32 nDstPortMap; /*!< Session destination port map specified in form of bit-mask with every bit position indicating corresponding port number.*/ - u16 nDstSubIfId; /*!< Session destination sub-interace Id. */ +typedef struct { + u16 nRtIdx; /*!< Session Index */ + u32 nDstPortMap; /*!< Session destination port map specified in form of bit-mask with every bit position indicating corresponding port number.*/ + u16 nDstSubIfId; /*!< Session destination sub-interace Id. */ } GSW_ROUTE_Session_Dest_t; /*! \brief This is the data structure for configuring Source L2NAT on egress port of PAE. */ -typedef struct -{ - ltq_bool_t bL2NATEna; /*!< Enable L2NAT on this egress port of PAE*/ - u16 nEgPortId; /*!< Egress Port Id */ - u8 nNatMAC[6]; /*!< New source MAC address for L2NAT on this egress port*/ +typedef struct { + ltq_bool_t bL2NATEna; /*!< Enable L2NAT on this egress port of PAE*/ + u16 nEgPortId; /*!< Egress Port Id */ + u8 nNatMAC[6]; /*!< New source MAC address for L2NAT on this egress port*/ } GSW_ROUTE_EgPort_L2NAT_Cfg_t; /*! \brief This is the data structure for GSWIP Routing Session Entry. */ -typedef struct -{ - GSW_ROUTE_Session_pattern_t pattern; /*!< The structure for routing session pattern parameters */ - GSW_ROUTE_Session_action_t action; /*!< The structure for routing session action associated with the above pattern */ +typedef struct { + GSW_ROUTE_Session_pattern_t pattern; /*!< The structure for routing session pattern parameters */ + GSW_ROUTE_Session_action_t action; /*!< The structure for routing session action associated with the above pattern */ } GSW_ROUTE_session_t; /*! - \brief This is the data structure for GSWIP Routing Session Table Entry. + \brief This is the data structure for GSWIP Routing Session Table Entry. */ -typedef struct -{ - int nHashVal; /*!< Routing Session Entry Hash Value - optional (valid range : 0..4095). When not supplied, carries a special value of (-1) */ - int nRtIndex; /*!< Routing Session Entry Index Value - returned in ADD operation. Mandatorily, to be passed for the rest of operations */ - GSW_ROUTE_session_t routeEntry; /*!< Routing Session pattern and action values. */ - ltq_bool_t bPrio; /*!< Indicate it is a priority session - mandatorily used in ADD. If set then it can replace normal session if table is full*/ - u32 nFlags; /*!< Flags to indicate special status E.g. - Swap done (1), Free (2), etc. */ +typedef struct { + int nHashVal; /*!< Routing Session Entry Hash Value - optional (valid range : 0..4095). When not supplied, carries a special value of (-1) */ + int nRtIndex; /*!< Routing Session Entry Index Value - returned in ADD operation. Mandatorily, to be passed for the rest of operations */ + GSW_ROUTE_session_t routeEntry; /*!< Routing Session pattern and action values. */ + ltq_bool_t bPrio; /*!< Indicate it is a priority session - mandatorily used in ADD. If set then it can replace normal session if table is full*/ + u32 nFlags; /*!< Flags to indicate special status E.g. - Swap done (1), Free (2), etc. */ } GSW_ROUTE_Entry_t; /*! - \brief This is the data structure for GSWIP Routing Tunnel Table Entry. + \brief This is the data structure for GSWIP Routing Tunnel Table Entry. */ -typedef struct -{ - int nTunIndex; /*!< Tunnel table entry index, optional in case of Add operation (-1). When (-1) is supplied the API would return assigned index */ - GSW_ROUTE_Tunnel_t tunnelEntry; /*!< Tunnel Table Entry */ +typedef struct { + int nTunIndex; /*!< Tunnel table entry index, optional in case of Add operation (-1). When (-1) is supplied the API would return assigned index */ + GSW_ROUTE_Tunnel_t tunnelEntry; /*!< Tunnel Table Entry */ -}GSW_ROUTE_Tunnel_Entry_t; +} GSW_ROUTE_Tunnel_Entry_t; /*! \brief This is the enumeration for GSWIP Routing Hit Status action. Used by \ref GSW_ROUTE_Session_Hit_t. */ -typedef enum -{ - GSW_ROUTE_HIT_READ = 0, /*!< Session routing Hit Status Read Action */ - GSW_ROUTE_HIT_CLEAR = 1, /*!< Session routing Hit Status Clear Action */ - GSW_ROUTE_HIT_N_CNTR_READ = 2, /*!< Session routing Hit Status & Session Counters Read Action */ - GSW_ROUTE_HIT_N_CNTR_CLEAR = 3 /*!< Session routing Hit Status & Session Counters Clear Action */ -}GSW_ROUTE_Session_HitOp_t; +typedef enum { + GSW_ROUTE_HIT_READ = 0, /*!< Session routing Hit Status Read Action */ + GSW_ROUTE_HIT_CLEAR = 1, /*!< Session routing Hit Status Clear Action */ + GSW_ROUTE_HIT_N_CNTR_READ = 2, /*!< Session routing Hit Status & Session Counters Read Action */ + GSW_ROUTE_HIT_N_CNTR_CLEAR = 3 /*!< Session routing Hit Status & Session Counters Clear Action */ +} GSW_ROUTE_Session_HitOp_t; /*! \brief This is the data structure for handling Session Hit Status in PAE. */ -typedef struct -{ - GSW_ROUTE_Session_HitOp_t eHitOper; /*!< Session Hit Operation */ - int nRtIndex; /*!< Routing Session Index */ - ltq_bool_t bHitStatus; /*!< Session Hit Status*/ - u32 nSessCntr; /*!< Session Counter - Packet or Bytes programmed using RMON API */ -}GSW_ROUTE_Session_Hit_t; - -#if 0 -/** \addtogroup GSWIP_ROUTE_API */ -/*@{*/ - -/** - \brief This function creates a Routing Session entry in the Routing-Session table. - The pattern part describes the five tuple serving as input key on which hash computation should be done on an incoming packet to which the dedicated actions should be applied. - A rule can be deleted using the command \ref GSW_ROUTE_SessionEntryDel or read using the command \ref GSW_ROUTE_SessionEntryRead. - \param[in] pDevCtx device context - \param[in, out] pRtEntry Pointer to Routing Entry structure \ref GSW_ROUTE_Entry_t. The nHashVal is optional and can be supplied (-1). The nPrio field is carrying the priority information - 1 (Priority session), 0 (Normal session). Upon return of API, nHashVal and nRtIndex carries back computed hash value and Index location. In case of swap of an existent session by a high priority new session, the existing session that got removed from acceleration is returned back in routeEntry struct member. The swap done is informed through nFlag member carrying special value(1). - \return Return value as follows: - - Routing session index number >=0 : if successful - - An error code < 0 in case an error occurs. There has to be detailed error codes covering the maximum reasons : - E.g. Collision List is full, RT_Table full, PPPoE_table full, MTU table full etc. -*/ -int GSW_ROUTE_SessionEntryAdd (void *pDevCtx, GSW_ROUTE_Entry_t *pRtEntry); - -/** - \brief This function deletes a Routing Session entry at specififed index in the Routing-Session table. - A rule can be created using the command \ref GSW_ROUTE_SessionEntryAdd - \param[in] pDevCtx device context - \param[in] pRtEntry Routing Session Entry carrying mandatory nRtIndex value. - \return Return value as follows: - - GSW_SUCCESS : if successful - - An error code < 0 in case an error occurs. -*/ -int GSW_ROUTE_SessionEntryDel (void *pDevCtx, GSW_ROUTE_Entry_t *pRtEntry); - -/** - \brief This function reads a session entry in the Routing session table at an specified index. The index must be valid entry of the routing index table. - \param[in] pDevCtx device context. - \param[in,out] pRtEntry Pointer to Routing Session Entry structure \ref GSW_ROUTE_Entry_t. - \return Return value as follows: - - GSW_SUCCESS: if successful - - An error code < 0, in case an error occurs -*/ -int GSW_ROUTE_SessionEntryRead(void *pDevCtx, GSW_ROUTE_Entry_t *pRtEntry); - -/** - \brief This function creates a tunnel entry in the Tunnel table. For complete configuration of tunnel, it is a multi-step config. Besides tunnel entry creation in tunnel table, it should also be programmed in RoutingSession table. - A configured tunnel entry can be read using the command \ref GSW_ROUTE_TunnelEntryRead - \param[in] pDevCtx device context - \param[in] nTunIdx Tunnel Index number, where the Tunnel entry is stored in the Tunnel Table. A value of -1 is used to indicate the index is not passed by caller. - \param[in] pTunnel Pointer to Tunnel structure \ref GSW_ROUTE_Tunnel_t. - \return Return value as follows: - - Tunnel Entry index number >=0 : if successful (Number of Tunnels supported are 16 so return value is 0..15 range) - - An error code < 0 in case an error occurs -*/ -int GSW_ROUTE_TunnelEntryAdd(void *pDevCtx, int nTunIdx, GSW_ROUTE_Tunnel_t *pTunnel); - -/** - \brief This function deletes a tunnel entry in the Tunnel table. - \param[in] pDevCtx device context - \param[in] nTunIdx number, where the Tunnel entry is stored in the Tunnel Table. - \return Return value as follows: - - Tunnel Entry index number >=0 : if successful - - An error code < 0 in case an error occurs -*/ -int GSW_ROUTE_TunnelEntryDel(void *pDevCtx, int nTunIdx); - -/** - \brief This function reads a tunnel entry in the Tunnel table at an specified index. The index must be valid entry of the Tunnel index table. - \param[in] pDevCtx device context. - \param[in] nTunIdx Index number, where the tunnel is stored. - \param[out] pTunnel Pointer to Tunnel structure \ref GSW_ROUTE_Tunnel_t. - \return Return value as follows: - - GSW_SUCCESS: if successful - - An error code in case an error occurs -*/ -int GSW_ROUTE_TunnelEntryRead(void *pDevCtx, int nTunIdx, GSW_ROUTE_Tunnel_t *pTunnel); - -/** - \brief This function configures a Source L2NAT on an egress port. - A configured tunnel entry can be read using the command \ref GSW_ROUTE_TunnelEntryRead - \param[in] pDevCtx device context - \param[in] pL2NatCfg Pointer to Tunnel structure \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. - - \return Return value as follows: - - Tunnel Entry index number >=0 : if successful - - An error code < 0 in case an error occurs -*/ -int GSW_ROUTE_L2NATCfgWrite(void *pDevCtx, GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); - -/** - \brief This function reads currently configured L2NAT entry in the Tunnel table for the specified port. The port number must be a valid number. - \param[in] pDevCtx device context. - \param[in,out] pL2NatCfg Pointer to L2NAT Config structure \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. The port number must be filled in this structure. - \return Return value as follows: - - GSW_SUCCESS: if successful - - An error code in case an error occurs -*/ -int GSW_ROUTE_L2NATCfgRead(void *pDevCtx, GSW_ROUTE_EgPort_L2NAT_Cfg_t *pL2NatCfg); - -/** - \brief This function reads or reads-n-clears Session Hit Sttaus for the specified index. - \param[in] pDevCtx device context. - \param[in,out] pHitOp Pointer to Session-Hit structure \ref GSW_ROUTE_Session_Hit_t. The index number must be filled in this structure. - \return Return value as follows: - - 0: Showing Session is not Hit. - - 1: Showing Session is Hit. - - (-1): In case of any error in reading or writing Session Hit Status. - - An error code in case an error occurs -*/ -int GSW_ROUTE_SessHitOp(void *pDevCtx, GSW_ROUTE_Session_Hit_t *pHitOp); - -/** - \brief This function modifies the destination ports of Routing Session. - \param[in] pDevCtx device context. - \param[in,out] pDestCfg Pointer to destination structure \ref GSW_ROUTE_Session_Dest_t. - \return Return value as follows: - - GSW_SUCCESS : if successful. - - An error code in case an error occurs -*/ -int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); -/*@}*/ /* GSWIP_ROUTE_API */ -#endif /* #if 0 */ +typedef struct { + GSW_ROUTE_Session_HitOp_t eHitOper; /*!< Session Hit Operation */ + int nRtIndex; /*!< Routing Session Index */ + ltq_bool_t bHitStatus; /*!< Session Hit Status*/ + u32 nSessCntr; /*!< Session Counter - Packet or Bytes programmed using RMON API */ +} GSW_ROUTE_Session_Hit_t; /** \brief This command adds a routing session of specified pattern and action. The pattern part describes the parameters to identify an incoming packet session to which the dedicated actions should be applied. Packets having the same pattern field belongs to same session and applied to same action. A routing rule and action can be read using the command \ref GSW_ROUTE_ENTRY_READ. - \remarks If a priority session addition is attempted and there is no space for new session then one of the existing normal session would be replaced by this new priority session. The replaced entry is returned in this case through GSW_Route_Entry_t pointer. - \param GSW_ROUTE_Entry_t Pointer to \ref GSW_ROUTE_Entry_t containing the session information filled by ioctl caller. This structure carries the config of replaced entry when swapped by high priority entry. + \remarks If a priority session addition is attempted and there is no space for new session then one of the existing normal session would be replaced by this new priority session. The replaced entry is returned in this case through GSW_Route_Entry_t pointer. + \param GSW_ROUTE_Entry_t Pointer to \ref GSW_ROUTE_Entry_t containing the session information filled by ioctl caller. This structure carries the config of replaced entry when swapped by high priority entry. - \remarks If any error happens during creation of session or configuring the individual unit tables, this error code of negative value is conveyed back to caller. + \remarks If any error happens during creation of session or configuring the individual unit tables, this error code of negative value is conveyed back to caller. \return Return value as follows: - GSW_SUCCESS: if successful @@ -423,7 +286,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); /** \brief This command deletes an earlier added routing session of specified index and pattern. It is must specify the index returned during creation. The pattern part is only used for comparing with the pattern stored in index. A routing rule and action of specified index can be read using the command \ref GSW_ROUTE_ENTRY_READ. - \param GSW_ROUTE_Entry_t Pointer to \ref GSW_ROUTE_Entry_t containing the session information filled by ioctl caller. This structure carries the config of replaced entry when swapped by high prirority entry. + \param GSW_ROUTE_Entry_t Pointer to \ref GSW_ROUTE_Entry_t containing the session information filled by ioctl caller. This structure carries the config of replaced entry when swapped by high prirority entry. \return Return value as follows: - GSW_SUCCESS: if successful @@ -448,7 +311,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); /** \brief This command adds a new Tunnel entry in the Routing Tunnel table. The Tunnel entry can be read using the command \ref GSW_ROUTE_TUNNEL_ENTRY_READ. - \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the values of a tunnel type and associated attributes. + \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the values of a tunnel type and associated attributes. \return Return value as follows: - GSW_SUCCESS: if successful @@ -459,7 +322,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); /** \brief This command deletes a specified Tunnel entry in the Routing Tunnel table. The Tunnel entry can be read using the command \ref GSW_ROUTE_TUNNEL_ENTRY_READ. - \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the Tunnel-Index and tunnel config values. The values are used to match and perform verification with stored values in Tunnel table at specified index. + \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the Tunnel-Index and tunnel config values. The values are used to match and perform verification with stored values in Tunnel table at specified index. \return Return value as follows: - GSW_SUCCESS: if successful @@ -471,7 +334,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); \brief This command reads the Tunnel values from the routing Tunnel table at a given specified Tunnel Index. A Tunnel entry can be written using the command \ref GSW_ROUTE_TUNNEL_ENTRY_ADD. - \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the Tunnel-Index as input. The tunnel config values at specified index is returned back to caller. + \param GSW_ROUTE_Tunnel_Entry_t Pointer to \ref GSW_ROUTE_Tunnel_Entry_t containing the Tunnel-Index as input. The tunnel config values at specified index is returned back to caller. \return Return value as follows: - GSW_SUCCESS: if successful @@ -480,10 +343,10 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); #define GSW_ROUTE_TUNNEL_ENTRY_READ _IOWR(GSW_ROUTE_MAGIC, 0x05, GSW_ROUTE_Tunnel_Entry_t) /** - \brief This command configures L2NAT on egress port of PAE. When enabled the Source MAC Address of + \brief This command configures L2NAT on egress port of PAE. When enabled the Source MAC Address of traffic leaving specified egress port would be NAT-ed with configured MAC address. - \param GSW_ROUTE_EgPort_L2NAT_Cfg_t L2NAT Attributes as defined in \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. + \param GSW_ROUTE_EgPort_L2NAT_Cfg_t L2NAT Attributes as defined in \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. \return Return value as follows: - GSW_SUCCESS: if successful @@ -494,7 +357,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); /** \brief This command reads L2NAT configurations on specified egress port of PAE. - \param GSW_ROUTE_EgPort_L2NAT_Cfg_t L2NAT Attributes as defined in \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. + \param GSW_ROUTE_EgPort_L2NAT_Cfg_t L2NAT Attributes as defined in \ref GSW_ROUTE_EgPort_L2NAT_Cfg_t. \return Return value as follows: - GSW_SUCCESS: if successful @@ -505,7 +368,7 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); /** \brief This command reads or reads-n-clears Hit-Status for high priority sessions. - \param GSW_ROUTE_Session_Hit_t Hit Status Data struct carrying operation. + \param GSW_ROUTE_Session_Hit_t Hit Status Data struct carrying operation. \return Return value is Session Hit Status: - 1 : if session status is Hit (before cleared). @@ -513,19 +376,19 @@ int GSW_ROUTE_SessDestModify(void *pDevCtx, GSW_ROUTE_Session_Dest_t *pDestCfg); - (-1) : if any error is encountered. */ -#define GSW_ROUTE_SESSION_HIT_OP _IOWR(GSW_ROUTE_MAGIC, 0x09, GSW_ROUTE_Session_Hit_t) +#define GSW_ROUTE_SESSION_HIT_OP _IOWR(GSW_ROUTE_MAGIC, 0x09, GSW_ROUTE_Session_Hit_t) /** \brief This command modifies the destination of an existing Routing session. - \param GSW_ROUTE_Session_Dest_t Data struct carrying Routing session index and destination portmap & sub-interface configuration. + \param GSW_ROUTE_Session_Dest_t Data struct carrying Routing session index and destination portmap & sub-interface configuration. - \return Return value is + \return Return value is - GSW_SUCCESS : if successful. - An error code in case an error occurs */ -#define GSW_ROUTE_SESSION_DEST_MOD _IOWR(GSW_ROUTE_MAGIC, 0x0A, GSW_ROUTE_Session_Dest_t) +#define GSW_ROUTE_SESSION_DEST_MOD _IOWR(GSW_ROUTE_MAGIC, 0x0A, GSW_ROUTE_Session_Dest_t) /*@}*/ /* PAE_API */ diff --git a/include/net/switch_api/mac_ops.h b/include/net/switch_api/mac_ops.h index b19bee904e24e9b0c26ef34d63da779c419c3e3d..57c8af04cf3a6f2d1fff2ed489df69bdbba173fa 100644 --- a/include/net/switch_api/mac_ops.h +++ b/include/net/switch_api/mac_ops.h @@ -10,45 +10,47 @@ #ifndef _MAC_OPS_H_ #define _MAC_OPS_H_ -#include <linux/types.h> +#include "gsw_irq.h" +#include "gsw_types.h" struct mac_ops { - /* This function Sets the Flow Control operation in Both XGMAC and LMAC. + /* This function Sets the Flow Ctrl operation in Both XGMAC and LMAC. * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * param[in/out]IN: mode 0 - Auto Mode based on GPHY/XPCS link information. - * 1 - Flow Control enabled only in RX - * 2 - Flow Control enabled only in TX - * 3 - Flow Control enabled both in RX & TX - * 4 - Flow Control disabled both in RX & TX - * return OUT 0:Flow Control operation Set Succesfully - * return OUT !0:Flow Control operation Set Error + * param[in/out]IN: mode 0 - Auto Mode based on GPHY/XPCS link. + * 1 - Flow Ctrl enabled only in RX + * 2 - Flow Ctrl enabled only in TX + * 3 - Flow Ctrl enabled both in RX & TX + * 4 - Flow Ctrl disabled both in RX & TX + * return OUT 0:Flow Ctrl operation Set Successfully + * return OUT !0:Flow Ctrl operation Set Error */ int(*set_flow_ctl)(void *, u32); - /* This function Gets the Flow Control operation in Both XGMAC and LMAC. + /* This function Gets the Flow Ctrl operation in Both XGMAC and LMAC. * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * return OUT: mode 0 - Auto Mode based on GPHY/XPCS link information. - * 1 - Flow Control enabled only in RX - * 2 - Flow Control enabled only in TX - * 3 - Flow Control enabled both in RX & TX - * 4 - Flow Control disabled both in RX & TX - * return OUT -1: Flow Control operation Get Error + * return OUT: mode 0 - Auto Mode based on GPHY/XPCS link. + * 1 - Flow Ctrl enabled only in RX + * 2 - Flow Ctrl enabled only in TX + * 3 - Flow Ctrl enabled both in RX & TX + * 4 - Flow Ctrl disabled both in RX & TX + * return OUT -1: Flow Ctrl operation Get Error */ int(*get_flow_ctl)(void *); /* This function Resets the MAC module. * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * return OUT 0: Reset of MAC module Done Succesfully + * return OUT 0: Reset of MAC module Done Successfully * return OUT -1: Reset of MAC module Error */ int(*mac_reset)(void *); /* This function Configures MAC Loopback. * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * param[in/out]IN: val 1 - Loopback Enable, 0 - Loopback Disable + * param[in/out]IN: val 1 - Loopback Enable, 0 - Loopback Dis * return OUT -1: Loopback Set Error */ int(*mac_config_loopback)(void *, u32); /* This function Configures MAC IPG. * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * param[in/out]IN: IPG val Value is from 0 - 7, where 0 denotes the default 96 bits + * param[in/out]IN: IPG val Value is from 0 - 7, + * where 0 denotes the default 96 bits * 000: 96 bit * 001: 128 bit * 010: 160 bit @@ -65,7 +67,7 @@ struct mac_ops { * 100 - 100Mbps * 1000 - 1Gbps * 25000 - 2.5Gbps - 100000 - 10Gbps + * 100000 - 10Gbps * return OUT -1: Speed Set Error */ @@ -163,7 +165,7 @@ struct mac_ops { */ int(*set_mtu)(void *, u32); /* This function Gets the MTU Configuration - * param[in/out]IN: ops MAC Operation Structure registered for MAC 0/1/2. + * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * return OUT: MTU * MTU configured * return OUT -1: MTU Get Error @@ -191,8 +193,8 @@ struct mac_ops { * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: val FCS generation Configuration * 0 - CRC and PAD insertion are enabled. - * 1 - CRC insertion enable and PAD insertion disable - * 2 - CRC and PAD are not inserted and not replaced. + * 1 - CRC insert enable and PAD insert disable + * 2 - CRC and PAD are not insert and not replaced. * return OUT -1: FCS generation Set Error */ int(*set_fcsgen)(void *, u32); @@ -200,28 +202,44 @@ struct mac_ops { * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * return OUT: val FCS generation Configuration * 0 - CRC and PAD insertion are enabled. - * 1 - CRC insertion enable and PAD insertion disable - * 2 - CRC and PAD are not inserted and not replaced. + * 1 - CRC insert enable and PAD insert disable + * 2 - CRC and PAD are not insert and not replaced. * return OUT -1: FCS generation Get Error */ int(*get_fcsgen)(void *); + /* This function Clears MAC Interrupt Status + * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. + * param[in/out]IN: event Difffernt events to clear + * return OUT : Cleared return status + */ + int(*clr_int_sts)(void *, u32); + /* This function Gets MAC Interrupt Status + * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. + * return OUT : Interrupts Pending + */ + int(*get_int_sts)(void *); /* This function Initializes System time Configuration * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * param[in/out]IN: sec Initial seconds value to be configured in register - * param[in/out]IN: nsec Initial nano-seconds value to be configured in register + * param[in/out]IN: sec Initial seconds value to be configured + * in register + * param[in/out]IN: nsec Initial nano-seconds value to be + * configured in register * return OUT -1: System time Configuration Set Error */ int(*init_systime)(void *, u32, u32); /* This function Configures addend value * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: addend - * The Timestamp Addend register is present only when the IEEE 1588 Timestamp feature is selected without - * external timestamp input. This register value is used only when the system time is configured for Fine - * Update mode (TSCFUPDT bit in the MAC_Timestamp_Control register). The content of this register is - * added to a 32-bit accumulator in every clock cycle and the system time is updated - * whenever the accumulator overflows. - * This field indicates the 32-bit time value to be added to the Accumulator register to achieve time - * synchronization. + * The Timestamp Addend register is present only when the IEEE 1588 + * Timestamp feature is selected without + * external timestamp input. This register value is used only when the + * system time is configured for Fine + * Update mode (TSCFUPDT bit in the MAC_Timestamp_Ctrl register). + * The content of this register is + * added to a 32-bit accumulator in every clock cycle and the + * system time is updated whenever the accumulator overflows. + * This field indicates the 32-bit time value to be added to the + * Accumulator register to achieve time synchronization. * return OUT -1: Addend Configuration Set Error */ int(*config_addend)(void *, u32); @@ -230,9 +248,9 @@ struct mac_ops { * param[in/out]IN: sec New seconds value to be configured * param[in/out]IN: nsec New nano seconds value to be configured * param[in/out]IN: addsub Add or Subtract Time - * When this bit is set, the time value is subtracted with the contents of the - * update register. When this bit is reset, the time value is added with the - * contents of the update register. + * When this bit is set, the time value is subtracted with the + * contents of the update register. When this bit is reset, + * the time value is added with the contents of the update register. * param[in/out]IN: one_nsec_accuracy * If the new nsec value need to be subtracted with * the system time, then MAC_STNSUR.TSSS field should be @@ -249,25 +267,36 @@ struct mac_ops { u64(*get_systime)(void *); /* This sequence is used get Transmitted 64-bit system time in nano sec * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. - * return OUT u64: Transmitted 64-bit system time in nano sec + * return OUT u64: Tx 64-bit system time in nano sec */ u64(*get_tx_tstamp)(void *); - /* This sequence is used Configure HW TimeStamping TX/RX filter Configuration + /* This sequence is used get Tx Transmitted capture count + * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. + * return OUT u32: Tx Timestamp capture count + */ + int(*get_txtstamp_cap_cnt)(void *); + /* This sequence is used Configure HW TimeStamping TX/RX filter Cfg * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: tx_type: 1/0 - ON/OFF - * param[in/out]IN: rx_filter: This is based on Table 7-146, Receive side timestamp Capture scenarios + * param[in/out]IN: rx_filter: This is based on Table 7-146, + * Receive side timestamp Capture scenarios * return OUT -1: Configure HW TimeStamping Set Error */ int(*config_hw_time_stamping)(void *, u32, u32); /* This sequence is used ConfigureSub Second Increment * param[in/out]IN: ops MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: ptp_clk: PTP Clock Value in Hz - * The value programmed in this field is accumulated with the contents of the sub-second register. - * For example, when the PTP clock is 50 MHz (period is 20 ns), you should program 20 (0x14) - * when the System TimeNanoseconds register has an accuracy of 1 ns [Bit 9 (TSCTRLSSR) is set in MAC_Timestamp_Control]. - * When TSCTRLSSR is clear, the Nanoseconds register has a resolution of ~0.465 ns. In this case, you - * should program a value of 43 (0x2B) which is derived by 20 ns/0.465. - * return OUT -1: Configure Sub Second Inccrement Error + * The value programmed in this field is accumulated with the + * contents of the sub-second register. + * For example, when the PTP clock is 50 MHz (period is 20 ns), + * you should program 20 (0x14) + * when the System TimeNanoseconds register has an accuracy + * of 1 ns [Bit 9 (TSCTRLSSR) is set in MAC_Timestamp_Ctrl]. + * When TSCTRLSSR is clear, the Nanoseconds register has a + * resolution of ~0.465 ns. In this case, you + * should program a value of 43 (0x2B) + * which is derived by 20 ns/0.465. + * return OUT -1: Configure Sub Second Inccrement Error */ int(*config_subsec_inc)(void *, u32); /* This sequence is used Initialize MAC @@ -301,7 +330,7 @@ struct mac_ops { /* This sequence is used for Writing XGMAC register * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: u16 - Register Offset. - * param[in/out]IN: u32 - Register Value. + * param[in/out]IN: u32 - Register Value. */ void(*xgmac_reg_wr)(void *, u16, u32); /* This sequence is used for Reading LMAC register @@ -313,9 +342,43 @@ struct mac_ops { /* This sequence is used for Writing LMAC register * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. * param[in/out]IN: u16 - Register Offset. - * param[in/out]IN: u32 - Register Value. + * param[in/out]IN: u32 - Register Value. + */ + void(*lmac_reg_wr)(void *, u32, u32); + /* This sequence is used for Registering IRQ Callback for a event + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * param[in/out]IN: GSW_Irq_Op_t - IRQ event info. + * return OUT int - Success/Fail + */ + int (*IRQ_Register)(void *, GSW_Irq_Op_t *); + /* This sequence is used for UnRegistering IRQ Callback for a event + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * param[in/out]IN: GSW_Irq_Op_t - IRQ event info. + * return OUT int - Success/Fail + */ + int (*IRQ_UnRegister)(void *, GSW_Irq_Op_t *); + /* This sequence is used for Enabling IRQ for a event + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * param[in/out]IN: GSW_Irq_Op_t - IRQ event info. + * return OUT int - Success/Fail + */ + int (*IRQ_Enable)(void *, GSW_Irq_Op_t *); + /* This sequence is used for Disabling IRQ for a event + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * param[in/out]IN: GSW_Irq_Op_t - IRQ event info. + * return OUT int - Success/Fail + */ + int (*IRQ_Disable)(void *, GSW_Irq_Op_t *); + /* This sequence is used for Enabling MAC Interrupt + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * return OUT int - Success/Fail + */ + int (*mac_int_en)(void *); + /* This sequence is used for Disabling MAC Interrupt + * param[in/out]IN: ops - MAC ops Struct registered for MAC 0/1/2. + * return OUT int - Success/Fail */ - void(*lmac_reg_wr)(void *, u32, u32); + int (*mac_int_dis)(void *); }; #endif