master/fsm_soe.c
changeset 1905 5abe24872083
parent 1882 8ae8cc56d910
child 1921 d9cf40facbc4
equal deleted inserted replaced
1904:2fadf016d9be 1905:5abe24872083
    43 
    43 
    44 /** Mailbox type for SoE.
    44 /** Mailbox type for SoE.
    45  */
    45  */
    46 #define EC_MBOX_TYPE_SOE 0x05
    46 #define EC_MBOX_TYPE_SOE 0x05
    47 
    47 
    48 #define EC_SOE_OPCODE_READ_REQUEST   0x01
    48 /** SoE operations
    49 #define EC_SOE_OPCODE_READ_RESPONSE  0x02
    49  */
    50 #define EC_SOE_OPCODE_WRITE_REQUEST  0x03
    50 enum ec_soe_opcodes {
    51 #define EC_SOE_OPCODE_WRITE_RESPONSE 0x04
    51     OPCODE_READ_REQUEST   = 0x01, /**< Read request. */
    52 
    52     OPCODE_READ_RESPONSE  = 0x02, /**< Read response. */
    53 #define EC_SOE_READ_REQUEST_SIZE   0x04
    53     OPCODE_WRITE_REQUEST  = 0x03, /**< Write request. */
    54 #define EC_SOE_READ_RESPONSE_SIZE  0x04
    54     OPCODE_WRITE_RESPONSE = 0x04  /**< Write response. */
    55 #define EC_SOE_WRITE_REQUEST_SIZE  0x04
    55 };
    56 #define EC_SOE_WRITE_RESPONSE_SIZE 0x04
    56 
    57 
    57 /** Size of all SoE headers.
       
    58  */
       
    59 #define EC_SOE_SIZE 0x04
       
    60 
       
    61 /** SoE response timeout [ms].
       
    62  */
    58 #define EC_SOE_RESPONSE_TIMEOUT 1000
    63 #define EC_SOE_RESPONSE_TIMEOUT 1000
    59 
    64 
    60 /*****************************************************************************/
    65 /*****************************************************************************/
    61 
    66 
    62 void ec_fsm_soe_read_start(ec_fsm_soe_t *);
    67 void ec_fsm_soe_read_start(ec_fsm_soe_t *);
   207         ec_fsm_soe_print_error(fsm);
   212         ec_fsm_soe_print_error(fsm);
   208         return;
   213         return;
   209     }
   214     }
   210 
   215 
   211     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   216     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   212             EC_SOE_READ_REQUEST_SIZE);
   217             EC_SOE_SIZE);
   213     if (IS_ERR(data)) {
   218     if (IS_ERR(data)) {
   214         fsm->state = ec_fsm_soe_error;
   219         fsm->state = ec_fsm_soe_error;
   215         ec_fsm_soe_print_error(fsm);
   220         ec_fsm_soe_print_error(fsm);
   216         return;
   221         return;
   217     }
   222     }
   218 
   223 
   219     EC_WRITE_U8(data, EC_SOE_OPCODE_READ_REQUEST);
   224     EC_WRITE_U8(data, OPCODE_READ_REQUEST);
   220     EC_WRITE_U8(data + 1, 1 << 6); // request value
   225     EC_WRITE_U8(data + 1, 1 << 6); // request value
   221     EC_WRITE_U16(data + 2, request->idn);
   226     EC_WRITE_U16(data + 2, request->idn);
   222 
   227 
   223     if (master->debug_level) {
   228     if (master->debug_level) {
   224         EC_DBG("SCC read request:\n");
   229         EC_DBG("SCC read request:\n");
   225         ec_print_data(data, EC_SOE_READ_REQUEST_SIZE);
   230         ec_print_data(data, EC_SOE_SIZE);
   226     }
   231     }
   227 
   232 
   228     fsm->request->data_size = 0;
   233     fsm->request->data_size = 0;
   229     fsm->request->jiffies_sent = jiffies;
   234     fsm->request->jiffies_sent = jiffies;
   230     fsm->retries = EC_FSM_RETRIES;
   235     fsm->retries = EC_FSM_RETRIES;
   375         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   380         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   376         ec_fsm_soe_print_error(fsm);
   381         ec_fsm_soe_print_error(fsm);
   377         return;
   382         return;
   378     }
   383     }
   379 
   384 
   380     if (rec_size < EC_SOE_READ_RESPONSE_SIZE) {
   385     if (rec_size < EC_SOE_SIZE) {
   381         fsm->state = ec_fsm_soe_error;
   386         fsm->state = ec_fsm_soe_error;
   382         EC_ERR("Received currupted SoE read response"
   387         EC_ERR("Received currupted SoE read response"
   383                 " (%zu bytes)!\n", rec_size);
   388                 " (%zu bytes)!\n", rec_size);
   384         ec_print_data(data, rec_size);
   389         ec_print_data(data, rec_size);
   385         ec_fsm_soe_print_error(fsm);
   390         ec_fsm_soe_print_error(fsm);
   389     header = EC_READ_U8(data);
   394     header = EC_READ_U8(data);
   390     opcode = header & 0x7;
   395     opcode = header & 0x7;
   391     incomplete = (header >> 3) & 1;
   396     incomplete = (header >> 3) & 1;
   392     error_flag = (header >> 4) & 1;
   397     error_flag = (header >> 4) & 1;
   393 
   398 
   394     if (opcode != EC_SOE_OPCODE_READ_RESPONSE) {
   399     if (opcode != OPCODE_READ_RESPONSE) {
   395         EC_ERR("Received no read response (opcode %x).\n", opcode);
   400         EC_ERR("Received no read response (opcode %x).\n", opcode);
   396         ec_print_data(data, rec_size);
   401         ec_print_data(data, rec_size);
   397         ec_fsm_soe_print_error(fsm);
   402         ec_fsm_soe_print_error(fsm);
   398         fsm->state = ec_fsm_soe_error;
   403         fsm->state = ec_fsm_soe_error;
   399         return;
   404         return;
   416         ec_fsm_soe_print_error(fsm);
   421         ec_fsm_soe_print_error(fsm);
   417         fsm->state = ec_fsm_soe_error;
   422         fsm->state = ec_fsm_soe_error;
   418         return;
   423         return;
   419     }
   424     }
   420 
   425 
   421     data_size = rec_size - EC_SOE_READ_RESPONSE_SIZE;
   426     data_size = rec_size - EC_SOE_SIZE;
   422     if (ec_soe_request_append_data(req,
   427     if (ec_soe_request_append_data(req,
   423                 data + EC_SOE_READ_RESPONSE_SIZE, data_size)) {
   428                 data + EC_SOE_SIZE, data_size)) {
   424         fsm->state = ec_fsm_soe_error;
   429         fsm->state = ec_fsm_soe_error;
   425         ec_fsm_soe_print_error(fsm);
   430         ec_fsm_soe_print_error(fsm);
   426         return;
   431         return;
   427     }
   432     }
   428 
   433 
   461     ec_soe_request_t *req = fsm->request;
   466     ec_soe_request_t *req = fsm->request;
   462     uint8_t incomplete, *data;
   467     uint8_t incomplete, *data;
   463     size_t header_size, max_fragment_size, remaining_size, fragment_size;
   468     size_t header_size, max_fragment_size, remaining_size, fragment_size;
   464     uint16_t fragments_left;
   469     uint16_t fragments_left;
   465 
   470 
   466     header_size = EC_MBOX_HEADER_SIZE + EC_SOE_WRITE_REQUEST_SIZE;
   471     header_size = EC_MBOX_HEADER_SIZE + EC_SOE_SIZE;
   467     if (slave->configured_rx_mailbox_size <= header_size) {
   472     if (slave->configured_rx_mailbox_size <= header_size) {
   468         EC_ERR("Mailbox size (%u) too small for SoE write.\n",
   473         EC_ERR("Mailbox size (%u) too small for SoE write.\n",
   469                 slave->configured_rx_mailbox_size);
   474                 slave->configured_rx_mailbox_size);
   470         fsm->state = ec_fsm_soe_error;
   475         fsm->state = ec_fsm_soe_error;
   471         ec_fsm_soe_print_error(fsm);
   476         ec_fsm_soe_print_error(fsm);
   480     if (remaining_size % fragment_size) {
   485     if (remaining_size % fragment_size) {
   481         fragments_left++;
   486         fragments_left++;
   482     }
   487     }
   483 
   488 
   484     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   489     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   485             EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   490             EC_SOE_SIZE + fragment_size);
   486     if (IS_ERR(data)) {
   491     if (IS_ERR(data)) {
   487         fsm->state = ec_fsm_soe_error;
   492         fsm->state = ec_fsm_soe_error;
   488         ec_fsm_soe_print_error(fsm);
   493         ec_fsm_soe_print_error(fsm);
   489         return;
   494         return;
   490     }
   495     }
   491 
   496 
   492     EC_WRITE_U8(data, EC_SOE_OPCODE_WRITE_REQUEST | incomplete << 3);
   497     EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3);
   493     EC_WRITE_U8(data + 1, 1 << 6); // only value included
   498     EC_WRITE_U8(data + 1, 1 << 6); // only value included
   494     EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
   499     EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
   495     memcpy(data + 4, req->data + fsm->offset, fragment_size);
   500     memcpy(data + 4, req->data + fsm->offset, fragment_size);
   496     fsm->offset += fragment_size;
   501     fsm->offset += fragment_size;
   497 
   502 
   498     if (master->debug_level) {
   503     if (master->debug_level) {
   499         EC_DBG("SCC write request:\n");
   504         EC_DBG("SCC write request:\n");
   500         ec_print_data(data, EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   505         ec_print_data(data, EC_SOE_SIZE + fragment_size);
   501     }
   506     }
   502 
   507 
   503     req->jiffies_sent = jiffies;
   508     req->jiffies_sent = jiffies;
   504     fsm->retries = EC_FSM_RETRIES;
   509     fsm->retries = EC_FSM_RETRIES;
   505     fsm->state = ec_fsm_soe_write_request;
   510     fsm->state = ec_fsm_soe_write_request;
   680         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   685         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   681         ec_fsm_soe_print_error(fsm);
   686         ec_fsm_soe_print_error(fsm);
   682         return;
   687         return;
   683     }
   688     }
   684 
   689 
   685     if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE) {
   690     if (rec_size < EC_SOE_SIZE) {
   686         fsm->state = ec_fsm_soe_error;
   691         fsm->state = ec_fsm_soe_error;
   687         EC_ERR("Received currupted SoE write response (%zu bytes)!\n",
   692         EC_ERR("Received currupted SoE write response (%zu bytes)!\n",
   688                 rec_size);
   693                 rec_size);
   689         ec_print_data(data, rec_size);
   694         ec_print_data(data, rec_size);
   690         ec_fsm_soe_print_error(fsm);
   695         ec_fsm_soe_print_error(fsm);
   691         return;
   696         return;
   692     }
   697     }
   693 
   698 
   694     opcode = EC_READ_U8(data) & 0x7;
   699     opcode = EC_READ_U8(data) & 0x7;
   695     if (opcode != EC_SOE_OPCODE_WRITE_RESPONSE) {
   700     if (opcode != OPCODE_WRITE_RESPONSE) {
   696         EC_ERR("Received no write response (opcode %x).\n", opcode);
   701         EC_ERR("Received no write response (opcode %x).\n", opcode);
   697         ec_print_data(data, rec_size);
   702         ec_print_data(data, rec_size);
   698         ec_fsm_soe_print_error(fsm);
   703         ec_fsm_soe_print_error(fsm);
   699         fsm->state = ec_fsm_soe_error;
   704         fsm->state = ec_fsm_soe_error;
   700         return;
   705         return;
   709         return;
   714         return;
   710     }
   715     }
   711 
   716 
   712     error_flag = (EC_READ_U8(data) >> 4) & 1;
   717     error_flag = (EC_READ_U8(data) >> 4) & 1;
   713     if (error_flag) {
   718     if (error_flag) {
   714         if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE + 2) {
   719         if (rec_size < EC_SOE_SIZE + 2) {
   715             EC_ERR("Received corrupted error response - error flag set,"
   720             EC_ERR("Received corrupted error response - error flag set,"
   716                     " but received size is %zu.\n", rec_size);
   721                     " but received size is %zu.\n", rec_size);
   717         } else {
   722         } else {
   718             req->error_code = EC_READ_U16(data + EC_SOE_WRITE_RESPONSE_SIZE);
   723             req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
   719             EC_ERR("Received error response:\n");
   724             EC_ERR("Received error response:\n");
   720             ec_print_soe_error(req->error_code);
   725             ec_print_soe_error(req->error_code);
   721         }
   726         }
   722         ec_print_data(data, rec_size);
   727         ec_print_data(data, rec_size);
   723         ec_fsm_soe_print_error(fsm);
   728         ec_fsm_soe_print_error(fsm);