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

txbeacon.c (17200B)


      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  * This program is the proprietary software of Broadcom Corporation
      9  * and/or its licensors, and may only be used, duplicated, modified
     10  * or distributed pursuant to the terms and conditions of a separate,
     11  * written license agreement executed between you and Broadcom
     12  * (an "Authorized License").  Except as set forth in an Authorized
     13  * License, Broadcom grants no license (express or implied), right
     14  * to use, or waiver of any kind with respect to the Software, and
     15  * Broadcom expressly reserves all rights in and to the Software and
     16  * all intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED
     17  * LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY,
     18  * AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE
     19  * OF THE SOFTWARE. 
     20  *
     21  * Except as expressly set forth in the Authorized License,
     22  *
     23  * 1. This program, including its structure, sequence and organization,
     24  * constitutes the valuable trade secrets of Broadcom, and you shall use
     25  * all reasonable efforts to protect the confidentiality thereof, and
     26  * to use this information only in connection with your use of Broadcom
     27  * integrated circuit products.
     28  *
     29  * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
     30  * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
     31  * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
     32  * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY
     33  * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
     34  * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
     35  * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
     36  * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
     37  * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
     38  * 
     39  * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
     40  * OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
     41  * INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
     42  * RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
     43  * BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
     44  * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
     45  * ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL
     46  * APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
     47  * REMEDY.
     48  */
     49 
     50 #include <soc/cm.h>
     51 #include <soc/debug.h>
     52 #include <soc/drv.h>
     53 #include <soc/uc_msg.h>
     54 #include <soc/shared/mos_msg_common.h>
     55 #include <shared/bsl.h>
     56 #include <bcm_int/control.h>
     57 #include <bcm/error.h>
     58 
     59 #include <bcm/txbeacon.h>
     60 
     61 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
     62 
     63 /* Version of the SDK-side app code */
     64 #define TXBEACON_SDK_VERSION    0x01000000
     65 #define TXBEACON_UK_MIN_VERSION 0x01000000
     66 
     67 
     68 /*
     69  * Function:
     70  *      _bcm_esw_txbeacon_hton
     71  * Purpose:
     72  *      Internal routine to convert txbeacon area endianness
     73  * Parameters:
     74  *      host - pointer to host struct
     75  *      net - pointer to net (uC) struct
     76  * Returns:
     77  *      nothing
     78  * Notes:
     79  */
     80 
     81 void
     82 _bcm_esw_txbeacon_hton(bcm_txbeacon_t *host, bcm_txbeacon_t *net)
     83 {
     84     net->flags = soc_htonl(host->flags);
     85     net->len = soc_htons(host->len);
     86     net->maxlen = soc_htons(host->maxlen);
     87     net->pkt_id = soc_htonl(host->pkt_id);
     88     net->port = soc_htons(host->port);
     89     net->interval = soc_htons(host->interval);
     90     net->count = soc_htons(host->count);
     91 }
     92 
     93 /*
     94  * Function:
     95  *      _bcm_esw_txbeacon_ntoh
     96  * Purpose:
     97  *      Internal routine to convert txbeacon area endianness
     98  * Parameters:
     99  *      host - pointer to host struct
    100  *      net - pointer to net (uC) struct
    101  * Returns:
    102  *      nothing
    103  * Notes:
    104  */
    105 
    106 void
    107 _bcm_esw_txbeacon_ntoh(bcm_txbeacon_t *net, bcm_txbeacon_t *host)
    108 {
    109     host->flags = soc_ntohl(net->flags);
    110     host->len = soc_ntohs(net->len);
    111     host->maxlen = soc_ntohs(net->maxlen);
    112     host->pkt_id = soc_ntohl(net->pkt_id);
    113     host->port = soc_ntohs(net->port);
    114     host->interval = soc_ntohs(net->interval);
    115     host->count = soc_ntohs(net->count);
    116 }
    117 #endif
    118 
    119 /*
    120  * Function:
    121  *      bcm_esw_txbeacon_init
    122  * Purpose:
    123  *      Init routine for TX beacon
    124  * Parameters:
    125  *      unit - for what unit is this being set up
    126  *      uC - Microcontroller to handle TX beacons
    127  * Returns:
    128  *      BCM_E_XXX
    129  * Notes:
    130  */
    131 
    132 int
    133 bcm_esw_txbeacon_init(int unit, int uC)
    134 {
    135 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    136     soc_control_t       *soc = SOC_CONTROL(unit);
    137 
    138     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    139          (!soc_feature(unit, soc_feature_cmicx)) ) {
    140         return (BCM_E_UNAVAIL);
    141     } 
    142 
    143     soc->txbeacon_msg_timeout =
    144         soc_property_get(unit, spn_UC_MSG_TX_BEACON_TIMEOUT, 200000000);
    145 
    146     /* Send the init msg to the uC and wait for an "APPL ready"
    147        message */
    148     if (soc_cmic_uc_appl_init(unit, uC, MOS_MSG_CLASS_PKT_BCN,
    149                               soc->txbeacon_msg_timeout,
    150                               TXBEACON_SDK_VERSION,
    151                               TXBEACON_UK_MIN_VERSION,
    152                               NULL, NULL) != SOC_E_NONE) {
    153         return (BCM_E_UNAVAIL);
    154     }
    155 
    156     soc->txbeacon_uC = uC;
    157     soc->txbeacon_init = 1;
    158 
    159     LOG_CLI((BSL_META_U(unit,
    160                         "txbeacon ready\n")));
    161     
    162     return (BCM_E_NONE);
    163 
    164 #else
    165     return (BCM_E_UNAVAIL);
    166 
    167 #endif 
    168 }
    169 
    170 /*
    171  * Function:
    172  *      bcm_esw_txbeacon_pkt_setup
    173  * Purpose:
    174  *      Add a packet for TX beacon
    175  * Parameters:
    176  *      unit - for what unit is this being set up
    177  *      txbeacon - pkt beacon info
    178  * Returns:
    179  *      BCM_E_XXX
    180  * Notes:
    181  */
    182 
    183 int
    184 bcm_esw_txbeacon_pkt_setup(
    185     int unit,
    186     bcm_txbeacon_t *txbeacon)
    187 {
    188 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    189 
    190     soc_control_t       *soc = SOC_CONTROL(unit);
    191     soc_info_t          *si = &SOC_INFO(unit);
    192     mos_msg_data_t      send, rcv;
    193     int rc = BCM_E_NONE;
    194     char *dma_mem;
    195 
    196     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    197          (!soc_feature(unit, soc_feature_cmicx)) ) {
    198         return (BCM_E_UNAVAIL);
    199     } 
    200 
    201     if (soc->txbeacon_init == 0) {
    202         return (BCM_E_INIT);
    203     }
    204 
    205     if (txbeacon->port >= SOC_MAX_NUM_PORTS) {
    206         return (BCM_E_PARAM);
    207     } 
    208 
    209     /* Make a dma-able copy */
    210     dma_mem = soc_cm_salloc(unit,
    211                             MOS_MSG_DMA_LEN(sizeof(bcm_txbeacon_t) +
    212                                             txbeacon->len),
    213                             "txbeacon copy");
    214     if (dma_mem == NULL) {
    215         return (BCM_E_MEMORY);
    216     }
    217     _bcm_esw_txbeacon_hton(txbeacon, (bcm_txbeacon_t *) dma_mem);
    218     sal_memcpy(dma_mem + sizeof(bcm_txbeacon_t), txbeacon->pkt_data, txbeacon->len);
    219     soc_cm_sflush(unit, dma_mem, sizeof(bcm_txbeacon_t) + txbeacon->len);
    220 
    221     send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    222     send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_CONFIG;
    223     /* Cheat and use the len for the queue num */
    224     send.s.len = soc_htons(si->port_cosq_base[txbeacon->port]);
    225     send.s.data = soc_htonl(soc_cm_l2p(unit, dma_mem));
    226 
    227     rcv.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    228 
    229     if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC,
    230                                       &send, &rcv,
    231                                       soc->txbeacon_msg_timeout) !=
    232          SOC_E_NONE) ||
    233         (rcv.s.data != 0)) {
    234         rc = BCM_E_FAIL;
    235     }
    236 
    237     soc_cm_sfree(unit, dma_mem);
    238 
    239     return(rc);
    240 
    241 #else
    242     return (BCM_E_UNAVAIL);
    243 
    244 #endif 
    245 }
    246 
    247 /*
    248  * Function:
    249  *      bcm_esw_txbeacon_destroy
    250  * Purpose:
    251  *      Remove this packet from the list
    252  * Parameters:
    253  *      unit - for what unit is this being set up
    254  *      pkt_id - ID of packet to destroy
    255  * Returns:
    256  *      BCM_E_XXX
    257  * Notes:
    258  */
    259 
    260 int bcm_esw_txbeacon_destroy(
    261     int unit,
    262     bcm_txbeacon_pkt_id_t pkt_id) {
    263 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    264 
    265     soc_control_t       *soc = SOC_CONTROL(unit);
    266     mos_msg_data_t      send, rcv;
    267 
    268     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    269          (!soc_feature(unit, soc_feature_cmicx)) ) {
    270         return (BCM_E_UNAVAIL);
    271     } 
    272 
    273     if (soc->txbeacon_init == 0) {
    274         return (BCM_E_INIT);
    275     } 
    276 
    277     send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    278     send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_DESTROY;
    279     send.s.len = soc_htons(4);
    280     send.s.data = soc_htonl(pkt_id);
    281 
    282     if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    283                                       soc->txbeacon_msg_timeout) != SOC_E_NONE) ||
    284         (rcv.s.data != 0)) {
    285         return(BCM_E_FAIL);
    286     }
    287 
    288     return(BCM_E_NONE);
    289 
    290 #else
    291     return (BCM_E_UNAVAIL);
    292 
    293 #endif 
    294 }
    295 
    296 /*
    297  * Function:
    298  *      bcm_esw_txbeacon_pkt_get
    299  * Purpose:
    300  *      Lookup packet beacon info structure
    301  * Parameters:
    302  *      unit - for what unit is this being set up
    303  *      txbeacon - pkt beacon info.  Should have the pkt_id, pkt_ptr,
    304  *                  and maxlen fields set.
    305  * Returns:
    306  *      BCM_E_XXX
    307  * Notes:
    308  *      Find the packet with the minimum packt ID which is greater
    309  *      than or equal to the pkt_id in the txbeacon into.  This can
    310  *      be used in a loop to recover all of the packets by starting
    311  *      with zero and then incrementing the returned pkt_id until a
    312  *      zero pkt_id is returned.
    313  *
    314  *      The txbeacon info must be filled in with the pkt_id, and a
    315  *      pkt_pointer.  Up to maxlen bytes are copied into the
    316  *      pkt_pointer.
    317  */
    318 
    319 int bcm_esw_txbeacon_pkt_get(
    320     int unit,
    321     bcm_txbeacon_t *txbeacon) {
    322 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    323 
    324     uint8               *dma_mem = NULL;
    325     soc_control_t       *soc = SOC_CONTROL(unit);
    326     mos_msg_data_t      send, rcv;
    327     uint8 *             pkt_data = txbeacon->pkt_data;
    328 
    329     int rc = BCM_E_NONE;
    330     int maxlen = txbeacon->maxlen;
    331     int size = 0;
    332 
    333     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    334          (!soc_feature(unit, soc_feature_cmicx)) ) {
    335         return (BCM_E_UNAVAIL);
    336     } 
    337 
    338     if (soc->txbeacon_init == 0) {
    339         return (BCM_E_INIT);
    340     }
    341 
    342     /* Get a dma-able region and copy the pkt data in*/
    343     size = MOS_MSG_DMA_LEN(sizeof(bcm_txbeacon_t) + maxlen);
    344     dma_mem = soc_cm_salloc(unit, size, "dma");
    345     if (dma_mem == NULL) {
    346         return (BCM_E_MEMORY);
    347     }
    348 
    349     _bcm_esw_txbeacon_hton(txbeacon, (bcm_txbeacon_t *) dma_mem);
    350     soc_cm_sflush(unit, dma_mem, sizeof(bcm_txbeacon_t));
    351     soc_cm_sinval(unit, dma_mem, size);
    352 
    353     send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    354     send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_GET;
    355     send.s.len = soc_htons(sizeof(bcm_txbeacon_t));
    356     send.s.data = soc_htonl(soc_cm_l2p(unit, dma_mem));
    357 
    358     rcv.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    359 
    360     rc = soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    361                                       soc->txbeacon_msg_timeout);
    362     if (rc == SOC_E_NONE) {
    363         /* Copy the data back out to the user area */
    364         _bcm_esw_txbeacon_ntoh((bcm_txbeacon_t *) dma_mem, txbeacon);
    365         txbeacon->pkt_data = pkt_data;          /* Restore data ptr */
    366         sal_memcpy(pkt_data, dma_mem + sizeof(bcm_txbeacon_t),
    367                    (maxlen > txbeacon->len) ? txbeacon->len : maxlen);
    368     } 
    369 
    370     soc_cm_sfree(unit, dma_mem);
    371     
    372     return(rc);
    373 
    374 #else
    375     return (BCM_E_UNAVAIL);
    376 
    377 #endif 
    378 }
    379 
    380 /*
    381  * Function:
    382  *      bcm_esw_txbeacon_start
    383  * Purpose:
    384  *      Start beacon for this packet or all
    385  * Parameters:
    386  *      unit - for what unit is this being set up
    387  *      pkt_id - ID of packet to start or zero for all
    388  * Returns:
    389  *      BCM_E_XXX
    390  * Notes:
    391  */
    392 
    393 int bcm_esw_txbeacon_start(
    394      int unit,
    395      bcm_txbeacon_pkt_id_t pkt_id) {
    396 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    397 
    398     mos_msg_data_t      send, rcv;
    399 
    400     soc_control_t       *soc = SOC_CONTROL(unit);
    401     
    402     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    403          (!soc_feature(unit, soc_feature_cmicx)) ) {
    404         return (BCM_E_UNAVAIL);
    405     } 
    406 
    407     if (soc->txbeacon_init == 0) {
    408         return BCM_E_INIT;
    409     } 
    410 
    411     send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    412     send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_START;
    413     send.s.len = soc_htons(4);
    414     send.s.data = soc_htonl(pkt_id);
    415 
    416     rcv.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    417 
    418     if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    419                                       soc->txbeacon_msg_timeout) != SOC_E_NONE) ||
    420         (rcv.s.data != 0)) {
    421         return(BCM_E_FAIL);
    422     }
    423 
    424     return(BCM_E_NONE);
    425 
    426 #else
    427     return (BCM_E_UNAVAIL);
    428 
    429 #endif 
    430 }
    431 
    432 /*
    433  * Function:
    434  *      bcm_esw_txbeacon_stop
    435  * Purpose:
    436  *      Stop the packet beacon
    437  * Parameters:
    438  *      unit - for what unit is this being set up
    439  *      pkt_id - ID of packet to stop or zero for all
    440  * Returns:
    441  *      BCM_E_XXX
    442  * Notes:
    443  */
    444 
    445 int bcm_esw_txbeacon_stop(
    446     int unit,
    447     bcm_txbeacon_pkt_id_t pkt_id) {
    448 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    449 
    450     mos_msg_data_t      send, rcv;
    451 
    452     soc_control_t       *soc = SOC_CONTROL(unit);
    453     
    454     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    455          (!soc_feature(unit, soc_feature_cmicx)) ) {
    456         return (BCM_E_UNAVAIL);
    457     } 
    458 
    459     if (soc->txbeacon_init == 0) {
    460         return BCM_E_INIT;
    461     } 
    462 
    463     send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    464     send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_STOP;
    465     send.s.len = soc_htons(4);
    466     send.s.data = soc_htonl(pkt_id);
    467 
    468     rcv.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    469 
    470     if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    471                                       soc->txbeacon_msg_timeout) != SOC_E_NONE) ||
    472         (rcv.s.data != 0)) {
    473         return(BCM_E_FAIL);
    474     }
    475 
    476     return(BCM_E_NONE);
    477 
    478 #else
    479     return (BCM_E_UNAVAIL);
    480 
    481 #endif 
    482 }
    483 
    484 /*
    485  * Function:
    486  *      bcm_esw_txbeacon_traverse
    487  * Purpose:
    488  *      Traverse the tx beacon packets
    489  * Parameters:
    490  *      unit - for what unit is this being set up
    491  *      txbeacon_traverse_cb
    492  * Returns:
    493  *      BCM_E_XXX
    494  * Notes:
    495  */
    496 
    497 int
    498 bcm_esw_txbeacon_traverse(
    499     int unit,
    500     bcm_txbeacon_traverse_cb_t trav_fn,
    501     void *user_data)
    502 {
    503 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    504 
    505     soc_control_t       *soc = SOC_CONTROL(unit);
    506     mos_msg_data_t      send, rcv;
    507     bcm_txbeacon_pkt_id_t pkt_id = 0;
    508     int rc = BCM_E_NONE;
    509     bcm_txbeacon_t *txb;
    510     int size;
    511     bcm_txbeacon_t *pkt;
    512 
    513     if ( (!soc_feature(unit, soc_feature_cmicm)) &&
    514          (!soc_feature(unit, soc_feature_cmicx)) ) {
    515         return (BCM_E_UNAVAIL);
    516     } 
    517 
    518     if (soc->txbeacon_init == 0) {
    519         return (BCM_E_INIT);
    520     }
    521 
    522     /* Allocate a dma-able area just big enough for the beacon info */
    523     txb = soc_cm_salloc(unit, MOS_MSG_DMA_LEN(sizeof(bcm_txbeacon_t)),
    524                         "traverse info");
    525     if (txb == NULL) {
    526         return(BCM_E_MEMORY);
    527     }
    528     
    529     while (1) {
    530 
    531         /* Set up the info-only area */
    532         txb->pkt_id = soc_htonl(pkt_id);
    533         txb->maxlen = 0;
    534         txb->pkt_data = NULL;
    535         soc_cm_sflush(unit, txb, sizeof(bcm_txbeacon_t));
    536         soc_cm_sinval(unit, txb, sizeof(bcm_txbeacon_t));
    537         
    538         send.s.mclass = MOS_MSG_CLASS_PKT_BCN;
    539         send.s.subclass = MOS_MSG_SUBCLASS_PKT_BCN_GET;
    540         send.s.len = soc_htons(sizeof(bcm_txbeacon_t));
    541         send.s.data = soc_htonl(soc_cm_l2p(unit, txb));
    542     
    543         if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    544                                           soc->txbeacon_msg_timeout) != SOC_E_NONE) ||
    545             (rcv.s.data != 0)) {
    546             break;
    547         } 
    548 
    549         /* Copy actual packet ID out */
    550         pkt_id = soc_htonl(txb->pkt_id);
    551 
    552         /* Allocate an area big enough for everything */
    553         size = MOS_MSG_DMA_LEN(sizeof(bcm_txbeacon_t) + soc_htons(txb->maxlen));
    554         pkt = soc_cm_salloc(unit, size, "traverse packet");
    555         if (pkt == NULL) {
    556             rc = BCM_E_MEMORY;
    557             break;
    558         }
    559 
    560 
    561         pkt->pkt_id = soc_htonl(pkt_id);
    562         pkt->maxlen = soc_htons(txb->maxlen);
    563         pkt->pkt_data = INT_TO_PTR(soc_cm_l2p(unit, ((char *) pkt) + sizeof(bcm_txbeacon_t)));
    564         soc_cm_sflush(unit, pkt, size);
    565         soc_cm_sinval(unit, pkt, size);
    566 
    567 
    568         /* Resend the request - this time with the len big enough for
    569            the whole packet */
    570         send.s.len = soc_htons(sizeof(bcm_txbeacon_t));
    571         send.s.data = soc_htonl(soc_cm_l2p(unit, pkt));
    572     
    573         if ((soc_cmic_uc_msg_send_receive(unit, soc->txbeacon_uC, &send, &rcv, 
    574                                           soc->txbeacon_msg_timeout) != SOC_E_NONE) ||
    575             (rcv.s.data != 0)) {
    576             rc = BCM_E_FAIL;
    577             soc_cm_sfree(unit, pkt);
    578             break;
    579         }
    580 
    581         /* Set the packet point to the virtual addr and call the loopback function */
    582         _bcm_esw_txbeacon_ntoh(pkt, pkt);
    583         pkt->pkt_data =  (((uint8 *) pkt) + sizeof(bcm_txbeacon_t));
    584 
    585         trav_fn(unit, pkt, user_data);
    586         
    587         soc_cm_sfree(unit, pkt);                /* Free the big one */
    588 
    589         pkt_id++;
    590     }
    591 
    592     soc_cm_sfree(unit, txb);
    593 
    594     return rc;
    595 
    596 #else
    597     return (BCM_E_UNAVAIL);
    598 
    599 #endif 
    600 }
    601