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 (10732B)


      1 /*  Feature  : KNET
      2  *
      3  *  Usage    : BCM.0> cint knet.c
      4  *
      5  *  config   : knet_config.bcm
      6  *
      7  *  Log file : knet_log.txt
      8  *
      9  *  Test Topology :
     10  *
     11  *                   +------------------------------+
     12  *                   |                              |
     13  *                   |                              |
     14  *                   |                              |
     15  *                   |                              |
     16  *  +----------------+          SWITCH              +-----------------+
     17  *                   |                              |
     18  *                   |                              |
     19  *                   |                              |
     20  *                   |                              |
     21  *                   |                              |
     22  *                   +------------------------------+
     23  *
     24  *
     25  *  Summary:
     26  *  ========
     27  *    This CINT script demonstrate how to send and receive packets over KNET interface
     28  *    This exampls shows how application can create KNET interface 
     29  *    and send/receive packets over it.
     30  *    
     31  *    Prerequistes:
     32  *    =============
     33  *      a) Build SDK with KNET feature enabled
     34  *      b) Build $SDK/src/examples/xgs/tomahawk3/knet/knet_tx.c and knet_rx.c 
     35  *         source files for customer target CPU
     36  *      c) Insert knet kernel module before launching SDK.
     37  *     
     38  *    Detailed steps done in the CINT script:
     39  *    =====================================================
     40  *    1) Step1 - Test Setup (Done in test_setup())
     41  *    ============================================
     42  *      a) Enable siwtch control "ArpReplyToCpu" and "ArpRequestCpu"
     43  *      b) Enable BCM RX module and register Rx Callback
     44  *      c) Add IFP rules to copy protocol and data packets to CPU
     45  * 
     46  *    2) Step2 - Configuration (Done in knet_setup())
     47  *    ===============================================
     48  *      a) Create Knet interface of type BCM_KNET_NETIF_T_TX_CPU_INGRESS
     49  *      b) Create Knet filter to divert packets to Knet interface
     50  *        
     51  *    3) Step3 - Verification (Done in verify())
     52  *    ===========================================
     53  *      a) Provided steps to user for sending and receiving packets 
     54  *         through knet interface  
     55  *      b) Expected Result:
     56  *         ================
     57  *         knet_tx executable will send 5 packets over knet interface
     58  *         knet_rx executable will receive 5 packets over knet interface and display
     59  */
     60  
     61 cint_reset();
     62 
     63 bcm_error_t
     64 knet_setup(int unit)
     65 {
     66     bcm_error_t rv = BCM_E_NONE; 
     67     const bcm_mac_t local_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE };
     68     const char *device_name = "virt-intf0";
     69 
     70     printf("Create a KNET interface to handle protocol and local station packets\n");
     71     rv = create_knet_interface(unit, device_name, local_mac);
     72     if(BCM_FAILURE(rv)) {
     73         printf("\nError in create_knet_interface() : %s\n", bcm_errmsg(rv));
     74         return rv;
     75     }
     76 
     77     printf("DONE; don't forget \"ifconfig virt-intf 192.168.2.254 netmask 255.255.255.0 up\"\n");
     78     return rv;
     79 }
     80 
     81 /*
     82  * Create a KNET interface with two filters to direct protocol and filter match
     83  * IP packets to it.
     84  */
     85 bcm_error_t
     86 create_knet_interface(int unit, char *device_name, bcm_mac_t local_mac)
     87 {
     88     bcm_error_t rv = BCM_E_NONE;
     89     bcm_knet_filter_t filter1;
     90     bcm_knet_filter_t filter2;
     91     bcm_knet_netif_t netif;
     92     int         count;
     93 
     94     /* Send packets through ingress logic */
     95     netif.type = BCM_KNET_NETIF_T_TX_CPU_INGRESS;
     96     netif.vlan = 2;
     97     netif.port = 0 ; 
     98     netif.flags = 0 ; 
     99     sal_strcpy(netif.name, device_name);        /* Set device name */
    100     /* Set MAC address associated with this interface */
    101     netif.mac_addr = local_mac;
    102 
    103     printf("bcm_knet_netif_create\n");
    104     rv = bcm_knet_netif_create(unit, &netif);
    105     if(BCM_FAILURE(rv)) {
    106         printf("\nError in bcm_knet_netif_create() : %s\n", bcm_errmsg(rv));
    107         return rv;
    108     }
    109 
    110     /* Add filter to catch protocol packets */
    111     sal_strcpy(filter1.desc, "Protocol Packets");
    112     filter1.type = BCM_KNET_FILTER_T_RX_PKT;
    113     filter1.flags = BCM_KNET_FILTER_F_STRIP_TAG;
    114     filter1.priority = 50;
    115     /* Send packet to network interface */
    116     filter1.dest_type = BCM_KNET_DEST_T_NETIF;
    117     filter1.dest_id = netif.id;
    118     filter1.match_flags = BCM_KNET_FILTER_M_REASON;
    119     BCM_RX_REASON_SET(&filter1.m_reason, bcmRxReasonProtocol);
    120     printf("bcm_knet_filter_create 1\n");
    121     rv = bcm_knet_filter_create(unit, &filter1);
    122     if(BCM_FAILURE(rv)) {
    123         printf("\nError in bcm_knet_filter_create() : %s\n", bcm_errmsg(rv));
    124         return rv;
    125     }
    126 
    127     /* Add filter to catch nexthop packets */
    128     sal_strcpy(filter2.desc, "Filter Match Packets");
    129     filter2.type = BCM_KNET_FILTER_T_RX_PKT;
    130     filter2.flags = BCM_KNET_FILTER_F_STRIP_TAG;
    131     filter2.priority = 55;
    132     filter2.dest_type = BCM_KNET_DEST_T_NETIF;
    133     filter2.dest_id = netif.id;
    134     filter2.match_flags = BCM_KNET_FILTER_M_REASON;
    135     BCM_RX_REASON_SET(&filter2.m_reason, bcmRxReasonFilterMatch);
    136     printf("bcm_knet_filter_create 2\n");
    137     rv = bcm_knet_filter_create(unit, &filter2);
    138     if(BCM_FAILURE(rv)) {
    139         printf("\nError in bcm_knet_filter_create() : %s\n", bcm_errmsg(rv));
    140         return rv;
    141     }
    142     return rv;
    143 }
    144 
    145 bcm_error_t
    146 configure_ifp (int unit)
    147 {
    148     bcm_error_t rv = BCM_E_NONE;
    149 
    150     bcm_field_group_config_t group_config;
    151     bcm_field_entry_t eid;
    152     bcm_vlan_t vlan = 2, vlan_mask = 0xfff;
    153     bcm_port_t port = 0, port_mask = 0xffffffff;
    154     int prio;
    155 
    156     /* Enable IFP for CPU port */
    157     rv = bcm_port_control_set(unit, port, bcmPortControlFilterIngress, 1);
    158 
    159     /* FP group configuration and creation */
    160     bcm_field_group_config_t_init(&group_config);
    161 
    162     BCM_FIELD_QSET_INIT(group_config.qset);
    163     BCM_FIELD_QSET_ADD(group_config.qset, bcmFieldQualifyStageIngress);
    164     BCM_FIELD_QSET_ADD(group_config.qset, bcmFieldQualifyInPort);
    165 
    166     group_config.mode = bcmFieldGroupModeAuto;
    167 
    168     rv = bcm_field_group_config_create(unit, &group_config);
    169     if(BCM_FAILURE(rv)) {
    170         printf("\nError in bcm_field_group_config_create() : %s\n", bcm_errmsg(rv));
    171         return rv;
    172     }
    173 
    174     /* FP entry configuration and creation */
    175     rv = bcm_field_entry_create(unit, group_config.group, &eid);
    176     if(BCM_FAILURE(rv)) {
    177         printf("\nError in bcm_field_entry_create() : %s\n", bcm_errmsg(rv));
    178         return rv;
    179     }
    180 
    181     rv = bcm_field_qualify_InPort(unit, eid, port, port_mask);
    182     if(BCM_FAILURE(rv)) {
    183         printf("\nError in bcm_field_qualify_InPort() : %s\n", bcm_errmsg(rv));
    184         return rv;
    185     }
    186 
    187     /* FP entry actions configuration */
    188     rv = bcm_field_action_add(unit, eid, bcmFieldActionDrop, 0, 0);
    189     if(BCM_FAILURE(rv)) {
    190         printf("\nError in bcm_field_action_add() : %s\n", bcm_errmsg(rv));
    191         return rv;
    192     }
    193 
    194     rv = bcm_field_action_add(unit, eid, bcmFieldActionCopyToCpu, 0, 0);
    195     if(BCM_FAILURE(rv)) {
    196         printf("\nError in bcm_field_action_add() : %s\n", bcm_errmsg(rv));
    197         return rv;
    198     }
    199 
    200     /* Installing FP entry to FP TCAM */
    201     rv = bcm_field_entry_install(unit, eid);
    202     if(BCM_FAILURE(rv)) {
    203         printf("\nError in bcm_field_entry_install() : %s\n", bcm_errmsg(rv));
    204         return rv;
    205     }
    206 
    207     return rv;
    208 }
    209 
    210 /* Receive Task Callback
    211  *
    212  * This routine catches bcm_rx packets and prints a simple message.
    213  */
    214 bcm_rx_t
    215 packetWatcher(int unit, bcm_pkt_t * pkt, void *cookie)
    216 {
    217     int        *count = (auto) cookie;
    218 
    219     (*count)++;
    220     printf("Packet: %3d; Size: %d; Src Port: %d; VLAN: %d;", *count,
    221            pkt->pkt_len, pkt->src_port, pkt->vlan);
    222     if (BCM_RX_REASON_IS_NULL(pkt->rx_reasons)) {
    223         printf(" Switched to CPU\n");
    224     } else {
    225         printf(" Sent for Reason\n");
    226     }
    227     return BCM_RX_HANDLED;
    228 }
    229 
    230 int         packet_count = 0;
    231 
    232 bcm_error_t
    233 rx_init(int unit)
    234 {
    235     bcm_error_t rv = BCM_E_NONE;
    236     const int   priority = 101;
    237     const int   flags = BCM_RCO_F_ALL_COS;
    238 
    239     if (!bcm_rx_active(unit)) {
    240         rv = bcm_rx_init(unit);
    241         if(BCM_FAILURE(rv)) {
    242             printf("\nError in bcm_rx_init() : %s\n", bcm_errmsg(rv));
    243             return rv;
    244         }
    245         rv = bcm_rx_start(unit, NULL);
    246         if(BCM_FAILURE(rv)) {
    247             printf("\nError in bcm_rx_start() : %s\n", bcm_errmsg(rv));
    248             return rv;
    249         }
    250 
    251     }
    252 
    253     rv = bcm_rx_register(unit, "Rx PacketWatch", 
    254                          packetWatcher, priority, &packet_count,
    255                          flags);
    256     if(BCM_FAILURE(rv)) {
    257         printf("\nError in bcm_rx_register() : %s\n", bcm_errmsg(rv));
    258         return rv;
    259     }
    260 
    261     return rv;
    262 }
    263 
    264 
    265 bcm_error_t 
    266 test_setup(int unit)
    267 {
    268     bcm_error_t rv = BCM_E_NONE;
    269 
    270     rv = bcm_switch_control_set(unit, bcmSwitchArpReplyToCpu, TRUE);
    271     if(BCM_FAILURE(rv)) {
    272         printf("\nError in bcm_switch_control_set() 
    273                   bcmSwitchArpReplyToCpu : %s.\n",bcm_errmsg(rv));
    274         return rv;
    275     }
    276 
    277     rv = bcm_switch_control_set(unit, bcmSwitchArpRequestToCpu, TRUE);
    278     if(BCM_FAILURE(rv)) {
    279         printf("\nError in bcm_switch_control_set() 
    280                   bcmSwitchArpRequestToCpu : %s.\n",bcm_errmsg(rv));
    281         return rv;
    282     }
    283 
    284     rv = rx_init(unit);
    285     if(BCM_FAILURE(rv)) {
    286         printf("\nError in rx_init(): %s.\n",bcm_errmsg(rv));
    287         return rv;
    288     }
    289 
    290     rv = configure_ifp(unit);
    291     if(BCM_FAILURE(rv)) {
    292         printf("\nError in configure_ifp(): %s.\n",bcm_errmsg(rv));
    293         return rv;
    294     }
    295 
    296     return rv;
    297 }
    298 
    299 void verify(int unit)
    300 {
    301     printf("\nUser has to follow below steps to verify KNET functionality\n");
    302     printf("====================================================================================\n");
    303     printf("1. Go to Linux shell prompt using \"shell\" command from BCM diag shell\n");
    304     printf("2. Configure IP address to knet interface \"ifconfig virt-intf 192.168.2.254 netmask 255.255.255.0 up\" \n");
    305     printf("3. Run knet_rx.exe in backround \"./knet_rx.exe -vv virt-intf0 5 &\"\n");
    306     printf("4. Run knet_tx.exe to send 5 packets \"./knet_tx.exe -vv virt-intf0 5\" \n");
    307     printf("=====================================================================================\n");
    308     printf("Above 4 steps will demonstrate transmit and receive functionality over KNET interface\n");
    309 
    310 }
    311 
    312 bcm_error_t execute()
    313 {
    314     bcm_error_t rv;
    315     int unit =0;
    316     bshell(unit, "config show; a ; version");
    317     if (BCM_FAILURE((rv = test_setup(unit)))) {
    318         printf("test_setup() failed.\n");
    319         return -1;
    320     }
    321 
    322     if (BCM_FAILURE((rv = knet_setup(unit)))) {
    323         printf("KNET Setup Failed\n");
    324         return -1;
    325     }
    326 
    327     verify(unit);
    328     return BCM_E_NONE;
    329 }
    330 
    331 const char *auto_execute = (ARGC == 1) ? ARGV[0] : "YES";
    332 if (!sal_strcmp(auto_execute, "YES")) {
    333   print execute();
    334 }