| /******************************************************************************* |
| Copyright (C) Marvell International Ltd. and its affiliates |
| |
| This software file (the "File") is owned and distributed by Marvell |
| International Ltd. and/or its affiliates ("Marvell") under the following |
| alternative licensing terms. Once you have made an election to distribute the |
| File under one of the following license alternatives, please (i) delete this |
| introductory statement regarding license alternatives, (ii) delete the two |
| license alternatives that you have not elected to use and (iii) preserve the |
| Marvell copyright notice above. |
| |
| ******************************************************************************** |
| Marvell Commercial License Option |
| |
| If you received this File from Marvell and you have entered into a commercial |
| license agreement (a "Commercial License") with Marvell, the File is licensed |
| to you under the terms of the applicable Commercial License. |
| |
| ******************************************************************************** |
| Marvell GPL License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File in accordance with the terms and conditions of the General |
| Public License Version 2, June 1991 (the "GPL License"), a copy of which is |
| available along with the File in the license.txt file or by writing to the Free |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or |
| on the worldwide web at http://www.gnu.org/licenses/gpl.txt. |
| |
| THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY |
| DISCLAIMED. The GPL License provides additional details about this warranty |
| disclaimer. |
| ******************************************************************************** |
| Marvell BSD License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File under the following licensing terms. |
| Redistribution and use in source and binary forms, with or without modification, |
| are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright notice, |
| this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| |
| * Neither the name of Marvell nor the names of its contributors may be |
| used to endorse or promote products derived from this software without |
| specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ******************************************************************************** |
| * mv_cph_db.c |
| * |
| * DESCRIPTION: Marvell CPH(CPH Packet Handler) data base implementation |
| * |
| * DEPENDENCIES: |
| * None |
| * |
| * CREATED BY: VictorGu |
| * |
| * DATE CREATED: 22Jan2013 |
| * |
| * FILE REVISION NUMBER: |
| * Revision: 1.0 |
| * |
| * |
| *******************************************************************************/ |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/version.h> |
| #include <linux/delay.h> |
| #include <linux/wait.h> |
| #include <linux/mutex.h> |
| #include <linux/spinlock.h> |
| #include <linux/poll.h> |
| #include <linux/clk.h> |
| #include <linux/fs.h> |
| #include <linux/vmalloc.h> |
| #include <linux/cdev.h> |
| #include <linux/device.h> |
| #include <linux/miscdevice.h> |
| |
| #include "mv_cph_header.h" |
| #include "ezxml.h" |
| |
| |
| /****************************************************************************** |
| * Variable Definition |
| ******************************************************************************/ |
| static CPH_APP_DB_T g_cph_app_db; |
| CHAR *g_cph_xml_cfg_file = US_CPH_XML_CFG_FILE; |
| CHAR *g_onu_profile_xml_cfg_file = US_ONU_PROFILE_XML_CFG_FILE; |
| |
| |
| /****************************************************************************** |
| * Function Definition |
| ******************************************************************************/ |
| /****************************************************************************** |
| * cph_db_set_param() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Set CPH DB parameter |
| * |
| * INPUTS: |
| * param - The parameter type |
| * value - Parameter value |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_set_param (CPH_DB_PARAM_E param, VOID *value) |
| { |
| MV_STATUS rc = MV_OK; |
| |
| switch (param) |
| { |
| case CPH_DB_PARAM_PROFILE_ID: |
| g_cph_app_db.profile_id = *(tpm_eth_complex_profile_t *)value; |
| break; |
| case CPH_DB_PARAM_ACTIVE_PORT: |
| g_cph_app_db.active_port = *(MV_APP_GMAC_PORT_E *)value; |
| break; |
| case CPH_DB_PARAM_APP_SUPPORT: |
| g_cph_app_db.app_support = *(BOOL *)value; |
| break; |
| case CPH_DB_PARAM_IGMP_SUPPORT: |
| g_cph_app_db.igmp_support = *(BOOL *)value; |
| break; |
| case CPH_DB_PARAM_BC_SUPPORT: |
| g_cph_app_db.bc_support = *(BOOL *)value; |
| break; |
| case CPH_DB_PARAM_FLOW_SUPPORT: |
| g_cph_app_db.flow_support = *(BOOL *)value; |
| break; |
| case CPH_DB_PARAM_UDP_SUPPORT: |
| g_cph_app_db.udp_support = *(BOOL *)value; |
| break; |
| case CPH_DB_PARAM_BC_COUNTER: |
| g_cph_app_db.bc_count = *(UINT32 *)value; |
| break; |
| default: |
| break; |
| } |
| |
| return rc; |
| } |
| |
| /****************************************************************************** |
| * cph_db_get_param() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Get CPH DB parameter |
| * |
| * INPUTS: |
| * param - The parameter type |
| * |
| * OUTPUTS: |
| * value - Parameter value |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_get_param (CPH_DB_PARAM_E param, VOID *value) |
| { |
| MV_STATUS rc = MV_OK; |
| |
| switch (param) |
| { |
| case CPH_DB_PARAM_PROFILE_ID: |
| *(tpm_eth_complex_profile_t *)value = g_cph_app_db.profile_id; |
| break; |
| case CPH_DB_PARAM_ACTIVE_PORT: |
| *(MV_APP_GMAC_PORT_E *)value = g_cph_app_db.active_port; |
| break; |
| case CPH_DB_PARAM_APP_SUPPORT: |
| *(BOOL *)value = g_cph_app_db.app_support; |
| break; |
| case CPH_DB_PARAM_IGMP_SUPPORT: |
| *(BOOL *)value = g_cph_app_db.igmp_support; |
| break; |
| case CPH_DB_PARAM_BC_SUPPORT: |
| *(BOOL *)value = g_cph_app_db.bc_support; |
| break; |
| case CPH_DB_PARAM_FLOW_SUPPORT: |
| *(BOOL *)value = g_cph_app_db.flow_support; |
| break; |
| case CPH_DB_PARAM_UDP_SUPPORT: |
| *(BOOL *)value = g_cph_app_db.udp_support; |
| break; |
| case CPH_DB_PARAM_BC_COUNTER: |
| *(UINT32 *)value = g_cph_app_db.bc_count; |
| break; |
| default: |
| break; |
| } |
| return rc; |
| } |
| |
| /****************************************************************************** |
| * cph_db_compare_rules() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Compare the parse_bm and parse_key of two rules |
| * |
| * INPUTS: |
| * parse_bm_1 - Parsing bitmap of first CPH rule |
| * parse_key_1 - Parsing key of first CPH rule |
| * parse_bm_2 - Parsing bitmap of second CPH rule |
| * parse_key_2 - Parsing key of second CPH rule |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * In case same, return TRUE, |
| * In case different, return FALSE. |
| *******************************************************************************/ |
| BOOL cph_db_compare_rules ( |
| CPH_APP_PARSE_FIELD_E parse_bm_1, |
| CPH_APP_PARSE_T *parse_key_1, |
| CPH_APP_PARSE_FIELD_E parse_bm_2, |
| CPH_APP_PARSE_T *parse_key_2) |
| { |
| if (parse_bm_1 == parse_bm_2) |
| { |
| /* Compare direction */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_DIR) |
| { |
| if (parse_key_1->dir != parse_key_2->dir) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old dir[%d], new dir[%d] \n", parse_key_1->dir, parse_key_2->dir); |
| return FALSE; |
| } |
| } |
| |
| /* Compare RX direction */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_RX_TX) |
| { |
| if (parse_key_1->rx_tx != parse_key_2->rx_tx) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old rx_tx[%d], new rx_tx[%d] \n", parse_key_1->rx_tx, parse_key_2->rx_tx); |
| return FALSE; |
| } |
| } |
| |
| /* Compare Marvell header */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_MH) |
| { |
| if (parse_key_1->mh != parse_key_2->mh) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old mh[%d], new mh[%d] \n", parse_key_1->mh, parse_key_2->mh); |
| return FALSE; |
| } |
| } |
| |
| /* Compare Eth type */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_ETH_TYPE) |
| { |
| if (parse_key_1->eth_type!= parse_key_2->eth_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old eth_type[%d], new eth_type[%d] \n", parse_key_1->eth_type, parse_key_2->eth_type); |
| return FALSE; |
| } |
| } |
| |
| /* Compare Eth subtype */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_ETH_SUBTYPE) |
| { |
| if (parse_key_1->eth_subtype != parse_key_2->eth_subtype) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old eth_subtype[%d], new eth_subtype[%d] \n", parse_key_1->eth_subtype, parse_key_2->eth_subtype); |
| return FALSE; |
| } |
| } |
| |
| /* Compare IPV4 type */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_IPV4_TYPE) |
| { |
| if (parse_key_1->ipv4_type != parse_key_2->ipv4_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old ipv4_type[%d], new ipv4_type[%d] \n", parse_key_1->ipv4_type, parse_key_2->ipv4_type); |
| return FALSE; |
| } |
| } |
| |
| /* Compare IPV6 type */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_IPV6_NH1) |
| { |
| if (parse_key_1->ipv6_nh1 != parse_key_2->ipv6_nh1) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old ipv6_nh1[%d], new ipv6_nh1[%d] \n", parse_key_1->ipv6_nh1, parse_key_2->ipv6_nh1); |
| return FALSE; |
| } |
| } |
| |
| /* Compare IPv6 NH */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_IPV6_NH2) |
| { |
| if (parse_key_1->ipv6_nh2!= parse_key_2->ipv6_nh2) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old ipv6_nh2[%d], new ipv6_nh2[%d] \n", parse_key_1->ipv6_nh2, parse_key_2->ipv6_nh2); |
| return FALSE; |
| } |
| } |
| |
| /* Compare ICMPv6 type */ |
| if (parse_bm_1 & CPH_APP_PARSE_FIELD_ICMPV6_TYPE) |
| { |
| if (parse_key_1->icmpv6_type != parse_key_2->icmpv6_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Old icmpv6_type[%d], new icmpv6_type[%d] \n", parse_key_1->icmpv6_type, parse_key_2->icmpv6_type); |
| return FALSE; |
| } |
| } |
| |
| return TRUE; |
| } |
| else |
| { |
| return FALSE; |
| } |
| } |
| |
| /****************************************************************************** |
| * cph_db_compare_rule_and_packet() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Compare the parse_bm and parse_key of CPH and the packet |
| * |
| * INPUTS: |
| * parse_bm_rule - Parsing bitmap of CPH rule |
| * parse_key_rule - Parsing key of CPH rule |
| * parse_bm_packet - Parsing bitmap of packet |
| * parse_key_packet - Parsing key of packet |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * In case same, return TRUE, |
| * In case different, return FALSE. |
| *******************************************************************************/ |
| BOOL cph_db_compare_rule_and_packet ( |
| CPH_APP_PARSE_FIELD_E parse_bm_rule, |
| CPH_APP_PARSE_T *parse_key_rule, |
| CPH_APP_PARSE_FIELD_E parse_bm_packet, |
| CPH_APP_PARSE_T *parse_key_packet) |
| { |
| /* Check direction */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_DIR) |
| { |
| if (parse_key_rule->dir != CPH_DIR_NOT_CARE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_DIR)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no dir field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->dir != parse_key_packet->dir) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet dir[%d] is different with rule dir[%d], mis-mathced!\n", parse_key_packet->dir, parse_key_rule->dir); |
| return FALSE; |
| } |
| } |
| } |
| |
| /* Check RX/TX direction */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_RX_TX) |
| { |
| if (parse_key_rule->rx_tx != CPH_RX_TX_NOT_CARE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_RX_TX)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no dir RX/TX field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->rx_tx != parse_key_packet->rx_tx) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet rx_tx[%d] is different with rule rx_tx[%d], mis-mathced!\n", parse_key_packet->rx_tx, parse_key_rule->rx_tx); |
| return FALSE; |
| } |
| } |
| } |
| |
| /* Check Marvell header */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_MH) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_MH)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no MH field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->mh != parse_key_packet->mh) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet mh[0x%x] is different with rule mh[0x%x], mis-mathced!\n", parse_key_packet->mh, parse_key_rule->mh); |
| return FALSE; |
| } |
| } |
| |
| /* Check Eth type */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_ETH_TYPE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_ETH_TYPE)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no eth_type field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->eth_type != parse_key_packet->eth_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet eth_type[0x%x] is different with rule eth_type[0x%x], mis-mathced!\n", parse_key_packet->eth_type, parse_key_rule->eth_type); |
| return FALSE; |
| } |
| } |
| |
| /* Check Eth subtype */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_ETH_SUBTYPE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_ETH_SUBTYPE)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no eth_subtype field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->eth_subtype != parse_key_packet->eth_subtype) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet eth_subtype[%d] is different with rule eth_subtype[%d], mis-mathced!\n", parse_key_packet->eth_subtype, parse_key_rule->eth_subtype); |
| return FALSE; |
| } |
| } |
| |
| /* Check IPV4 type */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_IPV4_TYPE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_IPV4_TYPE)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no ipv4_type field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->ipv4_type != parse_key_packet->ipv4_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet ipv4_type[%d] is different with rule ipv4_type[%d], mis-mathced!\n", parse_key_packet->ipv4_type, parse_key_rule->ipv4_type); |
| return FALSE; |
| } |
| } |
| |
| /* Check IPV6 NH1 */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_IPV6_NH1) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_IPV6_NH1)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no ipv6_nh1 field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->ipv6_nh1 != parse_key_packet->ipv6_nh1) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet ipv6_nh1[%d] is different with rule ipv6_nh1[%d], mis-mathced!\n", parse_key_packet->ipv6_nh1, parse_key_rule->ipv6_nh1); |
| return FALSE; |
| } |
| } |
| |
| /* Check IPv6 NH2 */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_IPV6_NH2) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_IPV6_NH2)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no ipv6_nh2 field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->ipv6_nh2 != parse_key_packet->ipv6_nh2) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet ipv6_nh2[%d] is different with rule ipv6_nh2[%d], mis-mathced!\n", parse_key_packet->ipv6_nh2, parse_key_rule->ipv6_nh2); |
| return FALSE; |
| } |
| } |
| |
| /* Check ICMPv6 type */ |
| if (parse_bm_rule & CPH_APP_PARSE_FIELD_ICMPV6_TYPE) |
| { |
| if (! (parse_bm_packet & CPH_APP_PARSE_FIELD_ICMPV6_TYPE)) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet has no icmpv6_type field\n"); |
| return FALSE; |
| } |
| |
| if (parse_key_rule->icmpv6_type != parse_key_packet->icmpv6_type) |
| { |
| MV_CPH_PRINT(CPH_DEBUG_LEVEL, "Packet icmpv6_type[%d] is different with rule icmpv6_type[%d], mis-mathced!\n", parse_key_packet->icmpv6_type, parse_key_rule->icmpv6_type); |
| return FALSE; |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /****************************************************************************** |
| * cph_db_check_duplicate_rule() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Check whether there is duplicate CPH rule w/ same parse bitmap |
| * value |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * In case has duplicated rule, return TRUE, |
| * In case has not duplicated rule, return FALSE. |
| *******************************************************************************/ |
| BOOL cph_db_check_duplicate_rule ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = FALSE; |
| |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| rc = cph_db_compare_rules(p_cph_rule->parse_bm, &p_cph_rule->parse_key, parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| return rc; |
| } |
| } |
| } |
| |
| return rc; |
| } |
| |
| /****************************************************************************** |
| * cph_db_add_app_rule() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Add application type CPH rule to data base |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * mod_bm - Modification bitmap |
| * mod_value - Modification value |
| * frwd_bm - Forwarding bitmap |
| * frwd_value - Forwarding value |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_add_app_rule ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key, |
| CPH_APP_MOD_FIELD_E mod_bm, |
| CPH_APP_MOD_T *mod_value, |
| CPH_APP_FRWD_FIELD_E frwd_bm, |
| CPH_APP_FRWD_T *frwd_value) |
| { |
| UINT32 idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = TRUE; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| /* Seach for an free entry */ |
| for (idx = 0; idx < CPH_APP_MAX_RULE_NUM; idx++) |
| { |
| if (g_cph_app_db.cph_rule[idx].valid == FALSE) |
| break; |
| } |
| |
| /* No free entry */ |
| if (idx == CPH_APP_MAX_RULE_NUM) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "No free CPH entry \n"); |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_FULL; |
| } |
| |
| /* Do not add new rule if there is already duplicated rule */ |
| rc = cph_db_check_duplicate_rule(parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "Already has duplicated rule, could not add new CPH rule \n"); |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_ERROR; |
| } |
| |
| /* Save CPH rule for application packet */ |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| p_cph_rule->parse_bm = parse_bm; |
| memcpy(&p_cph_rule->parse_key, parse_key, sizeof(CPH_APP_PARSE_T)); |
| p_cph_rule->mod_bm = mod_bm; |
| memcpy(&p_cph_rule->mod_value, mod_value, sizeof(CPH_APP_MOD_T)); |
| p_cph_rule->frwd_bm = frwd_bm; |
| memcpy(&p_cph_rule->frwd_value, frwd_value, sizeof(CPH_APP_FRWD_T)); |
| p_cph_rule->valid = TRUE; |
| g_cph_app_db.rule_num ++; |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_del_app_rule() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Delete application type CPH rule from data base |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_del_app_rule ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = FALSE; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| rc = cph_db_compare_rules(p_cph_rule->parse_bm, &p_cph_rule->parse_key, parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| memset(p_cph_rule, 0, sizeof(CPH_APP_RULE_T)); |
| p_cph_rule->valid = FALSE; |
| g_cph_app_db.rule_num --; |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_update_app_rule() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Update application type CPH rule from data base |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * mod_bm - Modification bitmap |
| * mod_value - Modification value |
| * frwd_bm - Forwarding bitmap |
| * frwd_value - Forwarding value |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_update_app_rule ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key, |
| CPH_APP_MOD_FIELD_E mod_bm, |
| CPH_APP_MOD_T *mod_value, |
| CPH_APP_FRWD_FIELD_E frwd_bm, |
| CPH_APP_FRWD_T *frwd_value) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = FALSE; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| rc = cph_db_compare_rules(p_cph_rule->parse_bm, &p_cph_rule->parse_key, parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| p_cph_rule->mod_bm = mod_bm; |
| memcpy(&p_cph_rule->mod_value, mod_value, sizeof(CPH_APP_MOD_T)); |
| p_cph_rule->frwd_bm = frwd_bm; |
| memcpy(&p_cph_rule->frwd_value, frwd_value, sizeof(CPH_APP_FRWD_T)); |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_get_app_rule() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Get application type CPH rule from data base |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * |
| * OUTPUTS: |
| * mod_bm - Modification bitmap |
| * mod_value - Modification value |
| * frwd_bm - Forwarding bitmap |
| * frwd_value - Forwarding value |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_get_app_rule ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key, |
| CPH_APP_MOD_FIELD_E *mod_bm, |
| CPH_APP_MOD_T *mod_value, |
| CPH_APP_FRWD_FIELD_E *frwd_bm, |
| CPH_APP_FRWD_T *frwd_value) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = FALSE; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| rc = cph_db_compare_rule_and_packet(p_cph_rule->parse_bm, &p_cph_rule->parse_key, parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| if (p_cph_rule->mod_value.state == TRUE) |
| { |
| *mod_bm = p_cph_rule->mod_bm; |
| memcpy(mod_value, &p_cph_rule->mod_value, sizeof(CPH_APP_MOD_T)); |
| *frwd_bm = p_cph_rule->frwd_bm; |
| memcpy(frwd_value, &p_cph_rule->frwd_value, sizeof(CPH_APP_FRWD_T)); |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return MV_FAIL; |
| } |
| |
| /****************************************************************************** |
| * cph_db_get_app_rule_by_dir_proto() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Get application type CPH rule from data base by protocol type |
| * |
| * INPUTS: |
| * dir - Direction |
| * proto_type - SKB protocol type |
| * |
| * OUTPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * mod_bm - Modification bitmap |
| * mod_value - Modification value |
| * frwd_bm - Forwarding bitmap |
| * frwd_value - Forwarding value |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_get_app_rule_by_dir_proto ( |
| CPH_DIR_E dir, |
| UINT16 proto_type, |
| CPH_APP_PARSE_FIELD_E *parse_bm, |
| CPH_APP_PARSE_T *parse_key, |
| CPH_APP_MOD_FIELD_E *mod_bm, |
| CPH_APP_MOD_T *mod_value, |
| CPH_APP_FRWD_FIELD_E *frwd_bm, |
| CPH_APP_FRWD_T *frwd_value) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| if ((p_cph_rule->mod_bm & CPH_APP_RX_MOD_REPLACE_PROTO_TYPE) && |
| (p_cph_rule->mod_value.proto_type == proto_type) && |
| (p_cph_rule->mod_value.state == TRUE)) |
| { |
| if ((p_cph_rule->parse_bm & CPH_APP_PARSE_FIELD_DIR) && |
| ((p_cph_rule->parse_key.dir == CPH_DIR_NOT_CARE)||(p_cph_rule->parse_key.dir == dir)) && |
| (p_cph_rule->parse_bm & CPH_APP_PARSE_FIELD_RX_TX) && |
| (p_cph_rule->parse_key.rx_tx == CPH_DIR_TX)) |
| { |
| *parse_bm = p_cph_rule->parse_bm; |
| memcpy(parse_key, &p_cph_rule->parse_key, sizeof(CPH_APP_PARSE_T)); |
| *mod_bm = p_cph_rule->mod_bm; |
| memcpy(mod_value, &p_cph_rule->mod_value, sizeof(CPH_APP_MOD_T)); |
| *frwd_bm = p_cph_rule->frwd_bm; |
| memcpy(frwd_value, &p_cph_rule->frwd_value, sizeof(CPH_APP_FRWD_T)); |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return MV_FAIL; |
| } |
| |
| /****************************************************************************** |
| * cph_db_increase_counter() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Increase RX counter |
| * |
| * INPUTS: |
| * parse_bm - Parsing bitmap |
| * parse_key - Parsing key |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_increase_counter ( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| BOOL rc = MV_FAIL; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare parse_bm and parse_key */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| rc = cph_db_compare_rule_and_packet(p_cph_rule->parse_bm, &p_cph_rule->parse_key, parse_bm, parse_key); |
| if (rc == TRUE) |
| { |
| if (p_cph_rule->mod_value.state == TRUE) |
| { |
| p_cph_rule->count++; |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return rc; |
| } |
| |
| /****************************************************************************** |
| * cph_db_increase_counter_by_dir_proto() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Increase RX counter according to protocol type |
| * |
| * INPUTS: |
| * dir - Direction |
| * proto_type - SKB protocol type |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_increase_counter_by_dir_proto (CPH_DIR_E dir, |
| UINT16 proto_type) |
| { |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&g_cph_app_db.app_lock, flags); |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| |
| /* Compare dir and protocol type */ |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| if ((p_cph_rule->mod_bm & CPH_APP_RX_MOD_REPLACE_PROTO_TYPE) && |
| (p_cph_rule->mod_value.proto_type == proto_type) && |
| (p_cph_rule->mod_value.state == TRUE)) |
| { |
| if ((p_cph_rule->parse_bm & CPH_APP_PARSE_FIELD_DIR) && |
| ((p_cph_rule->parse_key.dir == CPH_DIR_NOT_CARE) || |
| (p_cph_rule->parse_key.dir == dir)) && |
| (p_cph_rule->parse_bm & CPH_APP_PARSE_FIELD_RX_TX) && |
| (p_cph_rule->parse_key.rx_tx == CPH_DIR_TX)) |
| { |
| p_cph_rule->count++; |
| |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| return MV_OK; |
| } |
| } |
| } |
| } |
| spin_unlock_irqrestore(&g_cph_app_db.app_lock, flags); |
| |
| return MV_OK; |
| |
| } |
| |
| /****************************************************************************** |
| * cph_db_get_xml_param() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Get the XML parameter |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_get_xml_param(VOID) |
| { |
| ezxml_t xml_head; |
| ezxml_t xml_element; |
| ezxml_t xml_attr; |
| UINT32 attr_value = 0; |
| BOOL bool_value = TRUE; |
| const CHAR *name = NULL; |
| const CHAR *value = NULL; |
| INT32 rc = MV_OK; |
| |
| /* Read ONU profile XML file */ |
| if ((xml_head = ezxml_parse_file(g_onu_profile_xml_cfg_file)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_parse_file() of %s failed", __FUNCTION__, g_onu_profile_xml_cfg_file); |
| rc = MV_NOT_FOUND; |
| goto free_exit; |
| } |
| |
| if ((xml_element = ezxml_get(xml_head, XML_PROFILE_ELM_CAPABILITY, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_PROFILE_ELM_CAPABILITY); |
| rc = MV_FAIL; |
| goto free_exit; |
| |
| } |
| |
| for (xml_attr = ezxml_child(xml_element, XML_PROFILE_ELM_ATTRIB); xml_attr; xml_attr = xml_attr->next) |
| { |
| /* Parse attribute type and value */ |
| name = ezxml_attr(xml_attr, XML_PROFILE_ATTR_NAME); |
| if (name == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_attr() of %s failed\n", __FUNCTION__, XML_PROFILE_ATTR_NAME); |
| rc = MV_NOT_FOUND; |
| goto free_exit; |
| } |
| |
| if (strcmp(name, XML_PROFILE_NAME_PROFILE) == 0) |
| { |
| value = ezxml_attr(xml_attr, XML_PROFILE_ATTR_VALUE); |
| if (value == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_attr() of %s failed\n", __FUNCTION__, XML_PROFILE_ATTR_VALUE); |
| rc = MV_NOT_FOUND; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(value); |
| |
| cph_db_set_param(CPH_DB_PARAM_PROFILE_ID, &attr_value); |
| } |
| else if (strcmp(name, XML_PROFILE_NAME_ACTIVE_PORT) == 0) |
| { |
| value = ezxml_attr(xml_attr, XML_PROFILE_ATTR_VALUE); |
| if (value == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_attr() of %s failed\n", __FUNCTION__, XML_PROFILE_ATTR_VALUE); |
| rc = MV_NOT_FOUND; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(value); |
| |
| cph_db_set_param(CPH_DB_PARAM_ACTIVE_PORT, &attr_value); |
| break; |
| } |
| } |
| ezxml_free(xml_head); |
| |
| /* Read CPH XML file */ |
| if ((xml_head = ezxml_parse_file(g_cph_xml_cfg_file)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_parse_file() of %s failed", __FUNCTION__, g_cph_xml_cfg_file); |
| rc = MV_NOT_FOUND; |
| goto free_exit; |
| } |
| |
| /* Read application support flag*/ |
| if ((xml_element = ezxml_get(xml_head, XML_CPH_ELM_APP_SUPPORT, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_CPH_ELM_APP_SUPPORT); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| if (xml_element->txt == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: xml_element->txt == NULL \n", __FUNCTION__); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(xml_element->txt); |
| bool_value = (attr_value != 0)? TRUE:FALSE; |
| cph_db_set_param(CPH_DB_PARAM_APP_SUPPORT, &bool_value); |
| |
| /* Read IGMP support flag*/ |
| if ((xml_element = ezxml_get(xml_head, XML_CPH_ELM_IGMP_SUPPORT, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_CPH_ELM_IGMP_SUPPORT); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| if (xml_element->txt == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: xml_element->txt == NULL \n", __FUNCTION__); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(xml_element->txt); |
| bool_value = (attr_value != 0)? TRUE:FALSE; |
| cph_db_set_param(CPH_DB_PARAM_IGMP_SUPPORT, &bool_value); |
| |
| /* Read BC support flag*/ |
| if ((xml_element = ezxml_get(xml_head, XML_CPH_ELM_BC_SUPPORT, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_CPH_ELM_BC_SUPPORT); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| if (xml_element->txt == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: xml_element->txt == NULL \n", __FUNCTION__); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(xml_element->txt); |
| bool_value = (attr_value != 0)? TRUE:FALSE; |
| cph_db_set_param(CPH_DB_PARAM_BC_SUPPORT, &bool_value); |
| |
| /* Read Data flow mapping support flag*/ |
| if ((xml_element = ezxml_get(xml_head, XML_CPH_ELM_FLOW_SUPPORT, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_CPH_ELM_FLOW_SUPPORT); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| if (xml_element->txt == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: xml_element->txt == NULL \n", __FUNCTION__); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(xml_element->txt); |
| bool_value = (attr_value != 0)? TRUE:FALSE; |
| cph_db_set_param(CPH_DB_PARAM_FLOW_SUPPORT, &bool_value); |
| |
| /* Read UDP port mapping support flag*/ |
| if ((xml_element = ezxml_get(xml_head, XML_CPH_ELM_UDP_SUPPORT, -1)) == 0) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: ezxml_get() of %s failed\n", __FUNCTION__, XML_CPH_ELM_UDP_SUPPORT); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| if (xml_element->txt == NULL) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "%s: xml_element->txt == NULL \n", __FUNCTION__); |
| rc = MV_FAIL; |
| goto free_exit; |
| } |
| attr_value = mtype_get_digit_num(xml_element->txt); |
| bool_value = (attr_value != 0)? TRUE:FALSE; |
| cph_db_set_param(CPH_DB_PARAM_UDP_SUPPORT, &bool_value); |
| |
| free_exit: |
| ezxml_free(xml_head); |
| return rc; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** cph_db_get_tcont_state |
| ** ___________________________________________________________________________ |
| ** |
| ** DESCRIPTION: The function get T-CONT state |
| ** |
| ** INPUTS: |
| ** tcont - T-CONT |
| ** |
| ** OUTPUTS: |
| ** None. |
| ** |
| ** RETURNS: |
| ** state - State of T-CONT, enabled or disabled. |
| ** |
| *******************************************************************************/ |
| BOOL cph_db_get_tcont_state(UINT32 tcont) |
| { |
| /* Check tcont */ |
| if (tcont >= MV_TCONT_LLID_NUM) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "tcont[%d] is illegal, should be less than [%d]\n", tcont, MV_TCONT_LLID_NUM); |
| return FALSE; |
| } |
| |
| return g_cph_app_db.tcont_state[tcont]; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** cph_db_set_tcont_state |
| ** ___________________________________________________________________________ |
| ** |
| ** DESCRIPTION: The function sets T-CONT state in mv_cph |
| ** |
| ** INPUTS: |
| ** tcont - T-CONT |
| ** state - State of T-CONT, enabled or disabled. |
| ** |
| ** OUTPUTS: |
| ** None. |
| ** |
| ** RETURNS: |
| ** On success, the function returns (MV_OK). On error different types are |
| ** returned according to the case. |
| ** |
| *******************************************************************************/ |
| MV_STATUS cph_db_set_tcont_state(UINT32 tcont, BOOL state) |
| { |
| /* Check tcont */ |
| if (tcont >= MV_TCONT_LLID_NUM) |
| { |
| MV_CPH_PRINT(CPH_ERR_LEVEL, "tcont[%d] is illegal, should be less than [%d]\n", tcont, MV_TCONT_LLID_NUM); |
| return MV_FAIL; |
| } |
| |
| /* Apply t-cont state to mv_cph */ |
| g_cph_app_db.tcont_state[tcont] = state; |
| |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_display_parse_field() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Display CPH rule parsing field |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_display_parse_field( |
| CPH_APP_PARSE_FIELD_E parse_bm, |
| CPH_APP_PARSE_T *parse_key) |
| { |
| printk(KERN_INFO "Parse field(0x%x): ", parse_bm); |
| |
| /* Print direction */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_DIR) |
| { |
| printk(KERN_INFO "Dir(%s), ", cph_app_lookup_dir(parse_key->dir)); |
| } |
| |
| /* 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)); |
| } |
| |
| /* Print Marvell header */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_MH) |
| { |
| printk(KERN_INFO "MH(0x%x), ", parse_key->mh); |
| } |
| |
| /* Print Eth type */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_ETH_TYPE) |
| { |
| printk(KERN_INFO "Eth type(0x%04x), ", parse_key->eth_type); |
| } |
| |
| /* Print Eth subtype */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_ETH_SUBTYPE) |
| { |
| printk(KERN_INFO "Eth subtype(%d), ", parse_key->eth_subtype); |
| } |
| |
| /* Print IPV4 type */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_IPV4_TYPE) |
| { |
| printk(KERN_INFO "IPv4 type(%d), ", parse_key->ipv4_type); |
| } |
| |
| /* Print IPv6 NH1 */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_IPV6_NH1) |
| { |
| printk(KERN_INFO "IPv6 NH1(%d), ", parse_key->ipv6_nh1); |
| } |
| |
| /* Print IPv6 NH2 */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_IPV6_NH2) |
| { |
| printk(KERN_INFO "IPv6 NH2(%d), ", parse_key->ipv6_nh2); |
| } |
| |
| /* Print ICMPv6 type */ |
| if (parse_bm & CPH_APP_PARSE_FIELD_ICMPV6_TYPE) |
| { |
| printk(KERN_INFO "ICMPv6 type(%d)", parse_key->icmpv6_type); |
| } |
| |
| printk(KERN_INFO "\n"); |
| |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_display_mod_field() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Display CPH rule modification field |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_display_mod_field( |
| CPH_APP_MOD_FIELD_E mod_bm, |
| CPH_APP_MOD_T *mod_value) |
| { |
| printk(KERN_INFO "Mod field(0x%x): ", mod_bm); |
| |
| /* Print protocol type */ |
| if (mod_bm & CPH_APP_RX_MOD_REPLACE_PROTO_TYPE) |
| { |
| printk(KERN_INFO "Proto type(0x%x), ", mod_value->proto_type); |
| } |
| |
| printk(KERN_INFO "state(%s)", (mod_value->state==TRUE)?"Enabled":"Disabled"); |
| |
| printk(KERN_INFO "\n"); |
| |
| return MV_OK; |
| } |
| |
| /****************************************************************************** |
| * cph_db_display_frwd_field() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Display CPH rule forwarding field |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_display_frwd_field( |
| CPH_APP_FRWD_FIELD_E frwd_bm, |
| CPH_APP_FRWD_T *frwd_value) |
| { |
| printk(KERN_INFO "Forward field(0x%x): ", frwd_bm); |
| |
| /* Print target port */ |
| if (frwd_bm & CPH_APP_FRWD_SET_TRG_PORT) |
| { |
| printk(KERN_INFO "Target port(%d), ", frwd_value->trg_port); |
| } |
| |
| /* Print target queue */ |
| if (frwd_bm & CPH_APP_FRWD_SET_TRG_QUEUE) |
| { |
| printk(KERN_INFO "Target queue(%d), ", frwd_value->trg_queue); |
| } |
| |
| /* Print GEM port */ |
| if (frwd_bm & CPH_APP_FRWD_SET_GEM_PORT) |
| { |
| printk(KERN_INFO "Gem port(%d)", frwd_value->gem_port); |
| } |
| |
| |
| printk(KERN_INFO "\n"); |
| |
| return MV_OK; |
| } |
| |
| |
| /****************************************************************************** |
| * cph_db_display_all() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Display all CPH rules in data base |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_display_all(VOID) |
| { |
| CPH_APP_RULE_T *p_cph_rule = NULL; |
| UINT32 idx = 0; |
| UINT32 rule_idx = 0; |
| |
| printk(KERN_INFO "CPH Application Data Base, total rule number[%u]\n", g_cph_app_db.rule_num); |
| printk(KERN_INFO "-------------------------------------------------------\n"); |
| |
| printk(KERN_INFO "TPM complex profile: %s, active WAN: %s\n", |
| cph_app_lookup_profile_id(g_cph_app_db.profile_id), |
| cph_app_lookup_gmac(g_cph_app_db.active_port)); |
| |
| printk(KERN_INFO "Generic application handling suppport: %s\n", |
| (g_cph_app_db.app_support == TRUE)?"Enabled":"Disabled"); |
| |
| #ifdef CONFIG_MV_CPH_IGMP_HANDLE |
| printk(KERN_INFO "IGMP/MLD handling suppport: %s\n", |
| (g_cph_app_db.igmp_support == TRUE)?"Enabled":"Disabled"); |
| #endif |
| |
| #ifdef CONFIG_MV_CPH_BC_HANDLE |
| printk(KERN_INFO "Broadcast handling suppport: %s\n", |
| (g_cph_app_db.bc_support == TRUE)?"Enabled":"Disabled"); |
| #endif |
| |
| #ifdef CONFIG_MV_CPH_FLOW_MAP_HANDLE |
| printk(KERN_INFO "Data flow mapping/modification suppport: %s\n", |
| (g_cph_app_db.flow_support == TRUE)?"Enabled":"Disabled"); |
| #endif |
| |
| #ifdef CONFIG_MV_CPH_UDP_SAMPLE_HANDLE |
| printk(KERN_INFO "UDP port mapping suppport: %s\n", |
| (g_cph_app_db.udp_support == TRUE)?"Enabled":"Disabled"); |
| #endif |
| |
| printk(KERN_INFO "-------------------------------------------------------\n"); |
| |
| printk(KERN_INFO "CPH total rule number: %d\n", g_cph_app_db.rule_num); |
| |
| for (idx = 0, rule_idx = 0; (idx < CPH_APP_MAX_RULE_NUM) && (rule_idx < g_cph_app_db.rule_num); idx++) |
| { |
| p_cph_rule = &g_cph_app_db.cph_rule[idx]; |
| if (p_cph_rule->valid == TRUE) |
| { |
| rule_idx++; |
| |
| printk(KERN_INFO "CPH rule: #%d\n", rule_idx); |
| printk(KERN_INFO "-----------------------\n"); |
| cph_db_display_parse_field(p_cph_rule->parse_bm, &p_cph_rule->parse_key); |
| cph_db_display_mod_field(p_cph_rule->mod_bm, &p_cph_rule->mod_value); |
| cph_db_display_frwd_field(p_cph_rule->frwd_bm, &p_cph_rule->frwd_value); |
| printk(KERN_INFO "Counter: %d\n\n", p_cph_rule->count); |
| } |
| } |
| |
| printk(KERN_INFO "Mis-matched or broadcast counter: %d\n", g_cph_app_db.bc_count); |
| |
| printk(KERN_INFO "T-CONT State\n"); |
| for (idx = 0; idx < MV_TCONT_LLID_NUM; idx++) |
| { |
| printk(KERN_INFO "T-CONT[%d]: %s\n", idx, (g_cph_app_db.tcont_state[idx] == TRUE)?"TRUE":"FALSE"); |
| } |
| |
| return MV_OK; |
| } |
| |
| |
| /****************************************************************************** |
| * cph_db_init() |
| * _____________________________________________________________________________ |
| * |
| * DESCRIPTION: Initialize CPH data base |
| * |
| * INPUTS: |
| * None. |
| * |
| * OUTPUTS: |
| * None. |
| * |
| * RETURNS: |
| * On success, the function returns MV_OK. |
| * On error returns error code accordingly. |
| *******************************************************************************/ |
| MV_STATUS cph_db_init(VOID) |
| { |
| UINT32 idx = 0; |
| MV_STATUS rc = MV_OK; |
| |
| memset(&g_cph_app_db, 0, sizeof(g_cph_app_db)); |
| for (idx = 0; idx < CPH_APP_MAX_RULE_NUM; idx++) |
| g_cph_app_db.cph_rule[idx].valid = FALSE; |
| |
| /* Set the default value */ |
| g_cph_app_db.profile_id = TPM_PON_WAN_DUAL_MAC_INT_SWITCH; |
| g_cph_app_db.active_port = MV_APP_PON_MAC_PORT; |
| g_cph_app_db.app_support = TRUE; |
| g_cph_app_db.igmp_support = FALSE; |
| g_cph_app_db.bc_support = FALSE; |
| g_cph_app_db.flow_support = FALSE; |
| g_cph_app_db.udp_support = FALSE; |
| |
| for (idx = 0; idx < MV_TCONT_LLID_NUM; idx++) |
| g_cph_app_db.tcont_state[idx] = FALSE; |
| |
| /* Init spin lock */ |
| spin_lock_init(&g_cph_app_db.app_lock); |
| |
| return rc; |
| } |