openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

knet.c (59048B)


      1 /*
      2  * 
      3  * 
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  *
      8  * Kernel Networking Management
      9  */
     10 
     11 #include <sal/core/libc.h>
     12 
     13 #include <soc/drv.h>
     14 #include <soc/higig.h>
     15 #include <soc/dcbformats.h>
     16 #include <soc/knet.h>
     17 
     18 #include <bcm/knet.h>
     19 #include <bcm_int/esw_dispatch.h>
     20 #include <bcm_int/common/rx.h>
     21 #include <bcm_int/esw/cosq.h>
     22 #include <shared/bsl.h>
     23 
     24 #ifdef INCLUDE_KNET
     25 
     26 STATIC uint32
     27 _rx_reason_get(int unit, soc_rx_reasons_t *reasons)
     28 {
     29     soc_rx_reason_t *map;
     30     uint32 reason = 0;
     31     uint32 mask = 1;
     32     int i;
     33 
     34     if ((map = (SOC_DCB_RX_REASON_MAPS(unit))[0]) == NULL) {
     35         return reason;
     36     }
     37 
     38     for (i = 0; i < 32; i++) {
     39         if (SOC_RX_REASON_GET(*reasons, map[i])) {
     40             reason |= mask;
     41         }
     42         mask <<= 1;
     43     }
     44     return reason;
     45 }
     46 
     47 STATIC uint32
     48 _rx_reason_hi_get(int unit, soc_rx_reasons_t *reasons)
     49 {
     50     soc_rx_reason_t *map;
     51     uint32 reason = 0;
     52     uint32 mask = 1;
     53     int i;
     54 
     55     if ((map = (SOC_DCB_RX_REASON_MAPS(unit))[0]) == NULL) {
     56         return reason;
     57     }
     58 
     59     if (soc_feature(unit, soc_feature_dcb_reason_hi)) {
     60         for (i = 32; i < 64; i++) {
     61             if (SOC_RX_REASON_GET(*reasons, map[i])) {
     62                 reason |= mask;
     63             }
     64             mask <<= 1;
     65         }
     66     }
     67     return reason;
     68 }
     69 
     70 STATIC void
     71 _higig_match_set(bcm_knet_filter_t *filter, uint32 *mh_data, uint32 *mh_mask)
     72 {
     73 #if defined(BCM_HIGIG_SUPPORT)
     74     soc_higig_hdr_t *hg_data = (soc_higig_hdr_t *)mh_data;
     75     soc_higig_hdr_t *hg_mask = (soc_higig_hdr_t *)mh_mask;
     76 
     77     if (filter == NULL) {
     78         return;
     79     }
     80     if (filter->match_flags & BCM_KNET_FILTER_M_SRC_MODPORT) {
     81         hg_data->src_port = filter->m_src_modport;
     82         hg_mask->src_port = 0;
     83     }
     84     if (filter->match_flags & BCM_KNET_FILTER_M_SRC_MODID) {
     85         hg_data->src_mod = filter->m_src_modid;
     86         hg_mask->src_mod = 0;
     87     }
     88     /* Adjust for endianess because soc_higig_hdr_t uses bit fields. */
     89     mh_data[0] = soc_ntohl(mh_data[0]);
     90     mh_data[1] = soc_ntohl(mh_data[1]);
     91     mh_data[2] = soc_ntohl(mh_data[2]);
     92     mh_mask[0] = soc_ntohl(mh_mask[0]);
     93     mh_mask[1] = soc_ntohl(mh_mask[1]);
     94     mh_mask[2] = soc_ntohl(mh_mask[2]);
     95 #endif
     96 }
     97 
     98 STATIC void
     99 _higig2_match_set(bcm_knet_filter_t *filter, uint32 *mh_data, uint32 *mh_mask)
    100 {
    101 #if defined(BCM_HIGIG2_SUPPORT)
    102     soc_higig2_hdr_t *hg_data = (soc_higig2_hdr_t *)mh_data;
    103     soc_higig2_hdr_t *hg_mask = (soc_higig2_hdr_t *)mh_mask;
    104 
    105     if (filter == NULL) {
    106         return;
    107     }
    108     if (filter->match_flags & BCM_KNET_FILTER_M_SRC_MODPORT) {
    109         hg_data->ppd_overlay1.src_port = filter->m_src_modport;
    110         hg_mask->ppd_overlay1.src_port = 0;
    111     }
    112     if (filter->match_flags & BCM_KNET_FILTER_M_SRC_MODID) {
    113         hg_data->ppd_overlay1.src_mod = filter->m_src_modid;
    114         hg_mask->ppd_overlay1.src_mod = 0;
    115     }
    116     /* Adjust for endianess because soc_higig2_hdr_t uses bit fields. */
    117     mh_data[0] = soc_ntohl(mh_data[0]);
    118     mh_data[1] = soc_ntohl(mh_data[1]);
    119     mh_data[2] = soc_ntohl(mh_data[2]);
    120     mh_data[3] = soc_ntohl(mh_data[3]);
    121     mh_mask[0] = soc_ntohl(mh_mask[0]);
    122     mh_mask[1] = soc_ntohl(mh_mask[1]);
    123     mh_mask[2] = soc_ntohl(mh_mask[2]);
    124     mh_mask[3] = soc_ntohl(mh_mask[3]);
    125 #endif
    126 }
    127 
    128 STATIC int
    129 _trav_filter_clean(int unit, bcm_knet_filter_t *filter, void *user_data)
    130 {
    131     return bcm_esw_knet_filter_destroy(unit, filter->id);
    132 }
    133 
    134 #endif /* INCLUDE_KNET */
    135 
    136 /*
    137  * Function:
    138  *      bcm_esw_knet_init
    139  * Purpose:
    140  *      Initialize the kernel networking subsystem.
    141  * Parameters:
    142  *      unit - (IN) Unit number.
    143  * Returns:
    144  *      BCM_E_xxx
    145  * Notes:
    146  */
    147 int 
    148 bcm_esw_knet_init(int unit)
    149 {
    150 #ifndef INCLUDE_KNET
    151     return BCM_E_UNAVAIL;
    152 #else
    153     int rv;
    154     bcm_knet_filter_t filter;
    155 
    156     rv = bcm_esw_knet_cleanup(unit);
    157 
    158     if (BCM_SUCCESS(rv)) {
    159         /* Map all queues to primary Rx DMA channel */
    160         rv = _bcm_common_rx_queue_channel_set(unit, -1, 1);
    161     }
    162 
    163     if (soc_property_get(unit, spn_KNET_FILTER_PERSIST, 0)) {
    164         /* Do not create default filter */
    165         return rv;
    166     }
    167 
    168     if (BCM_SUCCESS(rv)) {
    169         bcm_knet_filter_t_init(&filter);
    170         filter.type = BCM_KNET_FILTER_T_RX_PKT;
    171         filter.dest_type = BCM_KNET_DEST_T_BCM_RX_API;
    172         filter.priority = 255;
    173         sal_strcpy(filter.desc, "DefaultRxAPI");
    174         rv = bcm_esw_knet_filter_create(unit, &filter);
    175     }
    176     return rv; 
    177 #endif
    178 }
    179 
    180 /*
    181  * Function:
    182  *      bcm_esw_knet_cleanup
    183  * Purpose:
    184  *      Clean up the kernel networking subsystem.
    185  * Parameters:
    186  *      unit - (IN) Unit number.
    187  * Returns:
    188  *      BCM_E_xxx
    189  * Notes:
    190  */
    191 int 
    192 bcm_esw_knet_cleanup(int unit)
    193 {
    194 #ifndef INCLUDE_KNET
    195     return BCM_E_UNAVAIL;
    196 #else
    197     int rv;
    198 
    199     if (soc_property_get(unit, spn_KNET_FILTER_PERSIST, 0)) {
    200         /* Leave filters in place */
    201         return BCM_E_NONE;
    202     }
    203 
    204     rv = bcm_esw_knet_filter_traverse(unit, _trav_filter_clean, NULL);
    205 
    206     return BCM_SUCCESS(rv) ? BCM_E_NONE : rv; 
    207 #endif
    208 }
    209 
    210 /*
    211  * Function:
    212  *      bcm_esw_knet_netif_create
    213  * Purpose:
    214  *      Create a kernel network interface.
    215  * Parameters:
    216  *      unit - (IN) Unit number.
    217  *      netif - (IN/OUT) Network interface configuration
    218  * Returns:
    219  *      BCM_E_xxx
    220  * Notes:
    221  */
    222 int 
    223 bcm_esw_knet_netif_create(int unit, bcm_knet_netif_t *netif)
    224 {
    225 #ifndef INCLUDE_KNET
    226     return BCM_E_UNAVAIL;
    227 #else
    228     int rv;
    229     int qnum;
    230     kcom_msg_netif_create_t netif_create;
    231     int max_port_cos_queues;
    232 
    233     sal_memset(&netif_create, 0, sizeof(netif_create));
    234     netif_create.hdr.opcode = KCOM_M_NETIF_CREATE;
    235     netif_create.hdr.unit = unit;
    236 
    237     switch (netif->type) {
    238     case BCM_KNET_NETIF_T_TX_CPU_INGRESS:
    239         netif_create.netif.type = KCOM_NETIF_T_VLAN;
    240         break;
    241     case BCM_KNET_NETIF_T_TX_LOCAL_PORT:
    242         netif_create.netif.type = KCOM_NETIF_T_PORT;
    243         break;
    244     case BCM_KNET_NETIF_T_TX_META_DATA:
    245         netif_create.netif.type = KCOM_NETIF_T_META;
    246         break;
    247     default:
    248         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    249                     (BSL_META_U(unit,
    250                                 "KNET: Unsupported interface type\n")));
    251         return BCM_E_PARAM;
    252     }
    253 
    254     if (netif->flags & BCM_KNET_NETIF_F_ADD_TAG) {
    255         netif_create.netif.flags |= KCOM_NETIF_F_ADD_TAG;
    256     }
    257     if (netif->flags & BCM_KNET_NETIF_F_RCPU_ENCAP) {
    258         netif_create.netif.flags |= KCOM_NETIF_F_RCPU_ENCAP;
    259     }
    260     if (netif->flags & BCM_KNET_NETIF_F_KEEP_RX_TAG) {
    261         netif_create.netif.flags |= KCOM_NETIF_F_KEEP_RX_TAG;
    262     }
    263     netif_create.netif.cb_user_data = netif->cb_user_data;
    264     netif_create.netif.vlan = netif->vlan;
    265     netif_create.netif.port = netif->port;
    266 
    267     if (SOC_WARM_BOOT(unit)) {
    268         BCM_IF_ERROR_RETURN(_bcm_esw_cosq_num_get(unit, &max_port_cos_queues));
    269     } else {
    270         BCM_IF_ERROR_RETURN(bcm_esw_cosq_config_get(unit, &max_port_cos_queues));
    271     }
    272     if (!((netif->cosq >= 0) && (netif->cosq < max_port_cos_queues))) {
    273         return BCM_E_PARAM;
    274     }
    275 
    276     if (BCM_SUCCESS(soc_esw_hw_qnum_get(unit, netif->port, netif->cosq, &qnum))) {
    277         netif_create.netif.qnum = qnum;
    278     }
    279     sal_memcpy(netif_create.netif.macaddr, netif->mac_addr, 6);
    280     sal_memcpy(netif_create.netif.name, netif->name,
    281                sizeof(netif_create.netif.name) - 1);
    282 
    283     rv = soc_knet_cmd_req((kcom_msg_t *)&netif_create,
    284                           sizeof(netif_create), sizeof(netif_create));
    285     if (BCM_SUCCESS(rv)) {
    286         /* ID and interface name are assigned by kernel */
    287         netif->id = netif_create.netif.id;
    288         sal_memcpy(netif->name, netif_create.netif.name,
    289                    sizeof(netif->name) - 1);
    290     }
    291     return rv;
    292 #endif
    293 }
    294 
    295 /*
    296  * Function:
    297  *      bcm_esw_knet_netif_destroy
    298  * Purpose:
    299  *      Destroy a kernel network interface.
    300  * Parameters:
    301  *      unit - (IN) Unit number.
    302  *      netif_id - (IN) Network interface ID
    303  * Returns:
    304  *      BCM_E_xxx
    305  * Notes:
    306  */
    307 int 
    308 bcm_esw_knet_netif_destroy(int unit, int netif_id)
    309 {
    310 #ifndef INCLUDE_KNET
    311     return BCM_E_UNAVAIL;
    312 #else
    313     kcom_msg_netif_destroy_t netif_destroy;
    314 
    315     sal_memset(&netif_destroy, 0, sizeof(netif_destroy));
    316     netif_destroy.hdr.opcode = KCOM_M_NETIF_DESTROY;
    317     netif_destroy.hdr.unit = unit;
    318 
    319     netif_destroy.hdr.id = netif_id;
    320     
    321     return soc_knet_cmd_req((kcom_msg_t *)&netif_destroy,
    322                             sizeof(netif_destroy), sizeof(netif_destroy));
    323 #endif
    324 }
    325 
    326 /*
    327  * Function:
    328  *      bcm_esw_knet_netif_get
    329  * Purpose:
    330  *      Get a kernel network interface configuration.
    331  * Parameters:
    332  *      unit - (IN) Unit number.
    333  *      netif_id - (IN) Network interface ID
    334  *      netif - (OUT) Network interface configuration
    335  * Returns:
    336  *      BCM_E_xxx
    337  * Notes:
    338  */
    339 int 
    340 bcm_esw_knet_netif_get(int unit, int netif_id, bcm_knet_netif_t *netif)
    341 {
    342 #ifndef INCLUDE_KNET
    343     return BCM_E_UNAVAIL;
    344 #else
    345     int rv;
    346     kcom_msg_netif_get_t netif_get;
    347 
    348     sal_memset(&netif_get, 0, sizeof(netif_get));
    349     netif_get.hdr.opcode = KCOM_M_NETIF_GET;
    350     netif_get.hdr.unit = unit;
    351 
    352     netif_get.hdr.id = netif_id;
    353 
    354     rv = soc_knet_cmd_req((kcom_msg_t *)&netif_get,
    355                           sizeof(netif_get.hdr), sizeof(netif_get));
    356 
    357     if (BCM_SUCCESS(rv)) {
    358         bcm_knet_netif_t_init(netif);
    359 
    360         switch (netif_get.netif.type) {
    361         case KCOM_NETIF_T_VLAN:
    362             netif->type = BCM_KNET_NETIF_T_TX_CPU_INGRESS;
    363             break;
    364         case KCOM_NETIF_T_PORT:
    365             netif->type = BCM_KNET_NETIF_T_TX_LOCAL_PORT;
    366             break;
    367         case KCOM_NETIF_T_META:
    368             netif->type = BCM_KNET_NETIF_T_TX_META_DATA;
    369             break;
    370         default:
    371             /* Unknown type - defaults to VLAN */
    372             break;
    373         }
    374 
    375         if (netif_get.netif.flags & KCOM_NETIF_F_ADD_TAG) {
    376             netif->flags |= BCM_KNET_NETIF_F_ADD_TAG;
    377         }
    378         if (netif_get.netif.flags & KCOM_NETIF_F_RCPU_ENCAP) {
    379             netif->flags |= BCM_KNET_NETIF_F_RCPU_ENCAP;
    380         }
    381         if (netif_get.netif.flags & KCOM_NETIF_F_KEEP_RX_TAG) {
    382             netif->flags |= BCM_KNET_NETIF_F_KEEP_RX_TAG;
    383         }
    384 
    385         netif->id = netif_get.netif.id;
    386         netif->vlan = netif_get.netif.vlan;
    387         netif->port = netif_get.netif.port;
    388         netif->cosq = netif_get.netif.qnum -
    389                       SOC_INFO(unit).port_uc_cosq_base[netif->port];
    390         sal_memcpy(netif->mac_addr, netif_get.netif.macaddr, 6);
    391         sal_memcpy(netif->name, netif_get.netif.name,
    392                    sizeof(netif->name) - 1);
    393     }
    394 
    395     return rv;
    396 #endif
    397 }
    398 
    399 /*
    400  * Function:
    401  *      bcm_esw_knet_netif_traverse
    402  * Purpose:
    403  *      Traverse kernel network interface objects
    404  * Parameters:
    405  *      unit - (IN) Unit number.
    406  *      trav_fn - (IN) User provided call back function
    407  *      user_data - (IN) User provided data used as input param for callback function
    408  * Returns:
    409  *      BCM_E_xxx
    410  * Notes:
    411  */
    412 int 
    413 bcm_esw_knet_netif_traverse(int unit, bcm_knet_netif_traverse_cb trav_fn,
    414                             void *user_data)
    415 {
    416 #ifndef INCLUDE_KNET
    417     return BCM_E_UNAVAIL;
    418 #else
    419     int rv, idx;
    420     bcm_knet_netif_t netif;
    421     kcom_msg_netif_list_t netif_list;
    422 
    423     if (trav_fn == NULL) {
    424         return BCM_E_PARAM;
    425     }
    426 
    427     sal_memset(&netif_list, 0, sizeof(netif_list));
    428     netif_list.hdr.opcode = KCOM_M_NETIF_LIST;
    429     netif_list.hdr.unit = unit;
    430 
    431     rv = soc_knet_cmd_req((kcom_msg_t *)&netif_list,
    432                           sizeof(netif_list.hdr), sizeof(netif_list));
    433 
    434     if (BCM_SUCCESS(rv)) {
    435         for (idx = 0; idx < netif_list.ifcnt; idx++) {
    436             rv = bcm_esw_knet_netif_get(unit, netif_list.id[idx], &netif);
    437             if (BCM_SUCCESS(rv)) {
    438                 rv = trav_fn(unit, &netif, user_data);
    439             }
    440             if (BCM_FAILURE(rv)) {
    441                 break;
    442             }
    443         }
    444     }
    445 
    446     return rv;
    447 #endif
    448 }
    449 
    450 /*
    451  * Function:
    452  *      bcm_esw_knet_filter_create
    453  * Purpose:
    454  *      Create a kernel packet filter.
    455  * Parameters:
    456  *      unit - (IN) Unit number.
    457  *      filter - (IN/OUT) Rx packet filter configuration
    458  * Returns:
    459  *      BCM_E_xxx
    460  * Notes:
    461  */
    462 int 
    463 bcm_esw_knet_filter_create(int unit, bcm_knet_filter_t *filter)
    464 {
    465 #ifndef INCLUDE_KNET
    466     return BCM_E_UNAVAIL;
    467 #else
    468     int rv;
    469     int idx, pdx;
    470     int oob_size;
    471     int data_offset;
    472     uint32 reason, reason_hi, bpdu;
    473     kcom_msg_filter_create_t filter_create;
    474 
    475     sal_memset(&filter_create, 0, sizeof(filter_create));
    476     filter_create.hdr.opcode = KCOM_M_FILTER_CREATE;
    477     filter_create.hdr.unit = unit;
    478 
    479     filter_create.filter.type = KCOM_FILTER_T_RX_PKT;
    480 
    481     switch (filter->dest_type) {
    482     case BCM_KNET_DEST_T_NULL:
    483         filter_create.filter.dest_type = KCOM_DEST_T_NULL;
    484         break;
    485     case BCM_KNET_DEST_T_NETIF:
    486         filter_create.filter.dest_type = KCOM_DEST_T_NETIF;
    487         break;
    488     case BCM_KNET_DEST_T_BCM_RX_API:
    489         filter_create.filter.dest_type = KCOM_DEST_T_API;
    490         break;
    491     case BCM_KNET_DEST_T_CALLBACK:
    492         filter_create.filter.dest_type = KCOM_DEST_T_CB;
    493         break;
    494     default:
    495         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    496                     (BSL_META_U(unit,
    497                                 "KNET: Unsupported destination type\n")));
    498         return BCM_E_PARAM;
    499     }
    500 
    501     switch (filter->mirror_type) {
    502     case BCM_KNET_DEST_T_NULL:
    503         filter_create.filter.mirror_type = KCOM_DEST_T_NULL;
    504         break;
    505     case BCM_KNET_DEST_T_NETIF:
    506         filter_create.filter.mirror_type = KCOM_DEST_T_NETIF;
    507         break;
    508     case BCM_KNET_DEST_T_BCM_RX_API:
    509         filter_create.filter.mirror_type = KCOM_DEST_T_API;
    510         break;
    511     case BCM_KNET_DEST_T_CALLBACK:
    512         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    513                     (BSL_META_U(unit,
    514                                 "KNET: Cannot mirror to callback\n")));
    515         return BCM_E_PARAM;
    516     default:
    517         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    518                     (BSL_META_U(unit,
    519                                 "KNET: Unsupported mirror type\n")));
    520         return BCM_E_PARAM;
    521     }
    522 
    523     if (filter->flags & BCM_KNET_FILTER_F_STRIP_TAG) {
    524         filter_create.filter.flags |= KCOM_FILTER_F_STRIP_TAG;
    525     }
    526 
    527     filter_create.filter.cb_user_data = filter->cb_user_data;
    528     filter_create.filter.dest_id = filter->dest_id;
    529     filter_create.filter.dest_proto = filter->dest_proto;
    530     filter_create.filter.mirror_id = filter->mirror_id;
    531     filter_create.filter.mirror_proto = filter->mirror_proto;
    532 
    533     filter_create.filter.priority = filter->priority;
    534     sal_strncpy(filter_create.filter.desc, filter->desc,
    535                 sizeof(filter_create.filter.desc) - 1);
    536 
    537     oob_size = 0;
    538     if (filter->match_flags & ~BCM_KNET_FILTER_M_RAW) {
    539         oob_size = SOC_DCB_SIZE(unit);
    540     }
    541 
    542     /* Create inverted mask */
    543     for (idx = 0; idx < oob_size; idx++) {
    544         filter_create.filter.mask.b[idx] = 0xff;
    545     }
    546 
    547     bpdu = 0;
    548     if (BCM_RX_REASON_GET(filter->m_reason, bcmRxReasonBpdu)){
    549         bpdu = 1;
    550     }
    551     reason = _rx_reason_get(unit, &filter->m_reason);
    552     reason_hi = 0;
    553     if (soc_feature(unit, soc_feature_dcb_reason_hi)) {
    554         reason_hi = _rx_reason_hi_get(unit, &filter->m_reason);
    555     }
    556 
    557 #if defined(BCM_TOMAHAWK3_SUPPORT)
    558     if (SOC_DCB_TYPE(unit) == 38) {
    559         reason &= ~0x30000;
    560         if ((BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSource) &&
    561              BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSourceFlex)) ||
    562             (BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSource) &&
    563              BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleDest)) ||
    564             (BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSourceFlex) &&
    565              BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleDest))) {
    566             /* TH3 can not support these cases in one filter */
    567             return BCM_E_PARAM;
    568         } else {
    569             if (BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSourceFlex)) {
    570                 reason |= 0x10000;
    571             }
    572             if (BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleDest)) {
    573                 reason |= 0x20000;
    574             }
    575             if (BCM_RX_REASON_GET(filter->m_reason, socRxReasonSampleSource)) {
    576                 reason |= 0x30000;
    577             }
    578         }
    579     }
    580 #endif
    581 
    582     /* Check if specified reason is supported */
    583     if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    584         if ((reason + reason_hi + bpdu) == 0) {
    585             LOG_VERBOSE(BSL_LS_SOC_COMMON,
    586                         (BSL_META_U(unit,
    587                                     "KNET: Unsupported Rx reason\n")));
    588             return BCM_E_PARAM;
    589         }
    590     }
    591 
    592 #if defined(BCM_FIREBOLT_SUPPORT)
    593     if (SOC_DCB_TYPE(unit) == 9) {
    594         dcb9_t *dcb_data = (dcb9_t *)&filter_create.filter.data;
    595         dcb9_t *dcb_mask = (dcb9_t *)&filter_create.filter.mask;
    596 
    597         /* Set module header match fields */
    598         _higig_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    599 
    600         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    601             dcb_data->outer_vid = filter->m_vlan;
    602             dcb_mask->outer_vid = 0;
    603         }
    604         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    605             dcb_data->srcport = filter->m_ingport;
    606             dcb_mask->srcport = 0;
    607         }
    608         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    609             dcb_data->reason = reason;
    610             dcb_mask->reason = ~reason;
    611             dcb_data->bpdu = bpdu;
    612             dcb_mask->bpdu = ~bpdu;
    613         }
    614         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    615             dcb_data->match_rule = filter->m_fp_rule;
    616             dcb_mask->match_rule = 0;
    617         }
    618         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    619             dcb_data->error = 1;
    620             dcb_mask->error = 0;
    621         }
    622     } else
    623 #endif
    624 
    625 #if defined(BCM_BRADLEY_SUPPORT)
    626     if (SOC_DCB_TYPE(unit) == 11) {
    627         dcb11_t *dcb_data = (dcb11_t *)&filter_create.filter.data;
    628         dcb11_t *dcb_mask = (dcb11_t *)&filter_create.filter.mask;
    629 
    630         /* Set module header match fields */
    631         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    632 
    633         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    634             dcb_data->outer_vid = filter->m_vlan;
    635             dcb_mask->outer_vid = 0;
    636         }
    637         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    638             dcb_data->srcport = filter->m_ingport;
    639             dcb_mask->srcport = 0;
    640         }
    641         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    642             dcb_data->reason = reason;
    643             dcb_mask->reason = ~reason;
    644             dcb_data->bpdu = bpdu;
    645             dcb_mask->bpdu = ~bpdu;
    646         }
    647         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    648             dcb_data->match_rule = filter->m_fp_rule;
    649             dcb_mask->match_rule = 0;
    650         }
    651         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    652             dcb_data->error = 1;
    653             dcb_mask->error = 0;
    654         }
    655     } else
    656 #endif
    657 
    658 #if defined(BCM_RAPTOR_SUPPORT)
    659     if (SOC_DCB_TYPE(unit) == 12) {
    660         dcb12_t *dcb_data = (dcb12_t *)&filter_create.filter.data;
    661         dcb12_t *dcb_mask = (dcb12_t *)&filter_create.filter.mask;
    662 
    663         /* Set module header match fields */
    664         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    665 
    666         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    667             dcb_data->outer_vid = filter->m_vlan;
    668             dcb_mask->outer_vid = 0;
    669         }
    670         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    671             dcb_data->srcport = filter->m_ingport;
    672             dcb_mask->srcport = 0;
    673         }
    674         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    675             dcb_data->reason = reason;
    676             dcb_mask->reason = ~reason;
    677             dcb_data->bpdu = bpdu;
    678             dcb_mask->bpdu = ~bpdu;
    679 
    680         }
    681         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    682             dcb_data->match_rule = filter->m_fp_rule;
    683             dcb_mask->match_rule = 0;
    684         }
    685         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    686             dcb_data->error = 1;
    687             dcb_mask->error = 0;
    688         }
    689     } else
    690 #endif
    691 
    692 #if defined(BCM_FIREBOLT2_SUPPORT)
    693     if (SOC_DCB_TYPE(unit) == 13) {
    694         dcb13_t *dcb_data = (dcb13_t *)&filter_create.filter.data;
    695         dcb13_t *dcb_mask = (dcb13_t *)&filter_create.filter.mask;
    696 
    697         /* Set module header match fields */
    698         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    699 
    700         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    701             dcb_data->outer_vid = filter->m_vlan;
    702             dcb_mask->outer_vid = 0;
    703         }
    704         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    705             dcb_data->srcport = filter->m_ingport;
    706             dcb_mask->srcport = 0;
    707         }
    708         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    709             dcb_data->reason = reason;
    710             dcb_mask->reason = ~reason;
    711             dcb_data->bpdu = bpdu;
    712             dcb_mask->bpdu = ~bpdu;
    713         }
    714         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    715             dcb_data->match_rule = filter->m_fp_rule;
    716             dcb_mask->match_rule = 0;
    717         }
    718         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    719             dcb_data->error = 1;
    720             dcb_mask->error = 0;
    721         }
    722     } else
    723 #endif
    724 
    725 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
    726     if (SOC_DCB_TYPE(unit) == 14) {
    727         dcb14_t *dcb_data = (dcb14_t *)&filter_create.filter.data;
    728         dcb14_t *dcb_mask = (dcb14_t *)&filter_create.filter.mask;
    729 
    730         /* Set module header match fields */
    731         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    732 
    733         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    734             dcb_data->outer_vid = filter->m_vlan;
    735             dcb_mask->outer_vid = 0;
    736         }
    737         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    738             dcb_data->srcport = filter->m_ingport;
    739             dcb_mask->srcport = 0;
    740         }
    741         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    742             dcb_data->reason = reason;
    743             dcb_mask->reason = ~reason;
    744             dcb_data->reason_hi = reason_hi;
    745             dcb_mask->reason_hi = ~reason_hi;
    746             dcb_data->bpdu = bpdu;
    747             dcb_mask->bpdu = ~bpdu;
    748         }
    749         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    750             dcb_data->match_rule = filter->m_fp_rule;
    751             dcb_mask->match_rule = 0;
    752         }
    753         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    754             dcb_data->error = 1;
    755             dcb_mask->error = 0;
    756         }
    757     } else
    758 #endif
    759 
    760 #if defined (BCM_RAVEN_SUPPORT)
    761     if (SOC_DCB_TYPE(unit) == 15) {
    762         dcb15_t *dcb_data = (dcb15_t *)&filter_create.filter.data;
    763         dcb15_t *dcb_mask = (dcb15_t *)&filter_create.filter.mask;
    764 
    765         /* Set module header match fields */
    766         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    767 
    768         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    769             dcb_data->outer_vid = filter->m_vlan;
    770             dcb_mask->outer_vid = 0;
    771         }
    772         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    773             dcb_data->srcport = filter->m_ingport;
    774             dcb_mask->srcport = 0;
    775         }
    776         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    777             dcb_data->reason = reason;
    778             dcb_mask->reason = ~reason;
    779             dcb_data->bpdu = bpdu;
    780             dcb_mask->bpdu = ~bpdu;
    781         }
    782         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    783             dcb_data->match_rule = filter->m_fp_rule;
    784             dcb_mask->match_rule = 0;
    785         }
    786         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    787             dcb_data->error = 1;
    788             dcb_mask->error = 0;
    789         }
    790     } else if (SOC_DCB_TYPE(unit) == 18) {
    791         dcb18_t *dcb_data = (dcb18_t *)&filter_create.filter.data;
    792         dcb18_t *dcb_mask = (dcb18_t *)&filter_create.filter.mask;
    793 
    794         /* Set module header match fields */
    795         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    796 
    797         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    798             dcb_data->outer_vid = filter->m_vlan;
    799             dcb_mask->outer_vid = 0;
    800         }
    801         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    802             dcb_data->srcport = filter->m_ingport;
    803             dcb_mask->srcport = 0;
    804         }
    805         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    806             dcb_data->reason = reason;
    807             dcb_mask->reason = ~reason;
    808             dcb_data->bpdu = bpdu;
    809             dcb_mask->bpdu = ~bpdu;
    810         }
    811         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    812             dcb_data->match_rule = filter->m_fp_rule;
    813             dcb_mask->match_rule = 0;
    814         }
    815         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    816             dcb_data->error = 1;
    817             dcb_mask->error = 0;
    818         }
    819     } else
    820 #endif
    821 
    822 #if defined (BCM_SCORPION_SUPPORT)
    823     if (SOC_DCB_TYPE(unit) == 16) {
    824         dcb16_t *dcb_data = (dcb16_t *)&filter_create.filter.data;
    825         dcb16_t *dcb_mask = (dcb16_t *)&filter_create.filter.mask;
    826 
    827         /* Set module header match fields */
    828         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    829 
    830         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    831             dcb_data->outer_vid = filter->m_vlan;
    832             dcb_mask->outer_vid = 0;
    833         }
    834         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    835             dcb_data->srcport = filter->m_ingport;
    836             dcb_mask->srcport = 0;
    837         }
    838         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    839             dcb_data->reason = reason;
    840             dcb_mask->reason = ~reason;
    841             dcb_data->bpdu = bpdu;
    842             dcb_mask->bpdu = ~bpdu;
    843         }
    844         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    845             dcb_data->match_rule = filter->m_fp_rule;
    846             dcb_mask->match_rule = 0;
    847         }
    848         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    849             dcb_data->error = 1;
    850             dcb_mask->error = 0;
    851         }
    852     } else
    853 #endif
    854 
    855 #if defined (BCM_HAWKEYE_SUPPORT)
    856     if (SOC_DCB_TYPE(unit) == 17) {
    857         dcb17_t *dcb_data = (dcb17_t *)&filter_create.filter.data;
    858         dcb17_t *dcb_mask = (dcb17_t *)&filter_create.filter.mask;
    859 
    860         /* Set module header match fields */
    861         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    862 
    863         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    864             dcb_data->outer_vid = filter->m_vlan;
    865             dcb_mask->outer_vid = 0;
    866         }
    867         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    868             dcb_data->srcport = filter->m_ingport;
    869             dcb_mask->srcport = 0;
    870         }
    871         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    872             dcb_data->reason = reason;
    873             dcb_mask->reason = ~reason;
    874             dcb_data->bpdu = bpdu;
    875             dcb_mask->bpdu = ~bpdu;
    876         }
    877         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    878             dcb_data->match_rule = filter->m_fp_rule;
    879             dcb_mask->match_rule = 0;
    880         }
    881         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    882             dcb_data->error = 1;
    883             dcb_mask->error = 0;
    884         }
    885     } else
    886 #endif
    887 
    888 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_SHADOW_SUPPORT)
    889     if (SOC_DCB_TYPE(unit) == 19) {
    890         dcb19_t *dcb_data = (dcb19_t *)&filter_create.filter.data;
    891         dcb19_t *dcb_mask = (dcb19_t *)&filter_create.filter.mask;
    892 
    893         /* Set module header match fields */
    894         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    895 
    896         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    897             dcb_data->outer_vid = filter->m_vlan;
    898             dcb_mask->outer_vid = 0;
    899         }
    900         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    901             dcb_data->srcport = filter->m_ingport;
    902             dcb_mask->srcport = 0;
    903         }
    904         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    905             dcb_data->reason = reason;
    906             dcb_mask->reason = ~reason;
    907             dcb_data->reason_hi = reason_hi;
    908             dcb_mask->reason_hi = ~reason_hi;
    909             dcb_data->bpdu = bpdu;
    910             dcb_mask->bpdu = ~bpdu;
    911         }
    912         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    913             dcb_data->match_rule = filter->m_fp_rule;
    914             dcb_mask->match_rule = 0;
    915         }
    916         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    917             dcb_data->error = 1;
    918             dcb_mask->error = 0;
    919         }
    920     } else
    921 #endif
    922 
    923 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
    924         if ((SOC_DCB_TYPE(unit) == 20) || (SOC_DCB_TYPE(unit) == 30)) {
    925         dcb20_t *dcb_data = (dcb20_t *)&filter_create.filter.data;
    926         dcb20_t *dcb_mask = (dcb20_t *)&filter_create.filter.mask;
    927 
    928         /* Set module header match fields */
    929         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    930 
    931         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    932             dcb_data->outer_vid = filter->m_vlan;
    933             dcb_mask->outer_vid = 0;
    934         }
    935         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    936             dcb_data->srcport = filter->m_ingport;
    937             dcb_mask->srcport = 0;
    938         }
    939         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    940             dcb_data->reason = reason;
    941             dcb_mask->reason = ~reason;
    942             dcb_data->reason_hi = reason_hi;
    943             dcb_mask->reason_hi = ~reason_hi;
    944             dcb_data->bpdu = bpdu;
    945             dcb_mask->bpdu = ~bpdu;
    946         }
    947         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    948             dcb_data->match_rule = filter->m_fp_rule;
    949             dcb_mask->match_rule = 0;
    950         }
    951         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    952             dcb_data->error = 1;
    953             dcb_mask->error = 0;
    954         }
    955     } else
    956 #endif
    957 
    958 #if defined(BCM_TRIDENT_SUPPORT)
    959     if (SOC_DCB_TYPE(unit) == 21) {
    960         dcb21_t *dcb_data = (dcb21_t *)&filter_create.filter.data;
    961         dcb21_t *dcb_mask = (dcb21_t *)&filter_create.filter.mask;
    962 
    963         /* Set module header match fields */
    964         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
    965 
    966         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
    967             dcb_data->outer_vid = filter->m_vlan;
    968             dcb_mask->outer_vid = 0;
    969         }
    970         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
    971             dcb_data->srcport = filter->m_ingport;
    972             dcb_mask->srcport = 0;
    973         }
    974         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
    975             dcb_data->reason = reason;
    976             dcb_mask->reason = ~reason;
    977             dcb_data->reason_hi = reason_hi;
    978             dcb_mask->reason_hi = ~reason_hi;
    979             dcb_data->bpdu = bpdu;
    980             dcb_mask->bpdu = ~bpdu;
    981         }
    982         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
    983             dcb_data->match_rule = filter->m_fp_rule;
    984             dcb_mask->match_rule = 0;
    985         }
    986         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
    987             dcb_data->error = 1;
    988             dcb_mask->error = 0;
    989         }
    990     } else
    991 #endif
    992 
    993 #if defined(BCM_TRIUMPH3_SUPPORT)
    994     if (SOC_DCB_TYPE(unit) == 23) {
    995         dcb23_t *dcb_data = (dcb23_t *)&filter_create.filter.data;
    996         dcb23_t *dcb_mask = (dcb23_t *)&filter_create.filter.mask;
    997 
    998         /* Set module header match fields */
    999         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1000 
   1001         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1002             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1003             dcb_mask->word4.overlay1.outer_vid = 0;
   1004         }
   1005         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1006             dcb_data->srcport = filter->m_ingport;
   1007             dcb_mask->srcport = 0;
   1008         }
   1009         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1010             dcb_data->reason = reason;
   1011             dcb_mask->reason = ~reason;
   1012             dcb_data->reason_hi = reason_hi;
   1013             dcb_mask->reason_hi = ~reason_hi;
   1014             dcb_data->bpdu = bpdu;
   1015             dcb_mask->bpdu = ~bpdu;
   1016         }
   1017         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1018             dcb_data->match_rule = filter->m_fp_rule;
   1019             dcb_mask->match_rule = 0;
   1020         }
   1021         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1022             dcb_data->error = 1;
   1023             dcb_mask->error = 0;
   1024         }
   1025     } else
   1026 #endif
   1027 
   1028 #if defined(BCM_KATANA_SUPPORT)
   1029     if (SOC_DCB_TYPE(unit) == 24) {
   1030         dcb24_t *dcb_data = (dcb24_t *)&filter_create.filter.data;
   1031         dcb24_t *dcb_mask = (dcb24_t *)&filter_create.filter.mask;
   1032 
   1033         /* Set module header match fields */
   1034         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1035 
   1036         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1037             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1038             dcb_mask->word4.overlay1.outer_vid = 0;
   1039         }
   1040         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1041             dcb_data->srcport = filter->m_ingport;
   1042             dcb_mask->srcport = 0;
   1043         }
   1044         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1045             dcb_data->reason = reason;
   1046             dcb_mask->reason = ~reason;
   1047             dcb_data->reason_hi = reason_hi;
   1048             dcb_mask->reason_hi = ~reason_hi;
   1049             dcb_data->bpdu = bpdu;
   1050             dcb_mask->bpdu = ~bpdu;
   1051         }
   1052         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1053             dcb_data->match_rule = filter->m_fp_rule;
   1054             dcb_mask->match_rule = 0;
   1055         }
   1056         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1057             dcb_data->error = 1;
   1058             dcb_mask->error = 0;
   1059         }
   1060     } else
   1061 #endif
   1062 
   1063 #if defined(BCM_TRIDENT2_SUPPORT)
   1064     if (SOC_DCB_TYPE(unit) == 26) {
   1065         dcb26_t *dcb_data = (dcb26_t *)&filter_create.filter.data;
   1066         dcb26_t *dcb_mask = (dcb26_t *)&filter_create.filter.mask;
   1067 
   1068         /* Set module header match fields */
   1069         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1070 
   1071         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1072             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1073             dcb_mask->word4.overlay1.outer_vid = 0;
   1074         }
   1075         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1076             dcb_data->srcport = filter->m_ingport;
   1077             dcb_mask->srcport = 0;
   1078         }
   1079         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1080             dcb_data->reason = reason;
   1081             dcb_mask->reason = ~reason;
   1082             dcb_data->reason_hi = reason_hi;
   1083             dcb_mask->reason_hi = ~reason_hi;
   1084             dcb_data->switch_pkt = 1;
   1085             dcb_mask->switch_pkt = 0;
   1086             dcb_data->bpdu = bpdu;
   1087             dcb_mask->bpdu = ~bpdu;
   1088         }
   1089         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1090             dcb_data->match_rule = filter->m_fp_rule;
   1091             dcb_mask->match_rule = 0;
   1092         }
   1093         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1094             dcb_data->error = 1;
   1095             dcb_mask->error = 0;
   1096         }
   1097     } else
   1098 #endif
   1099 
   1100 #if defined(BCM_KATANA2_SUPPORT)
   1101     if (SOC_DCB_TYPE(unit) == 29) {
   1102         dcb29_t *dcb_data = (dcb29_t *)&filter_create.filter.data;
   1103         dcb29_t *dcb_mask = (dcb29_t *)&filter_create.filter.mask;
   1104 
   1105         /* Set module header match fields */
   1106         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1107 
   1108         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1109             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1110             dcb_mask->word4.overlay1.outer_vid = 0;
   1111         }
   1112         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1113             dcb_data->srcport = filter->m_ingport;
   1114             dcb_mask->srcport = 0;
   1115         }
   1116         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1117             dcb_data->reason = reason;
   1118             dcb_mask->reason = ~reason;
   1119             dcb_data->word2.overlay1.reason_hi = reason_hi;
   1120             dcb_mask->word2.overlay1.reason_hi = ~reason_hi;
   1121             dcb_data->switch_pkt = 1;
   1122             dcb_mask->switch_pkt = 0;
   1123             dcb_data->bpdu = bpdu;
   1124             dcb_mask->bpdu = ~bpdu;
   1125         }
   1126         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1127             dcb_data->match_rule = filter->m_fp_rule;
   1128             dcb_mask->match_rule = 0;
   1129         }
   1130         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1131             dcb_data->error = 1;
   1132             dcb_mask->error = 0;
   1133         }
   1134     } else
   1135 #endif
   1136 
   1137 #if defined(BCM_GREYHOUND_SUPPORT)
   1138         if (SOC_DCB_TYPE(unit) == 31) {
   1139             dcb31_t *dcb_data = (dcb31_t *)&filter_create.filter.data;
   1140             dcb31_t *dcb_mask = (dcb31_t *)&filter_create.filter.mask;
   1141     
   1142             /* Set module header match fields */
   1143             _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1144     
   1145             if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1146                 dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1147                 dcb_mask->word4.overlay1.outer_vid = 0;
   1148             }
   1149             if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1150                 dcb_data->srcport = filter->m_ingport;
   1151                 dcb_mask->srcport = 0;
   1152             }
   1153             if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1154                 dcb_data->reason = reason;
   1155                 dcb_mask->reason = ~reason;
   1156                 dcb_data->reason_hi = reason_hi;
   1157                 dcb_mask->reason_hi = ~reason_hi;
   1158                 dcb_data->bpdu = bpdu;
   1159                 dcb_mask->bpdu = ~bpdu;
   1160             }
   1161             if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1162                 dcb_data->match_rule = filter->m_fp_rule;
   1163                 dcb_mask->match_rule = 0;
   1164             }
   1165             if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1166                 dcb_data->error = 1;
   1167                 dcb_mask->error = 0;
   1168             }
   1169         } else
   1170 #endif
   1171 
   1172 #if defined(BCM_TOMAHAWK_SUPPORT)
   1173     if (SOC_DCB_TYPE(unit) == 32) {
   1174         dcb32_t *dcb_data = (dcb32_t *)&filter_create.filter.data;
   1175         dcb32_t *dcb_mask = (dcb32_t *)&filter_create.filter.mask;
   1176 
   1177         /* Set module header match fields */
   1178         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1179 
   1180         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1181             dcb_data->outer_vid = filter->m_vlan;
   1182             dcb_mask->outer_vid = 0;
   1183         }
   1184         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1185             dcb_data->srcport = filter->m_ingport;
   1186             dcb_mask->srcport = 0;
   1187         }
   1188         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1189             dcb_data->reason = reason;
   1190             dcb_mask->reason = ~reason;
   1191             dcb_data->reason_hi = reason_hi;
   1192             dcb_mask->reason_hi = ~reason_hi;
   1193             dcb_data->switch_pkt = 1;
   1194             dcb_mask->switch_pkt = 0;
   1195             dcb_data->bpdu = bpdu;
   1196             dcb_mask->bpdu = ~bpdu;
   1197         }
   1198         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1199             dcb_data->match_rule = filter->m_fp_rule;
   1200             dcb_mask->match_rule = 0;
   1201         }
   1202         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1203             dcb_data->error = 1;
   1204             dcb_mask->error = 0;
   1205         }
   1206     } else
   1207 #endif
   1208 
   1209 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1210     if (SOC_DCB_TYPE(unit) == 33) {
   1211         dcb33_t *dcb_data = (dcb33_t *)&filter_create.filter.data;
   1212         dcb33_t *dcb_mask = (dcb33_t *)&filter_create.filter.mask;
   1213 
   1214         /* Set module header match fields */
   1215         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1216 
   1217         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1218             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1219             dcb_mask->word4.overlay1.outer_vid = 0;
   1220         }
   1221         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1222             dcb_data->srcport = filter->m_ingport;
   1223             dcb_mask->srcport = 0;
   1224         }
   1225         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1226             dcb_data->reason = reason;
   1227             dcb_mask->reason = ~reason;
   1228             dcb_data->reason_hi = reason_hi;
   1229             dcb_mask->reason_hi = ~reason_hi;
   1230             dcb_data->switch_pkt = 1;
   1231             dcb_mask->switch_pkt = 0;
   1232             dcb_data->bpdu = bpdu;
   1233             dcb_mask->bpdu = ~bpdu;
   1234         }
   1235         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1236             dcb_data->match_rule = filter->m_fp_rule;
   1237             dcb_mask->match_rule = 0;
   1238         }
   1239         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1240             dcb_data->error = 1;
   1241             dcb_mask->error = 0;
   1242         }
   1243     } else
   1244 #endif
   1245 
   1246 #if defined(BCM_HURRICANE3_SUPPORT)
   1247     if (SOC_DCB_TYPE(unit) == 34) {
   1248         dcb34_t *dcb_data = (dcb34_t *)&filter_create.filter.data;
   1249         dcb34_t *dcb_mask = (dcb34_t *)&filter_create.filter.mask;
   1250 
   1251         /* Set module header match fields */
   1252         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1253 
   1254         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1255             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1256             dcb_mask->word4.overlay1.outer_vid = 0;
   1257         }
   1258         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1259             dcb_data->srcport = filter->m_ingport;
   1260             dcb_mask->srcport = 0;
   1261         }
   1262         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1263             dcb_data->reason = reason;
   1264             dcb_mask->reason = ~reason;
   1265             dcb_data->reason_hi = reason_hi;
   1266             dcb_mask->reason_hi = ~reason_hi;
   1267             dcb_data->bpdu = bpdu;
   1268             dcb_mask->bpdu = ~bpdu;
   1269         }
   1270         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1271             dcb_data->match_rule = filter->m_fp_rule;
   1272             dcb_mask->match_rule = 0;
   1273         }
   1274         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1275             dcb_data->error = 1;
   1276             dcb_mask->error = 0;
   1277         }
   1278     } else
   1279 #endif
   1280 
   1281 #if defined(BCM_APACHE_SUPPORT)
   1282     if (SOC_DCB_TYPE(unit) == 35) {
   1283         dcb35_t *dcb_data = (dcb35_t *)&filter_create.filter.data;
   1284         dcb35_t *dcb_mask = (dcb35_t *)&filter_create.filter.mask;
   1285 
   1286         /* Set module header match fields */
   1287         _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1288 
   1289         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1290             dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1291             dcb_mask->word4.overlay1.outer_vid = 0;
   1292         }
   1293         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1294             dcb_data->srcport = filter->m_ingport;
   1295             dcb_mask->srcport = 0;
   1296         }
   1297         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1298             dcb_data->reason = reason;
   1299             dcb_mask->reason = ~reason;
   1300             dcb_data->reason_hi = reason_hi;
   1301             dcb_mask->reason_hi = ~reason_hi;
   1302             dcb_data->switch_pkt = 1;
   1303             dcb_mask->switch_pkt = 0;
   1304             dcb_data->bpdu = bpdu;
   1305             dcb_mask->bpdu = ~bpdu;
   1306         }
   1307         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1308             dcb_data->match_rule = filter->m_fp_rule;
   1309             dcb_mask->match_rule = 0;
   1310         }
   1311         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1312             dcb_data->error = 1;
   1313             dcb_mask->error = 0;
   1314         }
   1315     } else
   1316 #endif
   1317 
   1318 #if defined(BCM_TRIDENT3_SUPPORT)
   1319     if (SOC_DCB_TYPE(unit) == 36) {
   1320         ep_to_cpu_hdr36_t *hdr_data = (ep_to_cpu_hdr36_t *)&filter_create.filter.data;
   1321         ep_to_cpu_hdr36_t *hdr_mask = (ep_to_cpu_hdr36_t *)&filter_create.filter.mask;
   1322         dcb36_t *dcb_data = (dcb36_t *)&filter_create.filter.data.b[sizeof(ep_to_cpu_hdr36_t) - sizeof(dcb36_t)];
   1323         dcb36_t *dcb_mask = (dcb36_t *)&filter_create.filter.mask.b[sizeof(ep_to_cpu_hdr36_t) - sizeof(dcb36_t)];
   1324 
   1325         oob_size = sizeof(ep_to_cpu_hdr36_t);
   1326 
   1327         /* Create inverted mask */
   1328         for (idx = 0; idx < oob_size; idx++) {
   1329             filter_create.filter.mask.b[idx] = 0xff;
   1330         }
   1331 
   1332         /* Set module header match fields */
   1333         _higig2_match_set(filter, &hdr_data->mh0, &hdr_mask->mh0);
   1334 
   1335         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1336             hdr_data->outer_vid = filter->m_vlan;
   1337             hdr_mask->outer_vid = 0;
   1338         }
   1339         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1340             hdr_data->word8.overlay1.srcport = filter->m_ingport;
   1341             hdr_mask->word8.overlay1.srcport = 0;
   1342         }
   1343         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1344             hdr_data->reason = reason;
   1345             hdr_mask->reason = ~reason;
   1346             hdr_data->reason_hi = reason_hi;
   1347             hdr_mask->reason_hi = ~reason_hi;
   1348             hdr_data->switch_pkt = 1;
   1349             hdr_mask->switch_pkt = 0;
   1350             hdr_data->bpdu = bpdu;
   1351             hdr_mask->bpdu = ~bpdu;
   1352         }
   1353         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1354             hdr_data->match_rule = filter->m_fp_rule;
   1355             hdr_mask->match_rule = 0;
   1356         }
   1357         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1358             dcb_data->error = 1;
   1359             dcb_mask->error = 0;
   1360         }
   1361     } else
   1362 #endif
   1363 
   1364 #if defined(BCM_GREYHOUND2_SUPPORT)
   1365         if (SOC_DCB_TYPE(unit) == 37) {
   1366             dcb37_t *dcb_data = (dcb37_t *)&filter_create.filter.data;
   1367             dcb37_t *dcb_mask = (dcb37_t *)&filter_create.filter.mask;
   1368 
   1369             /* Set module header match fields */
   1370             _higig2_match_set(filter, &dcb_data->mh0, &dcb_mask->mh0);
   1371 
   1372             if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1373                 dcb_data->word4.overlay1.outer_vid = filter->m_vlan;
   1374                 dcb_mask->word4.overlay1.outer_vid = 0;
   1375             }
   1376             if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1377                 dcb_data->srcport = filter->m_ingport;
   1378                 dcb_mask->srcport = 0;
   1379             }
   1380             if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1381                 dcb_data->reason = reason;
   1382                 dcb_mask->reason = ~reason;
   1383                 dcb_data->reason_hi = reason_hi;
   1384                 dcb_mask->reason_hi = ~reason_hi;
   1385                 dcb_data->bpdu = bpdu;
   1386                 dcb_mask->bpdu = ~bpdu;
   1387             }
   1388             if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1389                 dcb_data->match_rule = filter->m_fp_rule;
   1390                 dcb_mask->match_rule = 0;
   1391             }
   1392             if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1393                 dcb_data->error = 1;
   1394                 dcb_mask->error = 0;
   1395             }
   1396         } else
   1397 #endif
   1398 
   1399 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1400     if (SOC_DCB_TYPE(unit) == 38) {
   1401         ep_to_cpu_hdr38_t *hdr_data = (ep_to_cpu_hdr38_t *)&filter_create.filter.data;
   1402         ep_to_cpu_hdr38_t *hdr_mask = (ep_to_cpu_hdr38_t *)&filter_create.filter.mask;
   1403         dcb38_t *dcb_data;
   1404         dcb38_t *dcb_mask;
   1405 
   1406         oob_size = soc_cmicx_pktdma_header_size_get(unit);
   1407         dcb_data = (dcb38_t *)&filter_create.filter.data.b[oob_size - sizeof(dcb38_t)];
   1408         dcb_mask = (dcb38_t *)&filter_create.filter.mask.b[oob_size - sizeof(dcb38_t)];
   1409 
   1410         /* Create inverted mask */
   1411         for (idx = 0; idx < oob_size; idx++) {
   1412             filter_create.filter.mask.b[idx] = 0xff;
   1413         }
   1414 
   1415         /* Set module header match fields */
   1416         _higig2_match_set(filter, &hdr_data->mh0, &hdr_mask->mh0);
   1417 
   1418         if (filter->match_flags & BCM_KNET_FILTER_M_VLAN) {
   1419             hdr_data->outer_vid = filter->m_vlan;
   1420             hdr_mask->outer_vid = 0;
   1421         }
   1422         if (filter->match_flags & BCM_KNET_FILTER_M_INGPORT) {
   1423             hdr_data->srcport = filter->m_ingport;
   1424             hdr_mask->srcport = 0;
   1425         }
   1426         if (filter->match_flags & BCM_KNET_FILTER_M_REASON) {
   1427             hdr_data->reason = reason;
   1428             hdr_mask->reason = ~(reason | ((reason & 0x30000) ? 0x30000 : 0));
   1429             hdr_data->reason_hi = reason_hi;
   1430             hdr_mask->reason_hi = ~reason_hi;
   1431             hdr_data->switch_pkt = 1;
   1432             hdr_mask->switch_pkt = 0;
   1433             hdr_data->word0.overlay1.bpdu = bpdu;
   1434             hdr_mask->word0.overlay1.bpdu = ~bpdu;
   1435         }
   1436         if (filter->match_flags & BCM_KNET_FILTER_M_FP_RULE) {
   1437             hdr_data->match_rule = filter->m_fp_rule;
   1438             hdr_mask->match_rule = 0;
   1439         }
   1440         if (filter->match_flags & BCM_KNET_FILTER_M_ERROR) {
   1441             dcb_data->error = 1;
   1442             dcb_mask->error = 0;
   1443         }
   1444     } else
   1445 #endif
   1446 
   1447     if (filter->match_flags & ~BCM_KNET_FILTER_M_RAW) {
   1448         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1449                     (BSL_META_U(unit,
   1450                                 "KNET: Unsupported DCB format\n")));
   1451 
   1452         /* Avoid partial build failures */
   1453         _higig_match_set(NULL, NULL, NULL);
   1454         _higig2_match_set(NULL, NULL, NULL);
   1455 
   1456         return BCM_E_UNAVAIL;
   1457     }
   1458 
   1459     /* Invert inverted mask */
   1460     for (idx = 0; idx < oob_size; idx++) {
   1461         filter_create.filter.mask.b[idx] ^= 0xff;
   1462     }
   1463 
   1464     filter_create.filter.oob_data_size = oob_size;
   1465 
   1466     if (filter->match_flags & BCM_KNET_FILTER_M_RAW) {
   1467         data_offset = 0;
   1468         for (pdx = 0; pdx < filter->raw_size; pdx++) {
   1469             if (filter->m_raw_mask[pdx] != 0) {
   1470                 data_offset = pdx;
   1471                 break;
   1472             }
   1473         }
   1474         idx = oob_size;
   1475         for (; pdx < filter->raw_size; pdx++) {
   1476             /* Check for array overflow */
   1477             if (idx >= KCOM_FILTER_BYTES_MAX) {
   1478                 return BCM_E_PARAM;
   1479             }
   1480             filter_create.filter.data.b[idx] = filter->m_raw_data[pdx];
   1481             filter_create.filter.mask.b[idx] = filter->m_raw_mask[pdx];
   1482             idx++;
   1483         }
   1484         filter_create.filter.pkt_data_offset = data_offset;
   1485         filter_create.filter.pkt_data_size = filter->raw_size - data_offset;
   1486     }
   1487 
   1488     /*
   1489      * If no match flags are set we treat raw filter data as OOB data.
   1490      * Note that this functionality is intended for debugging only.
   1491      */
   1492     if (filter->match_flags == 0) {
   1493         for (idx = 0; idx < filter->raw_size; idx++) {
   1494             /* Check for array overflow */
   1495             if (idx >= KCOM_FILTER_BYTES_MAX) {
   1496                 return BCM_E_PARAM;
   1497             }
   1498             filter_create.filter.data.b[idx] = filter->m_raw_data[idx];
   1499             filter_create.filter.mask.b[idx] = filter->m_raw_mask[idx];
   1500         }
   1501     }
   1502 
   1503     /* Dump raw data for debugging purposes */
   1504     for (idx = 0; idx < BYTES2WORDS(oob_size); idx++) {
   1505         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1506                     (BSL_META_U(unit,
   1507                                 "OOB[%d]: 0x%08x [0x%08x]\n"), idx,
   1508                      filter_create.filter.data.w[idx],
   1509                      filter_create.filter.mask.w[idx]));
   1510     }
   1511     for (idx = 0; idx < filter_create.filter.pkt_data_size; idx++) {
   1512         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1513                     (BSL_META_U(unit,
   1514                                 "PKT[%d]: 0x%02x [0x%02x]\n"),
   1515                      idx + filter_create.filter.pkt_data_offset,
   1516                      filter_create.filter.data.b[idx + oob_size],
   1517                      filter_create.filter.mask.b[idx + oob_size]));
   1518     }
   1519 
   1520     rv = soc_knet_cmd_req((kcom_msg_t *)&filter_create,
   1521                           sizeof(filter_create), sizeof(filter_create));
   1522 
   1523     if (BCM_SUCCESS(rv)) {
   1524         /* ID is assigned by kernel */
   1525         filter->id = filter_create.filter.id;
   1526     }
   1527     return rv;
   1528 #endif
   1529 }
   1530 
   1531 /*
   1532  * Function:
   1533  *      bcm_esw_knet_filter_destroy
   1534  * Purpose:
   1535  *      Destroy a kernel packet filter.
   1536  * Parameters:
   1537  *      unit - (IN) Unit number.
   1538  *      filter_id - (IN) Rx packet filter ID
   1539  * Returns:
   1540  *      BCM_E_xxx
   1541  * Notes:
   1542  */
   1543 int 
   1544 bcm_esw_knet_filter_destroy(int unit, int filter_id)
   1545 {
   1546 #ifndef INCLUDE_KNET
   1547     return BCM_E_UNAVAIL;
   1548 #else
   1549     kcom_msg_filter_destroy_t filter_destroy;
   1550 
   1551     sal_memset(&filter_destroy, 0, sizeof(filter_destroy));
   1552     filter_destroy.hdr.opcode = KCOM_M_FILTER_DESTROY;
   1553     filter_destroy.hdr.unit = unit;
   1554 
   1555     filter_destroy.hdr.id = filter_id;
   1556 
   1557     return soc_knet_cmd_req((kcom_msg_t *)&filter_destroy,
   1558                             sizeof(filter_destroy), sizeof(filter_destroy));
   1559 #endif
   1560 }
   1561 
   1562 /*
   1563  * Function:
   1564  *      bcm_esw_knet_filter_get
   1565  * Purpose:
   1566  *      Get a kernel packet filter configuration.
   1567  * Parameters:
   1568  *      unit - (IN) Unit number.
   1569  *      filter_id - (IN) Rx packet filter ID
   1570  *      filter - (OUT) Rx packet filter configuration
   1571  * Returns:
   1572  *      BCM_E_xxx
   1573  * Notes:
   1574  */
   1575 int 
   1576 bcm_esw_knet_filter_get(int unit, int filter_id, bcm_knet_filter_t *filter)
   1577 {
   1578 #ifndef INCLUDE_KNET
   1579     return BCM_E_UNAVAIL;
   1580 #else
   1581     int rv;
   1582     kcom_msg_filter_get_t filter_get;
   1583     dcb_t *dcb_data;
   1584     dcb_t *dcb_mask;
   1585     soc_rx_reasons_t no_reasons;
   1586     soc_rx_reasons_t mask_reasons;
   1587     int idx, rdx, fdx;
   1588 
   1589     sal_memset(&filter_get, 0, sizeof(filter_get));
   1590     filter_get.hdr.opcode = KCOM_M_FILTER_GET;
   1591     filter_get.hdr.unit = unit;
   1592 
   1593     filter_get.hdr.id = filter_id;
   1594 
   1595     rv = soc_knet_cmd_req((kcom_msg_t *)&filter_get,
   1596                           sizeof(filter_get.hdr), sizeof(filter_get));
   1597 
   1598     if (BCM_SUCCESS(rv)) {
   1599         bcm_knet_filter_t_init(filter);
   1600 
   1601         switch (filter_get.filter.type) {
   1602         case KCOM_FILTER_T_RX_PKT:
   1603             filter->type = BCM_KNET_DEST_T_BCM_RX_API;
   1604             break;
   1605         default:
   1606             /* Unknown type */
   1607             break;
   1608         }
   1609 
   1610         switch (filter_get.filter.dest_type) {
   1611         case KCOM_DEST_T_NETIF:
   1612             filter->dest_type = BCM_KNET_DEST_T_NETIF;
   1613             break;
   1614         case KCOM_DEST_T_API:
   1615             filter->dest_type = BCM_KNET_DEST_T_BCM_RX_API;
   1616             break;
   1617         case KCOM_DEST_T_CB:
   1618             filter->dest_type = BCM_KNET_DEST_T_CALLBACK;
   1619             break;
   1620         default:
   1621             filter->dest_type = BCM_KNET_DEST_T_NULL;
   1622             break;
   1623         }
   1624 
   1625         switch (filter_get.filter.mirror_type) {
   1626         case KCOM_DEST_T_NETIF:
   1627             filter->mirror_type = BCM_KNET_DEST_T_NETIF;
   1628             break;
   1629         case KCOM_DEST_T_API:
   1630             filter->mirror_type = BCM_KNET_DEST_T_BCM_RX_API;
   1631             break;
   1632         case KCOM_DEST_T_CB:
   1633             /* Should never get here, but keep for completeness */
   1634             filter->mirror_type = BCM_KNET_DEST_T_CALLBACK;
   1635             break;
   1636         default:
   1637             filter->mirror_type = BCM_KNET_DEST_T_NULL;
   1638             break;
   1639         }
   1640 
   1641         if (filter_get.filter.flags & KCOM_FILTER_F_STRIP_TAG) {
   1642             filter->flags |= BCM_KNET_FILTER_F_STRIP_TAG;
   1643         }
   1644 
   1645         filter->dest_id = filter_get.filter.dest_id;
   1646         filter->dest_proto = filter_get.filter.dest_proto;
   1647         filter->mirror_id = filter_get.filter.mirror_id;
   1648         filter->mirror_proto = filter_get.filter.mirror_proto;
   1649 
   1650         filter->id = filter_get.filter.id;
   1651         filter->priority = filter_get.filter.priority;
   1652         sal_memcpy(filter->desc, filter_get.filter.desc,
   1653                    sizeof(filter->desc) - 1);
   1654 
   1655         dcb_data = (dcb_t *)&filter_get.filter.data;
   1656         dcb_mask = (dcb_t *)&filter_get.filter.mask;
   1657 
   1658         sal_memset(&no_reasons, 0, sizeof(no_reasons));
   1659         SOC_DCB_RX_REASONS_GET(unit, dcb_mask, &mask_reasons);
   1660         if (sal_memcmp(&mask_reasons, &no_reasons, sizeof(mask_reasons))) {
   1661             filter->match_flags |= BCM_KNET_FILTER_M_REASON;
   1662             SOC_DCB_RX_REASONS_GET(unit, dcb_data, &filter->m_reason);
   1663         }
   1664         if (SOC_DCB_RX_OUTER_VID_GET(unit, dcb_mask)) {
   1665             filter->match_flags |= BCM_KNET_FILTER_M_VLAN;
   1666             filter->m_vlan = SOC_DCB_RX_OUTER_VID_GET(unit, dcb_data);
   1667         }
   1668         if (SOC_DCB_RX_INGPORT_GET(unit, dcb_mask)) {
   1669             filter->match_flags |= BCM_KNET_FILTER_M_INGPORT;
   1670             filter->m_ingport = SOC_DCB_RX_INGPORT_GET(unit, dcb_data);
   1671         }
   1672         if (SOC_DCB_RX_SRCPORT_GET(unit, dcb_mask)) {
   1673             filter->match_flags |= BCM_KNET_FILTER_M_SRC_MODPORT;
   1674             filter->m_src_modport = SOC_DCB_RX_SRCPORT_GET(unit, dcb_data);
   1675         }
   1676         if (SOC_DCB_RX_SRCMOD_GET(unit, dcb_mask)) {
   1677             filter->match_flags |= BCM_KNET_FILTER_M_SRC_MODID;
   1678             filter->m_src_modid = SOC_DCB_RX_SRCMOD_GET(unit, dcb_data);
   1679         }
   1680         if (SOC_DCB_RX_MATCHRULE_GET(unit, dcb_mask)) {
   1681             filter->match_flags |= BCM_KNET_FILTER_M_FP_RULE;
   1682             filter->m_fp_rule = SOC_DCB_RX_MATCHRULE_GET(unit, dcb_data);
   1683         }
   1684         if (SOC_DCB_RX_ERROR_GET(unit,dcb_mask)) {
   1685             filter->match_flags |= BCM_KNET_FILTER_M_ERROR;
   1686         }
   1687         if (filter_get.filter.pkt_data_size) {
   1688             filter->match_flags |= BCM_KNET_FILTER_M_RAW;
   1689             rdx = filter_get.filter.pkt_data_offset;
   1690             fdx = filter_get.filter.oob_data_size;
   1691             for (idx = 0; idx < filter_get.filter.pkt_data_size; idx++) {
   1692                 filter->m_raw_data[rdx] = filter_get.filter.data.b[fdx];
   1693                 filter->m_raw_mask[rdx] = filter_get.filter.mask.b[fdx];
   1694                 rdx++;
   1695                 fdx++;
   1696             }
   1697             filter->raw_size = rdx;
   1698         } else {
   1699             /*
   1700              * If a filter contains no raw packet data then we copy the OOB
   1701              * data into the raw data buffer while raw_size remains zero.
   1702              * Note that this functionality is intended for debugging only.
   1703              */
   1704             for (idx = 0; idx < SOC_DCB_SIZE(unit); idx++) {
   1705                 filter->m_raw_data[idx] = filter_get.filter.data.b[idx];
   1706                 filter->m_raw_mask[idx] = filter_get.filter.mask.b[idx];
   1707             }
   1708         }
   1709     }
   1710 
   1711     return rv;
   1712 #endif
   1713 }
   1714 
   1715 /*
   1716  * Function:
   1717  *      bcm_esw_knet_filter_traverse
   1718  * Purpose:
   1719  *      Traverse kernel packet filter objects
   1720  * Parameters:
   1721  *      unit - (IN) Unit number.
   1722  *      trav_fn - (IN) User provided call back function
   1723  *      user_data - (IN) User provided data used as input param for callback function
   1724  * Returns:
   1725  *      BCM_E_xxx
   1726  * Notes:
   1727  */
   1728 int 
   1729 bcm_esw_knet_filter_traverse(int unit, bcm_knet_filter_traverse_cb trav_fn, 
   1730                              void *user_data)
   1731 {
   1732 #ifndef INCLUDE_KNET
   1733     return BCM_E_UNAVAIL;
   1734 #else
   1735     int rv, idx;
   1736     bcm_knet_filter_t filter;
   1737     kcom_msg_filter_list_t filter_list;
   1738 
   1739     if (trav_fn == NULL) {
   1740         return BCM_E_PARAM;
   1741     }
   1742 
   1743     sal_memset(&filter_list, 0, sizeof(filter_list));
   1744     filter_list.hdr.opcode = KCOM_M_FILTER_LIST;
   1745     filter_list.hdr.unit = unit;
   1746 
   1747     rv = soc_knet_cmd_req((kcom_msg_t *)&filter_list,
   1748                           sizeof(filter_list.hdr), sizeof(filter_list));
   1749 
   1750     if (BCM_SUCCESS(rv)) {
   1751         for (idx = 0; idx < filter_list.fcnt; idx++) {
   1752             rv = bcm_esw_knet_filter_get(unit, filter_list.id[idx], &filter);
   1753             if (BCM_SUCCESS(rv)) {
   1754                 rv = trav_fn(unit, &filter, user_data);
   1755             }
   1756             if (BCM_FAILURE(rv)) {
   1757                 break;
   1758             }
   1759         }
   1760     }
   1761 
   1762     return rv;
   1763 #endif
   1764 }