Merge branch 'drop8' into merge8
Change-Id: I88df2af9ce53bbcf0fe8bd78b64666423820d71d
diff --git a/arch/arm/mach-feroceon-kw2/include/mach/system.h b/arch/arm/mach-feroceon-kw2/include/mach/system.h
index b426fee..1f26045 100755
--- a/arch/arm/mach-feroceon-kw2/include/mach/system.h
+++ b/arch/arm/mach-feroceon-kw2/include/mach/system.h
@@ -31,7 +31,7 @@
cpu_do_idle();
}
-#define UPON_SDK_VERSION "uPON_2.7.25_RC5"
+#define UPON_SDK_VERSION "uPON_2.7.25_RC8"
#ifdef __BIG_ENDIAN
#define MV_ARM_32BIT_LE(X) ((((X)&0xff)<<24) | \
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_app.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_app.c
index 8c77fd6..2fe434a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_app.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_app.c
@@ -1295,16 +1295,6 @@
/* U/S */
if(flow_rule.dir == CPH_DIR_US)
{
- /* Copy a new SKB */
- skb_old->tail += rx_desc->dataSize;
- skb_old->len = rx_desc->dataSize;
- skb_new = skb_copy(skb_old, GFP_ATOMIC);
- if(skb_new == NULL)
- {
- skb_new = skb_old;
- goto out;
- }
-
/* Forward packet to peer port */
rc = cph_app_parse_peer_port(port, &peer_port);
if (rc != MV_OK)
@@ -1313,8 +1303,21 @@
return 0;
}
+ MV_CPH_PRINT(CPH_DEBUG_LEVEL, "peer_port=%d\n", peer_port);
+
/* Forward packet */
- mv_net_devs[peer_port]->netdev_ops->ndo_start_xmit(skb_old, mv_net_devs[peer_port]);
+ if (netif_running(mv_net_devs[peer_port])) {
+ /* Copy a new SKB */
+ skb_old->tail += rx_desc->dataSize;
+ skb_old->len = rx_desc->dataSize;
+ skb_new = skb_copy(skb_old, GFP_ATOMIC);
+ if(skb_new == NULL)
+ {
+ skb_new = skb_old;
+ goto out;
+ }
+ mv_net_devs[peer_port]->netdev_ops->ndo_start_xmit(skb_old, mv_net_devs[peer_port]);
+ }
}
out:
/* Stripe VLAN tag, then send to Linux network stack */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_db.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_db.c
index 6e4d062..5ad8385 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_db.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_db.c
@@ -1282,7 +1282,7 @@
/* Print TX/RX direction */
if (parse_bm & CPH_APP_PARSE_FIELD_RX_TX)
{
- printk(KERN_INFO "RX/TX(%s), ", cph_app_lookup_rx_tx(parse_key->dir));
+ printk(KERN_INFO "RX/TX(%s), ", cph_app_lookup_rx_tx(parse_key->rx_tx));
}
/* Print Marvell header */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.c
index aae2125..7014319 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.c
@@ -147,7 +147,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_db_get_rule (CPH_FLOW_ENTRY_T *flow, BOOL for_packet)
@@ -201,6 +201,66 @@
}
/******************************************************************************
+* cph_flow_get_rule_by_vid()
+* _____________________________________________________________________________
+*
+* DESCRIPTION: Get CPH flow mapping rule by VID, only used to compare packet and db rule.
+*
+* INPUTS:
+* flow - Flow parsing field values
+* for_packet - Whether get rule for packet or for new CPH rule
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns MV_OK.
+* On error returns error code accordingly.
+*******************************************************************************/
+MV_STATUS cph_flow_get_rule_by_vid (CPH_FLOW_ENTRY_T *flow)
+{
+ UINT32 idx = 0;
+ UINT32 rule_idx = 0;
+ CPH_FLOW_ENTRY_T *p_flow_rule = NULL;
+ BOOL rc = FALSE;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gs_flow_table.flow_lock, flags);
+ /* Traverse CPH flow rule table */
+ for (idx = 0, rule_idx = 0; (idx < CPH_FLOW_ENTRY_NUM) && (rule_idx < gs_flow_table.rule_num); idx++)
+ {
+ p_flow_rule = &gs_flow_table.flow_rule[idx];
+
+ /* Compare packet or new rule rule data base rule */
+ if (p_flow_rule->valid == TRUE)
+ {
+ rule_idx++;
+
+ rc = cph_flow_compare_packet_and_rule_vid(flow, p_flow_rule);
+ if (rc == TRUE)
+ {
+ flow->op_type = p_flow_rule->op_type;
+ memcpy(&flow->mod_outer_tci, &p_flow_rule->mod_outer_tci, sizeof(CPH_FLOW_TCI_T));
+ memcpy(&flow->mod_inner_tci, &p_flow_rule->mod_inner_tci, sizeof(CPH_FLOW_TCI_T));
+ memcpy(&flow->pkt_frwd, &p_flow_rule->pkt_frwd, sizeof(CPH_FLOW_FRWD_T));
+
+ /* Increase count */
+ if (p_flow_rule->count == 0xFFFFFFFF)
+ p_flow_rule->count = 0;
+ else
+ p_flow_rule->count++;
+
+ spin_unlock_irqrestore(&gs_flow_table.flow_lock, flags);
+ return MV_OK;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&gs_flow_table.flow_lock, flags);
+
+ return MV_FAIL;
+}
+
+/******************************************************************************
* cph_flow_db_add_rule()
* _____________________________________________________________________________
*
@@ -213,7 +273,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_db_add_rule(CPH_FLOW_ENTRY_T *cph_flow)
@@ -278,7 +338,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_db_del_rule (CPH_FLOW_ENTRY_T *flow)
@@ -330,7 +390,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_db_clear_rule (VOID)
@@ -362,7 +422,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_db_clear_rule_by_mh (UINT16 mh)
@@ -403,7 +463,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_db_init (VOID)
@@ -433,6 +493,7 @@
* INPUTS:
* tci - TPID, VLAN ID, P-bits information.
* parse_field - Whether the TCI is from parsing field.
+* tci_field - the TCI field need to be checked.
*
* OUTPUTS:
* None.
@@ -441,18 +502,16 @@
* On success, the function returns TRUE.
* On error returns FALSE.
*******************************************************************************/
-BOOL cph_flow_verify_tci(CPH_FLOW_TCI_T *tci, BOOL parse_field)
+BOOL cph_flow_verify_tci(CPH_FLOW_TCI_T *tci, BOOL parse_field, CPH_TCI_FIELD_E tci_field)
{
UINT16 max_vid = 0;
UINT16 max_pbits = 0;
- if (parse_field == TRUE)
- {
+ if (TRUE == parse_field) {
max_vid = MV_CPH_VID_NOT_CARE_VALUE;
max_pbits = MV_CPH_PBITS_NOT_CARE_VALUE;
}
- else
- {
+ else {
max_vid = MV_VLAN_ID_MAX;
max_pbits = MV_PBITS_MAX;
}
@@ -467,16 +526,24 @@
}
/* Check VID */
+ if ((tci_field == CPH_TCI_FIELD_VID) ||
+ (tci_field == CPH_TCI_FIELD_VID_PBIT) ||
+ (tci_field == CPH_TCI_FIELD_ALL)) {
if (tci->vid > max_vid) {
MV_CPH_PRINT(CPH_ERR_LEVEL, "vid[%d] exceeds maximum value[%d] \n", tci->vid, max_vid);
return FALSE;
}
+ }
/* Check P-bits */
+ if ((tci_field == CPH_TCI_FIELD_PBIT) ||
+ (tci_field == CPH_TCI_FIELD_VID_PBIT) ||
+ (tci_field == CPH_TCI_FIELD_ALL)) {
if (tci->pbits > max_pbits) {
MV_CPH_PRINT(CPH_ERR_LEVEL, "pbits[%d] exceeds maximum value[%d] \n", tci->pbits, max_pbits);
return FALSE;
}
+ }
return TRUE;
}
@@ -536,22 +603,79 @@
}
/* Check TCI */
- rc = cph_flow_verify_tci(&cph_flow->parse_outer_tci, TRUE);
+ if ((parse_bm & CPH_FLOW_PARSE_EXT_VLAN) ||
+ (parse_bm & CPH_FLOW_PARSE_TWO_VLAN)) {
+ rc = cph_flow_verify_tci(&cph_flow->parse_outer_tci, TRUE, CPH_TCI_FIELD_VID_PBIT);
if (rc == FALSE) {
return FALSE;
}
- rc = cph_flow_verify_tci(&cph_flow->parse_inner_tci, TRUE);
+ }
+
+ if (parse_bm & CPH_FLOW_PARSE_TWO_VLAN) {
+ rc = cph_flow_verify_tci(&cph_flow->parse_inner_tci, TRUE, CPH_TCI_FIELD_VID_PBIT);
+ if (rc == FALSE) {
+ return FALSE;
+ }
+ }
+
+ switch (cph_flow->op_type) {
+ case CPH_VLAN_OP_ASIS:
+ case CPH_VLAN_OP_DISCARD:
+ case CPH_VLAN_OP_REM:
+ case CPH_VLAN_OP_REM_2_TAGS:
+ case CPH_VLAN_OP_SWAP:
+ break;
+ case CPH_VLAN_OP_ADD:
+ case CPH_VLAN_OP_REPLACE:
+ case CPH_VLAN_OP_REPLACE_INNER_REM_OUTER:
+ rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE, CPH_TCI_FIELD_VID_PBIT);
+ if (rc == FALSE) {
+ return FALSE;
+ }
+ break;
+ case CPH_VLAN_OP_ADD_COPY_DSCP:
+ case CPH_VLAN_OP_ADD_COPY_OUTER_PBIT:
+ case CPH_VLAN_OP_ADD_COPY_INNER_PBIT:
+ case CPH_VLAN_OP_REPLACE_VID:
+ rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE, CPH_TCI_FIELD_VID);
if (rc == FALSE) {
return FALSE;
}
- rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE);
+ break;
+ case CPH_VLAN_OP_ADD_2_TAGS:
+ case CPH_VLAN_OP_REPLACE_2TAGS:
+ case CPH_VLAN_OP_REPLACE_INNER_ADD_OUTER:
+ rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE, CPH_TCI_FIELD_VID_PBIT);
+ if (rc == FALSE) {
+ return FALSE;
+ }
+ rc = cph_flow_verify_tci(&cph_flow->mod_inner_tci, FALSE, CPH_TCI_FIELD_VID_PBIT);
+ if (rc == FALSE) {
+ return FALSE;
+ }
+ break;
+ case CPH_VLAN_OP_ADD_2_TAGS_COPY_DSCP:
+ case CPH_VLAN_OP_ADD_2_TAGS_COPY_PBIT:
+ case CPH_VLAN_OP_REPLACE_2TAGS_VID:
+ case CPH_VLAN_OP_REPLACE_INNER_ADD_OUTER_COPY_PBIT:
+ rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE, CPH_TCI_FIELD_VID);
+ if (rc == FALSE) {
+ return FALSE;
+ }
+ rc = cph_flow_verify_tci(&cph_flow->mod_inner_tci, FALSE, CPH_TCI_FIELD_VID);
if (rc == FALSE) {
return FALSE;
}
- rc = cph_flow_verify_tci(&cph_flow->mod_inner_tci, FALSE);
+ break;
+ case CPH_VLAN_OP_REPLACE_PBIT:
+ rc = cph_flow_verify_tci(&cph_flow->mod_outer_tci, FALSE, CPH_TCI_FIELD_PBIT);
if (rc == FALSE) {
return FALSE;
}
+ break;
+ default:
+ break;
+ }
/* Check target port/queue/GEM port */
if (p_pkt_fwd->trg_port > MV_TCONT_LLID_MAX) {
@@ -591,7 +715,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
VOID cph_flow_display_tci(CPH_FLOW_TCI_T *tci, UINT32 trace_level)
@@ -617,7 +741,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_add_rule(CPH_FLOW_ENTRY_T *cph_flow)
@@ -666,7 +790,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_del_rule(CPH_FLOW_ENTRY_T *cph_flow)
@@ -704,7 +828,7 @@
* T-CONT, queue and packet modification for VID, P-bits.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_get_rule(CPH_FLOW_ENTRY_T *cph_flow)
@@ -741,7 +865,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_clear_rule(VOID)
@@ -773,7 +897,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_clear_rule_by_mh(UINT16 mh)
@@ -805,7 +929,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_set_dscp_map(CPH_DSCP_PBITS_T *dscp_map)
@@ -849,7 +973,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_del_dscp_map(VOID)
@@ -1090,7 +1214,7 @@
* flow - Flow parsing field values
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_parse_packet (INT32 port, UINT8 *data, BOOL rx, BOOL mh, CPH_FLOW_ENTRY_T *flow)
@@ -1369,6 +1493,90 @@
}
/******************************************************************************
+* cph_flow_compare_packet_and_rule_vid()
+* _____________________________________________________________________________
+*
+* DESCRIPTION: Compare flow packet and rule w/ only VID.
+*
+* INPUTS:
+* packet_rule - The parsing field values come from the packets
+* db_rule - The flow rule stored in flow database
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* In case same, return TRUE,
+* In case different, return FALSE.
+*******************************************************************************/
+BOOL cph_flow_compare_packet_and_rule_vid (CPH_FLOW_ENTRY_T *packet_rule, CPH_FLOW_ENTRY_T *db_rule)
+{
+ /* Check direction */
+ if ((packet_rule->dir != db_rule->dir) &&
+ (db_rule->dir != CPH_DIR_NOT_CARE))
+ return FALSE;
+
+ /* Check Multicast protocol */
+ if ((db_rule->parse_bm & CPH_FLOW_PARSE_MC_PROTO) != (packet_rule->parse_bm & CPH_FLOW_PARSE_MC_PROTO))
+ {
+ return FALSE;
+ }
+
+ /* Check MH if needed */
+ if ((db_rule->parse_bm & CPH_FLOW_PARSE_MH) &&
+ (packet_rule->parse_bm & CPH_FLOW_PARSE_MH) )
+ {
+ if (packet_rule->mh != db_rule->mh)
+ return FALSE;
+ }
+
+ /* Check if it is default rule */
+ if (packet_rule->is_default != db_rule->is_default)
+ return FALSE;
+
+ /* Check VLAN ID */
+ if ((packet_rule->parse_bm & (CPH_FLOW_PARSE_EXT_VLAN | CPH_FLOW_PARSE_TWO_VLAN))
+ != (db_rule->parse_bm & (CPH_FLOW_PARSE_EXT_VLAN | CPH_FLOW_PARSE_TWO_VLAN)))
+ return FALSE;
+ if (packet_rule->is_default == FALSE)
+ {
+ if ((db_rule->parse_bm & CPH_FLOW_PARSE_EXT_VLAN) ||
+ (db_rule->parse_bm & CPH_FLOW_PARSE_TWO_VLAN))
+ {
+ if (db_rule->parse_outer_tci.tpid != MV_CPH_TPID_NOT_CARE_VALUE)
+ return FALSE;
+
+ if (db_rule->parse_outer_tci.pbits != MV_CPH_PBITS_NOT_CARE_VALUE)
+ return FALSE;
+
+ if ((packet_rule->parse_outer_tci.vid != db_rule->parse_outer_tci.vid) &&
+ (db_rule->parse_outer_tci.vid != MV_CPH_VID_NOT_CARE_VALUE))
+ return FALSE;
+ }
+ if (db_rule->parse_bm & CPH_FLOW_PARSE_TWO_VLAN)
+ {
+ if (db_rule->parse_inner_tci.tpid != MV_CPH_TPID_NOT_CARE_VALUE)
+ return FALSE;
+
+ if (db_rule->parse_inner_tci.pbits != MV_CPH_PBITS_NOT_CARE_VALUE)
+ return FALSE;
+
+ if ((packet_rule->parse_inner_tci.vid != db_rule->parse_inner_tci.vid) &&
+ (db_rule->parse_inner_tci.vid != MV_CPH_VID_NOT_CARE_VALUE))
+ return FALSE;
+ }
+ }
+ /* Check Ethernet type if needed */
+ if (db_rule->parse_bm & CPH_FLOW_PARSE_ETH_TYPE)
+ {
+ if (packet_rule->eth_type != db_rule->eth_type)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/******************************************************************************
* cph_flow_mod_packet()
* _____________________________________________________________________________
*
@@ -1385,7 +1593,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_mod_packet (struct sk_buff *skb, BOOL mh, CPH_FLOW_ENTRY_T *flow, INT32 *out_offset)
@@ -1549,7 +1757,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_mod_frwd (CPH_FLOW_ENTRY_T *flow, struct mv_eth_tx_spec *tx_spec_out)
@@ -1772,7 +1980,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_display_all (VOID)
@@ -1847,7 +2055,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_init(VOID)
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.h
index b6656f1..96e9ee2 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_flow.h
@@ -149,6 +149,15 @@
CPH_FLOW_PARSE_MC_PROTO = 0x10, /* parsing multicast protocol */
} CPH_FLOW_PARSE_E;
+typedef enum
+{
+ CPH_TCI_FIELD_VID,
+ CPH_TCI_FIELD_CFI,
+ CPH_TCI_FIELD_PBIT,
+ CPH_TCI_FIELD_VID_PBIT,
+ CPH_TCI_FIELD_ALL,
+} CPH_TCI_FIELD_E;
+
typedef struct
{
BOOL valid;
@@ -200,7 +209,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_add_rule(CPH_FLOW_ENTRY_T *cph_flow);
@@ -218,7 +227,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_del_rule(CPH_FLOW_ENTRY_T *cph_flow);
@@ -236,7 +245,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_clear_rule(VOID);
@@ -254,7 +263,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_clear_rule_by_mh(UINT16 mh);
@@ -273,12 +282,31 @@
* T-CONT, queue and packet modification for VID, P-bits.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_get_rule(CPH_FLOW_ENTRY_T *cph_flow);
/******************************************************************************
+* cph_flow_get_rule_by_vid()
+* _____________________________________________________________________________
+*
+* DESCRIPTION: Get CPH flow mapping rule by VID, only used to compare packet and db rule.
+*
+* INPUTS:
+* flow - Flow parsing field values
+* for_packet - Whether get rule for packet or for new CPH rule
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns MV_OK.
+* On error returns error code accordingly.
+*******************************************************************************/
+MV_STATUS cph_flow_get_rule_by_vid (CPH_FLOW_ENTRY_T *flow);
+
+/******************************************************************************
* cph_flow_set_dscp_map()
* _____________________________________________________________________________
*
@@ -291,7 +319,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_set_dscp_map(CPH_DSCP_PBITS_T *dscp_map);
@@ -309,7 +337,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_del_dscp_map(VOID);
@@ -449,6 +477,25 @@
BOOL cph_flow_compare_packet_and_rule (CPH_FLOW_ENTRY_T *packet_rule, CPH_FLOW_ENTRY_T *db_rule);
/******************************************************************************
+* cph_flow_compare_packet_and_rule_vid()
+* _____________________________________________________________________________
+*
+* DESCRIPTION: Compare flow packet and rule w/ only VID.
+*
+* INPUTS:
+* packet_rule - The parsing field values come from the packets
+* db_rule - The flow rule stored in flow database
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* In case same, return TRUE,
+* In case different, return FALSE.
+*******************************************************************************/
+BOOL cph_flow_compare_packet_and_rule_vid (CPH_FLOW_ENTRY_T *packet_rule, CPH_FLOW_ENTRY_T *db_rule);
+
+/******************************************************************************
* cph_flow_parse_packet()
* _____________________________________________________________________________
*
@@ -463,7 +510,7 @@
* flow - Flow parsing field values
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_parse_packet (INT32 port, UINT8 *data, BOOL rx, BOOL mh, CPH_FLOW_ENTRY_T *flow);
@@ -485,7 +532,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_mod_packet (struct sk_buff *skb, BOOL mh, CPH_FLOW_ENTRY_T *flow, INT32 *out_offset);
@@ -504,7 +551,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
MV_STATUS cph_flow_mod_frwd (CPH_FLOW_ENTRY_T *flow, struct mv_eth_tx_spec *tx_spec_out);
@@ -561,7 +608,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_display_all(VOID);
@@ -579,7 +626,7 @@
* None.
*
* RETURNS:
-* On success, the function returns MV_OK.
+* On success, the function returns MV_OK.
* On error returns error code accordingly.
*******************************************************************************/
INT32 cph_flow_init(VOID);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_mod.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_mod.c
index 7c631c3..eebe31f 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_mod.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_mod.c
@@ -128,7 +128,7 @@
return MV_ERROR;
}
- printk(KERN_INFO "\nCPH module inserted - %s\n\n", CPH_MODULE_VERSION);
+ /* printk(KERN_INFO "\nCPH module inserted - %s\n\n", CPH_MODULE_VERSION); */
return MV_OK;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_netdev.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_netdev.c
index 9d1e6df..883620c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_netdev.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_netdev.c
@@ -658,20 +658,23 @@
{
/* Handle multicat packets as unicast one */
if (flow_rule.parse_bm & CPH_FLOW_PARSE_MC_PROTO) {
-
flow_rule.parse_bm &= ~CPH_FLOW_PARSE_MC_PROTO;
- rc = cph_flow_get_rule(&flow_rule);
-
+ rc = cph_flow_get_rule_by_vid(&flow_rule);
if (rc != MV_OK)
{
- flow_rule.is_default = TRUE;
rc = cph_flow_get_rule(&flow_rule);
+
if (rc != MV_OK)
{
- MV_CPH_PRINT(CPH_DEBUG_LEVEL, "%s():fail to call cph_flow_get_rule, rc<%d> \n", __FUNCTION__, rc);
- return 0;
+ flow_rule.is_default = TRUE;
+ rc = cph_flow_get_rule(&flow_rule);
+ if (rc != MV_OK)
+ {
+ MV_CPH_PRINT(CPH_DEBUG_LEVEL, "%s():fail to call cph_flow_get_rule, rc<%d> \n", __FUNCTION__, rc);
+ return 0;
+ }
}
- }
+ }
}
else {
@@ -699,7 +702,7 @@
skb->data += MV_ETH_MH_SIZE;
skb->len -= MV_ETH_MH_SIZE;
}
-
+
/* modify packet */
rc = cph_flow_mod_frwd(&flow_rule, tx_spec_out);
if (rc != MV_OK)
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_sysfs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_sysfs.c
index 0e540a0..f16bd32 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_sysfs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cph/mv_cph_sysfs.c
@@ -127,9 +127,9 @@
#ifdef CONFIG_MV_CPH_FLOW_MAP_HANDLE
off += sprintf(buf+off, "---------------------------------------------------------------------------------------------------------------------------------------\n");
off += sprintf(buf+off, " |Parse outer |Parse inner |Mod outer |Mod Inner |Forward\n");
- off += sprintf(buf+off, "echo dir parse_bm mh ety tpid vid pbits tpid vid pbits op_type tpid vid pbits tpid vid pbits port queue hwf_queue gem > add_flow_rule - Add flow rule\n");
- off += sprintf(buf+off, "echo dir parse_bm mh ety tpid vid pbits tpid vid pbits > del_flow_rule - delete flow mapping rule\n");
- off += sprintf(buf+off, "echo dir parse_bm mh ety tpid vid pbits tpid vid pbits > get_flow_rule - get flow mapping rule\n");
+ off += sprintf(buf+off, "echo dir default parse_bm mh ety tpid vid pbits tpid vid pbits op_type tpid vid pbits tpid vid pbits port queue hwf_queue gem > add_flow_rule - Add flow rule\n");
+ off += sprintf(buf+off, "echo dir default parse_bm mh ety tpid vid pbits tpid vid pbits > del_flow_rule - delete flow mapping rule\n");
+ off += sprintf(buf+off, "echo dir default parse_bm mh ety tpid vid pbits tpid vid pbits > get_flow_rule - get flow mapping rule\n");
off += sprintf(buf+off, "echo pbits0 pbits1 ... pbits62 pbits63 > set_dscp_map - set DSCP to P-bits mapping rules\n");
#endif
return off;
@@ -156,6 +156,7 @@
off += sprintf(buf+off, " 0x01:FRWD_SET_TRG_PORT 0x02:FRWD_SET_TRG_QUEUE 0x04:FRWD_SET_GEM_PORT\n");
off += sprintf(buf+off, "[Flow Parameters]\n");
off += sprintf(buf+off, "dir: 0: U/S, 1:D/S, 2: Not care\n");
+ off += sprintf(buf+off, "default: 0: not default, 1:default\n");
off += sprintf(buf+off, "bm:\n");
off += sprintf(buf+off, " 0x01:PARSE_MH 0x02:PARSE_EXT_VLAN 0x04:PARSE_TWO_VLAN 0x08:PARSE_ETH_TYPE\n");
off += sprintf(buf+off, "mh(hex), ety(hex), tpid(hex), vid(dec), pbits(dec)\n");
@@ -903,6 +904,7 @@
const CHAR *buf, size_t len)
{
const CHAR *name = attr->attr.name;
+ UINT32 v0 = 0;
UINT32 v1 = 0;
UINT32 v2 = 0;
UINT32 v3 = 0;
@@ -932,14 +934,15 @@
return -EPERM;
/* Read input */
- sscanf(buf, "%d %x %x %x %x %d %d %x %d %d %d %x %d %d %x %d %d %d %d %d %d", &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v12, &v13, &v14, &v15, &v16, &v17, &v18, &v19, &v20, &v21);
+ sscanf(buf, "%d %d %x %x %x %x %d %d %x %d %d %d %x %d %d %x %d %d %d %d %d %d", &v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v12, &v13, &v14, &v15, &v16, &v17, &v18, &v19, &v20, &v21);
raw_local_irq_save(flags);
#ifdef CONFIG_MV_CPH_FLOW_MAP_HANDLE
if (!strcmp(name, "add_flow_rule")) {
memset(&cph_flow, 0, sizeof(cph_flow));
- cph_flow.dir = (CPH_DIR_E)v1;
+ cph_flow.dir = (CPH_DIR_E)v0;
+ cph_flow.is_default = v1? TRUE : FALSE;
cph_flow.parse_bm = (CPH_FLOW_PARSE_E)v2;
cph_flow.mh = (UINT16)v3;
cph_flow.eth_type = (UINT16)v4;
@@ -972,7 +975,8 @@
}
else if (!strcmp(name, "del_flow_rule")) {
memset(&cph_flow, 0, sizeof(cph_flow));
- cph_flow.dir = (CPH_DIR_E)v1;
+ cph_flow.dir = (CPH_DIR_E)v0;
+ cph_flow.is_default = v1? TRUE : FALSE;
cph_flow.parse_bm = (CPH_FLOW_PARSE_E)v2;
cph_flow.mh = (UINT16)v3;
cph_flow.eth_type = (UINT16)v4;
@@ -994,7 +998,8 @@
}
else if (!strcmp(name, "get_flow_rule")) {
memset(&cph_flow, 0, sizeof(cph_flow));
- cph_flow.dir = (CPH_DIR_E)v1;
+ cph_flow.dir = (CPH_DIR_E)v0;
+ cph_flow.is_default = v1? TRUE : FALSE;
cph_flow.parse_bm = (CPH_FLOW_PARSE_E)v2;
cph_flow.mh = (UINT16)v3;
cph_flow.eth_type = (UINT16)v4;
@@ -1009,10 +1014,11 @@
if (rc == MV_OK) {
printk("Succeed to get flow rule\n");
printk(KERN_INFO " |Parse outer |Parse inner |Mod outer |Mod Inner |Forward\n");
- printk(KERN_INFO "dir parse_bm mh ety tpid vid pbits tpid vid pbits tpid vid pbits tpid vid pbits port queue hwf_queue gem op_type\n");
+ printk(KERN_INFO "dir default tparse_bm mh ety tpid vid pbits tpid vid pbits tpid vid pbits tpid vid pbits port queue hwf_queue gem op_type\n");
printk(KERN_INFO
- "%2.2s 0x%04x %-4d 0x%04x 0x%04x %4d %1d 0x%04x %4d %1d 0x%04x %4d %1d 0x%04x %4d %1d %1d %1d %1d %4d %s \n",
- cph_app_lookup_dir(cph_flow.dir), cph_flow.parse_bm, cph_flow.mh, cph_flow.eth_type,
+ "%2.2s %4.4s 0x%04x %-4d 0x%04x 0x%04x %4d %1d 0x%04x %4d %1d 0x%04x %4d %1d 0x%04x %4d %1d %1d %1d %1d %4d %s \n",
+ cph_app_lookup_dir(cph_flow.dir), (cph_flow.is_default == TRUE) ?"Yes":"No", cph_flow.parse_bm,
+ cph_flow.mh, cph_flow.eth_type,
cph_flow.parse_outer_tci.tpid, cph_flow.parse_outer_tci.vid, cph_flow.parse_outer_tci.pbits,
cph_flow.parse_inner_tci.tpid, cph_flow.parse_inner_tci.vid, cph_flow.parse_inner_tci.pbits,
cph_flow.mod_outer_tci.tpid, cph_flow.mod_outer_tci.vid, cph_flow.mod_outer_tci.pbits,
@@ -1200,7 +1206,6 @@
cph_sysfs_init_mod_db();
cph_sysfs_init_frwd_db();
- printk(KERN_INFO "= CUST Module SYS FS init successfully =\n");
out:
return err;
}
@@ -1218,5 +1223,5 @@
sysfs_remove_group(&pd->kobj, &cph_spec_proc_group);
- printk(KERN_INFO "= CPH Module SYS FS exit successfully =\n");
+ /*printk(KERN_INFO "= CPH Module SYS FS exit successfully =\n");*/
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
index 7f54bbc..4122161 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
@@ -714,6 +714,8 @@
return(rcode);
}
+ onuGponDbGemPortValidSet(gemPortid, valid);
+
#ifdef MV_GPON_STATIC_GEM_PORT
if (staticGemPortConfigFlag != 0)
{
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
index 36c4d32..c43260a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
@@ -513,10 +513,10 @@
if (status != MV_OK)
return(MV_ERROR);
- } else if (mvCtrlRevGet() == ONU_ASIC_REV_A0) {
+ } else if ((mvCtrlRevGet() == ONU_ASIC_REV_A0) || (MV_6601_DEV_ID == mvCtrlModelGet())) {
- /* ASIC Rev A0 */
- /* =========== */
+ /* ASIC Rev A0 and MC */
+ /* ================== */
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, ONU_PHY_OUTPUT, 0);
if (status != MV_OK) {
mvPonPrint(PON_PRINT_ERROR, PON_ISR_MODULE,
@@ -691,10 +691,10 @@
if (status != MV_OK)
return(status);
- } else if (mvCtrlRevGet() == ONU_ASIC_REV_A0) {
+ } else if ((mvCtrlRevGet() == ONU_ASIC_REV_A0) || (MV_6601_DEV_ID == mvCtrlModelGet())) {
- /* ASIC Rev A0 */
- /* =========== */
+ /* ASIC Rev A0 and MC */
+ /* ================== */
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, ONU_PHY_OUTPUT, 0);
if (status != MV_OK)
return(status);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
index 426528a..1025809 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
@@ -5658,6 +5658,32 @@
memset(&(tpm_db.ipv6_mc_stream[stream_num]), 0, sizeof(tpm_db_ipv6_mc_stream_entry_t));
}
+int32_t tpm_db_get_mc_mac_port_bm(uint8_t *mac_addr, uint32_t *uni_port_bm)
+{
+ uint32_t entry_id;
+ uint32_t port_nr;
+
+ *uni_port_bm = 0;
+
+ for (entry_id = 0; entry_id < TPM_MC_MAX_MAC_NUM; entry_id++) {
+ if (tpm_db_mc_mac_table[entry_id] != NULL)
+ if (!memcmp(tpm_db_mc_mac_table[entry_id]->mac_addr, mac_addr, 6 * sizeof(uint8_t)))
+ break;
+ }
+
+ if (entry_id == TPM_MC_MAX_MAC_NUM) {
+ /* no entry for this MAC */
+ *uni_port_bm = 0;
+ return TPM_DB_OK;
+ }
+
+ for (port_nr = TPM_SRC_PORT_UNI_0; port_nr <= TPM_SRC_PORT_UNI_VIRT; port_nr++)
+ if (tpm_db_mc_mac_table[entry_id]->user_num[port_nr])
+ *uni_port_bm |= (TPM_TRG_UNI_0 << port_nr);
+
+ return TPM_DB_OK;
+}
+
int32_t tpm_db_increase_mc_mac_port_user_num(uint8_t *mac_addr, uint32_t uni_port)
{
uint32_t entry_id, first_free = TPM_MC_MAX_MAC_NUM;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
index a526cfd..6a9e104 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
@@ -1241,6 +1241,7 @@
int32_t tpm_db_set_ipv6_mc_stream_entry(uint32_t stream_num, tpm_db_ipv6_mc_stream_entry_t *mc_stream);
int32_t tpm_db_get_ipv6_mc_stream_entry(uint32_t stream_num, tpm_db_ipv6_mc_stream_entry_t *mc_stream);
void tpm_db_reset_ipv6_mc_stream_entry(uint32_t stream_num);
+int32_t tpm_db_get_mc_mac_port_bm(uint8_t *mac_addr, uint32_t *uni_port_bm);
int32_t tpm_db_increase_mc_mac_port_user_num(uint8_t *mac_addr, uint32_t uni_port);
int32_t tpm_db_decrease_mc_mac_port_user_num(uint8_t *mac_addr, uint32_t uni_port);
uint8_t tpm_db_get_mc_mac_port_user_num(uint8_t *mac_addr, uint32_t uni_port);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
index 05af79d..c3f5f19 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
@@ -8352,7 +8352,7 @@
mc_stream.dest_port_bm = dest_port_bm;
mc_stream.u4_entry = rule_num;
memcpy(mc_stream.group_addr, ipv4_dst_add, 4 * sizeof(uint8_t));
- if (ignore_ipv4_src)
+ if (!ignore_ipv4_src)
memcpy(mc_stream.src_addr, ipv4_src_add, 4 * sizeof(uint8_t));
ret_code = tpm_db_set_mc_stream_entry(stream_num, &mc_stream);
@@ -8412,15 +8412,18 @@
port = port << 1;
}
- if (new_target != 0)
- new_target |= TPM_TRG_PORT_CPU; /* igmp report to CPU */
+ ret_code = tpm_db_get_mc_mac_port_bm(mc_mac, &trg_port_bm);
+ IF_ERROR(ret_code);
+
+ if (trg_port_bm != 0)
+ trg_port_bm |= TPM_TRG_PORT_CPU; /* igmp report to CPU */
switch (filter_mode) {
case TPM_MC_COMBINED_IP_MAC_FILTER:
- if (tpm_db_get_mc_per_uni_vlan_xlate() != 0 && new_target != 0)
- new_target |= TPM_TRG_UNI_VIRT; /* loopback G1 */
+ if (tpm_db_get_mc_per_uni_vlan_xlate() != 0 && trg_port_bm != 0)
+ trg_port_bm |= TPM_TRG_UNI_VIRT; /* loopback G1 */
case TPM_MC_MAC_ONLY_FILTER:
- trg_port_bm = tpm_db_trg_port_switch_port_get(new_target);
+ trg_port_bm = tpm_db_trg_port_switch_port_get(trg_port_bm);
break;
case TPM_MC_IP_ONLY_FILTER:
trg_port_bm = 0x3F; /* all uni ports + CPU + G1/wifi */
@@ -8429,7 +8432,7 @@
break;
}
- if (new_target == 0) {
+ if (trg_port_bm == 0) {
ret_code = tpm_sw_del_static_mac(TPM_MOD_OWNER_TPM, mc_mac);
IF_ERROR(ret_code);
tpm_db_reset_mc_mac_entry(mc_mac);