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

proc_req.c (6296B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        proc_req.c
      8  * Purpose:
      9  * Requires:    
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <unistd.h>
     16 #include <stdlib.h>
     17 
     18 #include <netinet/in.h>
     19 #include <arpa/inet.h>
     20 #include <memory.h>
     21 
     22 #include <sys/types.h>
     23 #include <sys/socket.h>
     24 #include <sys/time.h>
     25 #include <soc/mem.h>
     26 #include <soc/hash.h>
     27 
     28 #include <soc/cmic.h>
     29 #include <soc/drv.h>
     30 #include <soc/debug.h>
     31 #include <soc/schanmsg.h>
     32 #include <sal/appl/io.h>
     33 #include <bde/pli/verinet.h>
     34 
     35 #include "pcid.h"
     36 #include "mem.h"
     37 #include "cmicsim.h"
     38 #include "dma.h"
     39 #include "pli.h"
     40 
     41 STATIC rpc_cmd_t cmd;
     42 /*
     43  * Handles an incoming client request
     44  * We block until the client has something to send us and then 
     45  * we do something over the socket descriptor.
     46  * Returns 1 when a command is processed, 0 on disconnect.
     47  */
     48 
     49 int pcid_process_request(pcid_info_t *pcid_info, int sockfd,
     50                     struct timeval *tmout)
     51 {
     52     char buf[32];
     53     uint32 regval;
     54     int r, unit, finished = 0;
     55 
     56     unit = pcid_info->unit;
     57     r = get_command(sockfd, tmout, &cmd);
     58 
     59     if (r == 0) {
     60     return PR_NO_REQUEST;    /* No request; return to poll later */
     61     }
     62 
     63     if (r < 0) {        /* Error; cause polling loop to exit */
     64     return PR_ERROR;
     65     }
     66 
     67     switch (cmd.opcode) {
     68     /*
     69      * We only handle requests: anything else is a programming
     70      * error. Once we are here, all parameters have been marshalled
     71      * and we simply need to call the correct routine (see pli_cmd.c).
     72      */
     73 
     74     case RPC_SCHAN_REQ:
     75         {       
     76             schan_msg_t msg; 
     77             int i; 
     78             int dw_write, dw_read; 
     79             extern int schan_op(pcid_info_t *pcid_info, int unit, schan_msg_t* data); 
     80 
     81             dw_write = cmd.args[0]; 
     82             dw_read = cmd.args[1]; 
     83         
     84             for(i = 0; i < dw_write; i++) {
     85                 msg.dwords[i] = cmd.args[i+2]; 
     86             }
     87             PCID_MEM_LOCK(pcid_info);
     88             if (!(pcid_info->schan_cb) || 
     89                 (i = (pcid_info->schan_cb)(pcid_info, unit, &msg))) {
     90                 i = schan_op(pcid_info, unit, &msg); 
     91             }
     92             PCID_MEM_UNLOCK(pcid_info);
     93             make_rpc(&cmd, RPC_SCHAN_RESP, RPC_OK, 0); 
     94             cmd.argcount = dw_read+1; 
     95             cmd.args[0] = i; 
     96             for(i = 0; i < dw_read; i++) {
     97                 cmd.args[i+1] = msg.dwords[i]; 
     98             }
     99             if (write_command(sockfd, &cmd) != RPC_OK) {
    100                 pcid_info->opt_rpc_error = 1;
    101             }
    102             break; 
    103         }       
    104 
    105     case RPC_GETREG_REQ: /* PIO read of register */
    106     /* Get a register from our model ... */
    107     /* cmd.args[1] is register type (verinet.h) */
    108 
    109     regval = pli_getreg_service(pcid_info, unit, cmd.args[1], cmd.args[0]);
    110 
    111     /* coverity[secure_coding] */
    112     strcpy(buf, "********");
    113     make_rpc_getreg_resp(&cmd,
    114                  0,
    115                  regval,
    116                  buf);
    117     if (write_command(sockfd, &cmd) != RPC_OK) {
    118         pcid_info->opt_rpc_error = 1;
    119     }
    120 
    121     break;
    122 
    123     case RPC_SETREG_REQ: /* PIO write to register */
    124     /* Set a register on our model... */
    125         /* coverity[stack_use_overflow] */
    126     pli_setreg_service(pcid_info, unit, cmd.args[2], cmd.args[0],
    127                            cmd.args[1]);
    128     make_rpc_setreg_resp(&cmd, cmd.args[1]);
    129     if (write_command(sockfd, &cmd) != RPC_OK) {
    130         pcid_info->opt_rpc_error = 1;
    131     }
    132     break;
    133       
    134     case RPC_IOCTL_REQ: /* Change something inside the model */
    135         if (pcid_info->ioctl) {
    136             pcid_info->ioctl(pcid_info, cmd.args);
    137         }
    138     break;
    139        
    140     case RPC_SHUTDOWN: /* Change something inside the model */
    141         if (pcid_info->ioctl) {
    142             cmd.args[0] = BCM_SIM_DEACTIVATE;
    143             pcid_info->ioctl(pcid_info, cmd.args);
    144         }
    145     break;
    146        
    147     case RPC_REGISTER_CLIENT:
    148     /* Setup port for DMA r/w requests to client and interrupts ...*/
    149     /* Connect to client interrupt and DMA ports and test*/
    150         LOG_CLI((BSL_META_U(unit,
    151                             "Received register client request\n")));
    152     regval = RPC_OK;
    153 
    154     pcid_info->client = register_client(sockfd,
    155                  cmd.args[0],
    156                  cmd.args[1],
    157                  cmd.args[2]);
    158 
    159     if (pcid_info->client == 0) {
    160         finished = 1;
    161         break;
    162     }
    163 
    164     /*
    165      * TEST: Write to DMA address 0 on client.
    166      */
    167     r = dma_writemem(pcid_info->client->dmasock,
    168                   0,
    169                   0xbabeface);
    170       
    171     /*
    172      * TEST: Read from DMA address 0 on client.
    173      */
    174     r = dma_readmem(pcid_info->client->dmasock,0, &regval);
    175       
    176     /* TEST: Result should be the same, if not FAIL! */
    177     if(regval != 0xbabeface){
    178         LOG_CLI((BSL_META_U(unit,
    179                                 "ERROR: regval = 0x%x\n"), regval));
    180         pcid_info->opt_rpc_error = 1;
    181     }
    182     
    183     /*
    184      * TEST: Send an interrupt to the client.
    185      */
    186     r = send_interrupt(pcid_info->client->intsock, 0);
    187         if (r < 0) {
    188             LOG_ERROR(BSL_LS_SOC_COMMON,
    189                       (BSL_META_U(unit,
    190                                   "RPC error: soc_internal_send_int failed. \n")));
    191             pcid_info->opt_rpc_error = 1;
    192         } else {
    193         r = RPC_OK;
    194         }
    195 
    196     /* Send Registration status back ... */
    197     make_rpc_register_resp(&cmd, r);
    198     if (write_command(pcid_info->client->piosock, &cmd) != RPC_OK) {
    199         pcid_info->opt_rpc_error = 1;
    200     }
    201 
    202     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    203                     (BSL_META_U(unit,
    204                                 "Client registration: 0x%x DMA=0x%x, INT=0x%x, PIO=0x%x -OK\n"),
    205                      pcid_info->client->inetaddr,
    206                      pcid_info->client->dmasock,
    207                      pcid_info->client->intsock,
    208                      pcid_info->client->piosock));
    209 
    210     break;
    211 
    212     case RPC_DISCONNECT:
    213     /* First disconnect the interrupt and dma sockets on client */
    214 
    215     unregister_client(pcid_info->client);
    216 
    217     finished = 1;
    218     break;
    219 
    220     default:
    221     /* Unknown opcode */
    222     break;
    223     }
    224 
    225     return (finished ? PR_ALL_DONE : PR_REQUEST_HANDLED);
    226 }