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); |