1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * implementation of the transport layer protocol (known as librsc protocol): 27 * 28 */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * Header files 34 */ 35 36 #include <sys/conf.h> 37 #include <sys/cyclic.h> 38 #include <sys/membar.h> 39 #include <sys/modctl.h> 40 #include <sys/strlog.h> 41 #include <sys/sunddi.h> 42 #include <sys/ddi.h> 43 #include <sys/types.h> 44 #include <sys/rmc_comm_dp.h> 45 #include <sys/rmc_comm_dp_boot.h> 46 #include <sys/rmc_comm_drvintf.h> 47 #include <sys/rmc_comm.h> 48 49 #ifdef DEBUG_ERROR_INJECTION 50 51 #define ERRI_RX_SEQ_NUMBER 1 52 #define ERRI_ACK_MSG 2 53 #define ERRI_CRC_HEADER 3 54 #define ERRI_CRC_MSG 4 55 #define ERRI_SEND_CTL_STACK 5 56 #define ERRI_SEND_CTL_START 6 57 58 #define ERRI_CTL_RX_SEQ_NUMBER 7 59 #define ERRI_CTL_CRC_HEADER 8 60 61 int erri_test_number = 0; 62 int erri_test_intrvl = 0; 63 int erri_test_repeat = 0; 64 int erri_test_count = 0; 65 66 int erri_test_simulate_srec_sec(struct rmc_comm_state *, char *, int); 67 68 #endif 69 70 71 /* static functions */ 72 73 static void dp_link_setup_tohandler(void *); 74 static void dp_delay_ack_tohandler(void *); 75 static uint8_t *dp_get_buffer(struct rmc_comm_state *, uint8_t); 76 static void dp_release_buffer(struct rmc_comm_state *, uint8_t); 77 static void dp_init_buffers(struct rmc_comm_state *); 78 static void dp_got_full_hdr(struct rmc_comm_state *, dp_packet_t *); 79 static void dp_got_bp_msg(struct rmc_comm_state *, dp_packet_t *); 80 static void dp_got_full_msg(struct rmc_comm_state *, dp_packet_t *); 81 static void dp_tx_handle_ack(struct rmc_comm_state *, uint16_t); 82 static void dp_tx_handle_nak(struct rmc_comm_state *, uint16_t); 83 static void dp_send_packet(struct rmc_comm_state *, uchar_t *); 84 static void dp_enable_data_link(struct rmc_comm_state *); 85 static int dp_get_msglen(struct rmc_comm_state *, uint8_t *); 86 static uint16_t dp_calc_crc16(uint8_t *, int); 87 void dp_wake_up_waiter(struct rmc_comm_state *, uint8_t); 88 void dp_reset(struct rmc_comm_state *, uint8_t, boolean_t, boolean_t); 89 90 /* 91 * utilities... 92 */ 93 94 /* 95 * init rx/tx buffer pool 96 */ 97 static void 98 dp_init_buffers(struct rmc_comm_state *rcs) 99 { 100 int i; 101 dp_buffer_t *dbuf = rcs->dp_state.dp_buffers; 102 103 for (i = 0; i < DP_BUFFER_COUNT; i++) 104 dbuf[i].in_use = 0; 105 } 106 107 /* 108 * get tx/rx buffer 109 */ 110 static uint8_t * 111 dp_get_buffer(struct rmc_comm_state *rcs, uint8_t type) 112 { 113 dp_buffer_t *dbuf = rcs->dp_state.dp_buffers; 114 115 ASSERT(MUTEX_HELD(rcs->dp_state.dp_mutex)); 116 117 if ((type != DP_TX_BUFFER && type != DP_RX_BUFFER) || 118 dbuf[type].in_use) { 119 120 DPRINTF(rcs, DMEM, 121 (CE_CONT, "get buffer err. type=%d, in_use=%d\n", 122 type, dbuf[type].in_use)); 123 124 return (NULL); 125 } 126 127 DPRINTF(rcs, DMEM, (CE_CONT, "get buffer type=%d\n", type)); 128 129 dbuf[type].in_use = 1; 130 131 return (dbuf[type].buf); 132 } 133 134 /* 135 * release tx/rx buffer 136 */ 137 static void 138 dp_release_buffer(struct rmc_comm_state *rcs, uint8_t type) 139 { 140 dp_buffer_t *dbuf = rcs->dp_state.dp_buffers; 141 142 ASSERT(MUTEX_HELD(rcs->dp_state.dp_mutex)); 143 144 if (type != DP_TX_BUFFER && type != DP_RX_BUFFER) { 145 DPRINTF(rcs, DMEM, 146 (CE_CONT, "free buffer err. type=%d, in_use=%d\n", 147 type, dbuf[type].in_use)); 148 return; 149 } 150 DPRINTF(rcs, DMEM, (CE_CONT, "free buffer type=%d\n", type)); 151 152 dbuf[type].in_use = 0; 153 } 154 155 /* 156 * setup data link timeout handler 157 * (called without having the dp_mutex) 158 */ 159 static void 160 dp_link_setup_tohandler(void *arg) 161 { 162 struct rmc_comm_state *rcs = (struct rmc_comm_state *)arg; 163 rmc_comm_dp_state_t *dps = &rcs->dp_state; 164 165 DPRINTF(rcs, DPRO, (CE_CONT, "t/o setup data link\n")); 166 167 /* 168 * check if timer has actually been cancelled 169 */ 170 mutex_enter(dps->dp_mutex); 171 if (dps->timer_link_setup != (timeout_id_t)0) { 172 173 /* 174 * send CTL:start to the remote side to set up the data link 175 */ 176 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_START); 177 178 dps->timer_link_setup = timeout(dp_link_setup_tohandler, 179 (void *) rcs, drv_usectohz(RETRY_DP_SETUP * 1000)); 180 } 181 mutex_exit(dps->dp_mutex); 182 } 183 184 /* 185 * delay acknowledgment of a received message timeout handler 186 * (called without having the dp_mutex) 187 */ 188 static void 189 dp_delay_ack_tohandler(void *arg) 190 { 191 struct rmc_comm_state *rcs = (struct rmc_comm_state *)arg; 192 rmc_comm_dp_state_t *dps = &rcs->dp_state; 193 194 #ifdef DEBUG_ERROR_INJECTION 195 196 if (erri_test_number == ERRI_ACK_MSG && 197 erri_test_repeat >= 0 && 198 erri_test_count++ > 0 && !(erri_test_count % erri_test_intrvl)) { 199 200 /* 201 * DON'T ACK THE MESSAGE - BE SILENT! 202 */ 203 204 if (erri_test_repeat == 0) 205 erri_test_repeat--; /* will not repeat the test */ 206 207 dps->timer_delay_ack = (timeout_id_t)0; 208 return; 209 } 210 211 #endif 212 213 /* 214 * check if timer has actually been cancelled 215 */ 216 mutex_enter(dps->dp_mutex); 217 if (dps->timer_delay_ack != (timeout_id_t)0) { 218 /* 219 * ACK the message 220 */ 221 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_ACK); 222 dps->timer_delay_ack = (timeout_id_t)0; 223 } 224 mutex_exit(dps->dp_mutex); 225 } 226 227 /* 228 * Enable data link protocol: 229 * stop data link setup timer 230 * set data_link_ok flag 231 * (must already have the dp_mutex) 232 */ 233 static void 234 dp_enable_data_link(struct rmc_comm_state *rcs) 235 { 236 rmc_comm_dp_state_t *dps = &rcs->dp_state; 237 timeout_id_t timer_id; 238 239 ASSERT(MUTEX_HELD(dps->dp_mutex)); 240 241 dps->data_link_ok = 1; 242 243 timer_id = dps->timer_link_setup; 244 dps->timer_link_setup = (timeout_id_t)0; 245 if (timer_id != (timeout_id_t)0) { 246 247 mutex_exit(dps->dp_mutex); 248 (void) untimeout(timer_id); 249 mutex_enter(dps->dp_mutex); 250 } 251 } 252 253 /* 254 * CRC calculation routine. 255 */ 256 static uint16_t 257 dp_calc_crc16(uint8_t *buf, int len) 258 { 259 extern uint16_t crctab16[]; 260 uint16_t crc; 261 262 crc = 0; 263 while (len--) { 264 crc = (crc >> 8) ^ crctab16[(crc ^ *buf++) & 0xFF]; 265 } 266 return (crc); 267 } 268 269 /* 270 * Reset the data protocol 271 * (dp_mutex must be held) 272 */ 273 void 274 dp_reset(struct rmc_comm_state *rcs, uint8_t rx_seqid, 275 boolean_t flush_tx, boolean_t restart_data_link) 276 { 277 rmc_comm_dp_state_t *dps = &rcs->dp_state; 278 279 ASSERT(MUTEX_HELD(dps->dp_mutex)); 280 281 DPRINTF(rcs, DPRO, (CE_CONT, 282 "reset proto: rxsid=%d, flushtx=%d, restartdp=%d\n", 283 rx_seqid, flush_tx, restart_data_link)); 284 285 DPRINTF(rcs, DGEN, (CE_CONT, 286 "stats: reset=%d nak=%d start=%d stack=%d retries=%d crcerr=%d\n", 287 dps->reset_cnt, dps->nak_cnt, dps->start_cnt, dps->stack_cnt, 288 dps->retries_cnt, dps->crcerr_cnt)); 289 290 dps->last_rx_seqid = rx_seqid; 291 dps->reset_cnt++; 292 293 /* 294 * Flush pending tx message. 295 */ 296 if (flush_tx) { 297 dps->last_tx_seqid = INITIAL_SEQID; 298 dps->last_rx_ack = rx_seqid; 299 300 /* 301 * if there is any pending request/response session 302 * then just abort it. 303 */ 304 dp_wake_up_waiter(rcs, MSG_ERROR); 305 } 306 307 /* 308 * restart data link, but only if the data link set up timer is 309 * not already running. 310 */ 311 if (restart_data_link && dps->timer_link_setup == (timeout_id_t)0) { 312 313 dps->data_link_ok = 0; 314 315 /* 316 * set up the data protocol link 317 */ 318 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_START); 319 dps->timer_link_setup = timeout(dp_link_setup_tohandler, 320 (void *)rcs, drv_usectohz(RETRY_DP_SETUP * 1000)); 321 } 322 } 323 324 /* 325 * Handles acknowledgment of a message previously sent OR a heartbeat command 326 * (CTL_RESPOND). 327 */ 328 static void 329 dp_tx_handle_ack(struct rmc_comm_state *rcs, uint16_t rxnum) 330 { 331 rmc_comm_dp_state_t *dps = &rcs->dp_state; 332 dp_req_resp_t *drr = &dps->req_resp; 333 334 ASSERT(MUTEX_HELD(dps->dp_mutex)); 335 336 DPRINTF(rcs, DPRO, (CE_CONT, "handle ACK, rxnum=%03d\n", rxnum)); 337 338 dps->last_rx_ack = rxnum; 339 if ((drr->flags & MSG_SENT) == 0) { 340 /* 341 * no pending messages, so nothing to do 342 */ 343 return; 344 } 345 346 if (rxnum == dps->last_tx_seqid) { 347 /* 348 * message was sent and acknowledged successfully 349 * set flag and signal the waiting task if it is not 350 * expecting a reply back 351 */ 352 drr->flags |= MSG_ACKED; 353 if (drr->response.msg_type == DP_NULL_MSG) { 354 dp_wake_up_waiter(rcs, MSG_ACKED); 355 } 356 } 357 } 358 359 /* 360 * Handles NAK 361 */ 362 static void 363 dp_tx_handle_nak(struct rmc_comm_state *rcs, uint16_t rxnum) 364 { 365 rmc_comm_dp_state_t *dps = &rcs->dp_state; 366 dp_req_resp_t *drr = &dps->req_resp; 367 368 ASSERT(MUTEX_HELD(dps->dp_mutex)); 369 370 DPRINTF(rcs, DPRO, (CE_CONT, "handle NAK, rxnum=%03d\n", rxnum)); 371 372 if ((drr->flags & MSG_SENT) == 0) { 373 /* 374 * no pending messages, so nothing to do 375 */ 376 return; 377 } 378 379 /* 380 * since one message per time can be sent, it is assumed that the 381 * message being NAKed is just the one that has been sent. 382 */ 383 dps->nak_cnt++; 384 385 dp_wake_up_waiter(rcs, MSG_NAKED); 386 } 387 388 /* 389 * Got a full header. Check header CRC and get the length of the packet 390 */ 391 static void 392 dp_got_full_hdr(struct rmc_comm_state *rcs, dp_packet_t *pkt) 393 { 394 /* 395 * Got the full header. Call up to the logical layer to see 396 * how big of a buffer I need for this message. If the size 397 * is < sizeof (dp_msg_t), then there is something wrong with 398 * this message - drop it. If the size is equal, then hand it 399 * up right now. If the size is too big - drop it. otherwise we must 400 * receive the body of the message. 401 */ 402 403 pkt->full_length = dp_get_msglen(rcs, pkt->buf); 404 405 DPRINTF(rcs, DPKT, (CE_CONT, "got header msglen=%d\n", 406 pkt->full_length)); 407 408 if ((pkt->full_length < 0) || 409 (pkt->full_length < sizeof (dp_header_t)) || 410 (pkt->full_length > DP_BUFFER_SIZE)) { 411 /* 412 * not a valid message: either message too big or too small 413 */ 414 dp_release_buffer(rcs, DP_RX_BUFFER); 415 pkt->buf = NULL; 416 417 pkt->rx_state = WAITING_FOR_SYNC; 418 419 } else if (pkt->full_length == sizeof (dp_header_t)) { 420 /* 421 * process message: it is basically a control message 422 * (no data being carried) 423 */ 424 rmc_comm_dp_mrecv(rcs, pkt->buf); 425 426 dp_release_buffer(rcs, DP_RX_BUFFER); 427 pkt->buf = NULL; 428 429 pkt->rx_state = WAITING_FOR_SYNC; 430 } else { 431 pkt->rx_state = RECEIVING_BODY; 432 } 433 } 434 435 /* 436 * Got a BP (boot prom) message. Usually, BP messages are received when 437 * the firmware goes into boot monitor mode (where only BP protocol is used). 438 * This just happens during firmware download. There should not be any other 439 * case where a BP message is received. 440 */ 441 static void 442 dp_got_bp_msg(struct rmc_comm_state *rcs, dp_packet_t *pkt) 443 { 444 bp_msg_t *msgp = (bp_msg_t *)pkt->buf; 445 rmc_comm_dp_state_t *dps = &rcs->dp_state; 446 dp_req_resp_t *drr = &dps->req_resp; 447 int datalen = sizeof (bp_msg_t); 448 449 ASSERT(MUTEX_HELD(dps->dp_mutex)); 450 451 /* 452 * ignore BP message, if it is not expected 453 */ 454 if ((drr->flags & MSG_SENT_BP) != 0) { 455 456 DPRINTF(rcs, DPRO, (CE_CONT, "got bp msg: %02x %02x %02x\n", 457 msgp->cmd, msgp->dat1, msgp->dat2)); 458 459 /* 460 * A boot prom (BP) msg has been sent. Here is the 461 * 'expected' reply 462 */ 463 464 /* 465 * check that the recv buffer is big enough (just in case). 466 */ 467 if (datalen <= drr->response.msg_bufsiz) { 468 bcopy(pkt->buf, drr->response.msg_buf, datalen); 469 drr->response.msg_msglen = datalen; 470 dp_wake_up_waiter(rcs, MSG_RXED_BP); 471 } else { 472 drr->response.msg_msglen = -1; 473 dp_wake_up_waiter(rcs, MSG_RXED_BP); 474 } 475 } 476 477 /* Return the buffer to the pool and wait for the next msg. */ 478 dp_release_buffer(rcs, DP_RX_BUFFER); 479 pkt->buf = NULL; 480 pkt->rx_state = WAITING_FOR_SYNC; 481 } 482 483 /* 484 * Got a complete message, check CRC and pass it on to the upper layer (message 485 * processing) 486 */ 487 static void 488 dp_got_full_msg(struct rmc_comm_state *rcs, dp_packet_t *pkt) 489 { 490 uint16_t crc; 491 int msglen; 492 493 DPRINTF(rcs, DPKT, (CE_CONT, "got full msg\n")); 494 495 /* 496 * check message CRC 497 */ 498 499 msglen = pkt->full_length - sizeof (dp_header_t) - sizeof (crc); 500 501 bcopy(pkt->buf + (pkt->full_length - sizeof (crc)), &crc, sizeof (crc)); 502 503 if (crc == dp_calc_crc16(pkt->buf + sizeof (dp_header_t), msglen)) { 504 /* 505 * CRC is ok, process this message 506 */ 507 DPRINTF(rcs, DPKT, (CE_CONT, "got 'good' msg\n")); 508 509 rmc_comm_dp_mrecv(rcs, pkt->buf); 510 } else { 511 DPRINTF(rcs, DPKT, (CE_CONT, "CRC error (msg)\n")); 512 rcs->dp_state.crcerr_cnt++; 513 } 514 515 dp_release_buffer(rcs, DP_RX_BUFFER); 516 pkt->buf = NULL; 517 518 pkt->rx_state = WAITING_FOR_SYNC; 519 } 520 521 /* 522 * Check the checksum of the header & return the length field. If the 523 * checksum check fails, then return -1. 524 */ 525 static int 526 dp_get_msglen(struct rmc_comm_state *rcs, uint8_t *buf) 527 { 528 dp_header_t *dp_msgp; 529 uint16_t crc; 530 531 dp_msgp = (dp_header_t *)buf; 532 533 crc = dp_calc_crc16(buf + sizeof (dp_msgp->pad), sizeof (dp_header_t) - 534 sizeof (dp_msgp->crc) - sizeof (dp_msgp->pad)); 535 536 if (dp_msgp->crc == crc) { 537 return (dp_msgp->length + sizeof (dp_msgp->pad)); 538 } else { 539 DPRINTF(rcs, DPKT, (CE_CONT, "CRC error (header)\n")); 540 rcs->dp_state.crcerr_cnt++; 541 return (-1); 542 } 543 } 544 545 /* 546 * to send a protocol packet to the remote side. it handles escaping SYNC 547 * and ESC chars 548 */ 549 static void 550 dp_send_packet(struct rmc_comm_state *rcs, uchar_t *buf) 551 { 552 char syncbuf[2]; 553 dp_header_t *dp_msgp = (dp_header_t *)buf; 554 int total, cur; 555 556 /* First, send out two SYNC characters. */ 557 syncbuf[0] = syncbuf[1] = SYNC_CHAR; 558 rmc_comm_serdev_send(rcs, (char *)syncbuf, 2); 559 560 total = dp_msgp->length; 561 buf = buf + sizeof (dp_msgp->pad); 562 563 while (total > 0) { 564 cur = 0; 565 566 /* Count up characters that don't need ESC'ing. */ 567 while ((cur < total) && 568 (buf[cur] != ESC_CHAR) && 569 (buf[cur] != SYNC_CHAR)) { 570 cur++; 571 } 572 573 /* Send characters that don't need escaping, if any. */ 574 if (cur > 0) { 575 rmc_comm_serdev_send(rcs, (char *)buf, cur); 576 total -= cur; 577 buf += cur; 578 } 579 580 /* 581 * If total > 0 at this point, we need to send an 582 * ESC'd character. Send as many as there are. 583 */ 584 while ((total > 0) && 585 ((*buf == SYNC_CHAR) || (*buf == ESC_CHAR))) { 586 syncbuf[0] = ESC_CHAR; 587 syncbuf[1] = *buf; 588 rmc_comm_serdev_send(rcs, (char *)syncbuf, 2); 589 buf++; 590 total--; 591 } 592 } 593 } 594 595 /* 596 * to wake a thread waiting for a reply/ACK/error status for a request/response 597 * session. 598 */ 599 void 600 dp_wake_up_waiter(struct rmc_comm_state *rcs, uint8_t flags) 601 { 602 dp_req_resp_t *drr = &rcs->dp_state.req_resp; 603 604 ASSERT(MUTEX_HELD(rcs->dp_state.dp_mutex)); 605 606 DPRINTF(rcs, DGEN, (CE_CONT, "wake up? %x, set %x\n", 607 (drr->flags & (MSG_SENT | MSG_SENT_BP)) != 0, flags)); 608 609 if ((drr->flags & (MSG_SENT | MSG_SENT_BP)) != 0) { 610 drr->flags |= flags; 611 cv_signal(drr->cv_wait_reply); 612 } 613 } 614 615 /* 616 * initialization of the data protocol (called from the attach routine) 617 */ 618 void 619 rmc_comm_dp_init(struct rmc_comm_state *rcs) 620 { 621 rmc_comm_dp_state_t *dps = &rcs->dp_state; 622 dp_packet_t *pkt = &dps->dp_packet; 623 624 DPRINTF(rcs, DGEN, (CE_CONT, "rmc_comm_dp_init\n")); 625 626 /* 627 * initialize data structure: 628 */ 629 bzero((void *) dps, sizeof (rmc_comm_dp_state_t)); 630 631 /* 632 * initialize packet receive handler state 633 */ 634 635 pkt->rx_state = WAITING_FOR_SYNC; 636 637 /* 638 * cv variables initialization 639 * (dp_mutex has been already created during the serial device 640 * initialization) 641 */ 642 cv_init(dps->cv_ok_to_send, NULL, CV_DRIVER, NULL); 643 cv_init(dps->req_resp.cv_wait_reply, NULL, CV_DRIVER, NULL); 644 645 mutex_enter(dps->dp_mutex); 646 647 dp_init_buffers(rcs); 648 649 /* 650 * initialize the data protocol (reset sequence numbers, etc.) 651 */ 652 dps->last_tx_seqid = INITIAL_SEQID; 653 dps->last_rx_seqid = dps->last_rx_ack = INITIAL_SEQID; 654 655 /* 656 * start timer to 'delay' the set up of the data protocol link 657 */ 658 dps->timer_link_setup = timeout(dp_link_setup_tohandler, 659 (void *)rcs, drv_usectohz(DELAY_DP_SETUP * 1000)); 660 661 mutex_exit(dps->dp_mutex); 662 663 #ifdef DEBUG_ERROR_INJECTION 664 665 erri_test_number = ddi_prop_get_int(DDI_DEV_T_ANY, rcs->dip, 666 DDI_PROP_DONTPASS, "test-no", 0); 667 erri_test_intrvl = ddi_prop_get_int(DDI_DEV_T_ANY, rcs->dip, 668 DDI_PROP_DONTPASS, "test-interval", 0); 669 erri_test_repeat = ddi_prop_get_int(DDI_DEV_T_ANY, rcs->dip, 670 DDI_PROP_DONTPASS, "test-repeat", 0); 671 672 erri_test_count = 0; 673 674 675 cmn_err(CE_CONT, "error injection test: no=%d, intrvl=%d, rep=%d\n", 676 erri_test_number, erri_test_intrvl, erri_test_repeat); 677 #endif 678 679 } 680 681 /* 682 * termination of the data protocol (called from the detach routine) 683 */ 684 void 685 rmc_comm_dp_fini(struct rmc_comm_state *rcs) 686 { 687 rmc_comm_dp_state_t *dps = &rcs->dp_state; 688 timeout_id_t tid_delay_ack; 689 timeout_id_t tid_link_setup; 690 691 DPRINTF(rcs, DGEN, (CE_CONT, 692 "stats: reset=%d nak=%d start=%d stack=%d retries=%d crcerr=%d\n", 693 dps->reset_cnt, dps->nak_cnt, dps->start_cnt, dps->stack_cnt, 694 dps->retries_cnt, dps->crcerr_cnt)); 695 696 /* 697 * if any timer is running, must be terminated here! 698 */ 699 mutex_enter(dps->dp_mutex); 700 tid_delay_ack = dps->timer_link_setup; 701 tid_link_setup = dps->timer_delay_ack; 702 dps->timer_link_setup = (timeout_id_t)0; 703 dps->timer_delay_ack = (timeout_id_t)0; 704 mutex_exit(dps->dp_mutex); 705 706 if (tid_delay_ack) 707 (void) untimeout(tid_delay_ack); 708 709 if (tid_link_setup) 710 (void) untimeout(tid_link_setup); 711 712 /* 713 * cv variables termination 714 */ 715 cv_destroy(dps->cv_ok_to_send); 716 cv_destroy(dps->req_resp.cv_wait_reply); 717 } 718 719 /* 720 * This is the low-level receiver handler. It's job is to find a complete 721 * message from the incoming data stream, and once it finds one to pass it 722 * on to the upper layer (message processing). 723 * (it must have the dp_mutex) 724 */ 725 void 726 rmc_comm_dp_drecv(struct rmc_comm_state *rcs, uint8_t *buf, int buflen) 727 { 728 rmc_comm_dp_state_t *dps = &rcs->dp_state; 729 dp_packet_t *pkt = &dps->dp_packet; 730 uint8_t quit; 731 int count; 732 int max; 733 734 ASSERT(MUTEX_HELD(dps->dp_mutex)); 735 736 pkt->inbuf = buf; 737 pkt->inbuflen = buflen; 738 739 DPRINTF(rcs, DPKT, (CE_CONT, "drecv len=%d\n", buflen)); 740 741 while (pkt->inbuflen > 0) { 742 switch (pkt->rx_state) { 743 744 case WAITING_FOR_SYNC: 745 while ((pkt->inbuflen > 0) && 746 (*pkt->inbuf != SYNC_CHAR) && 747 (*pkt->inbuf != ESC_CHAR)) { 748 749 DPRINTF(rcs, DPKT, 750 (CE_CONT, "not SYNC: %02x\n", 751 (uchar_t)(*pkt->inbuf))); 752 753 pkt->inbuf++; 754 pkt->inbuflen--; 755 } 756 757 if (pkt->inbuflen > 0) { 758 if (*pkt->inbuf == SYNC_CHAR) 759 pkt->rx_state = WAITING_FOR_HDR; 760 else if (*pkt->inbuf == ESC_CHAR) 761 pkt->rx_state = WAITING_FOR_SYNC_ESC; 762 } 763 break; 764 765 case WAITING_FOR_SYNC_ESC: 766 pkt->inbuf++; 767 pkt->inbuflen--; 768 pkt->rx_state = WAITING_FOR_SYNC; 769 break; 770 771 case WAITING_FOR_HDR: 772 while ((pkt->inbuflen > 0) && 773 (*pkt->inbuf == SYNC_CHAR)) { 774 pkt->inbuf++; 775 pkt->inbuflen--; 776 } 777 778 if (pkt->inbuflen <= 0) 779 break; 780 781 if (*pkt->inbuf == ESC_CHAR) { 782 /* 783 * ESC as first char of header? 784 * Impossible - start over! 785 */ 786 pkt->rx_state = WAITING_FOR_SYNC; 787 pkt->inbuf++; 788 pkt->inbuflen--; 789 break; 790 } 791 792 /* Get a buffer for this message. */ 793 pkt->buf = dp_get_buffer(rcs, DP_RX_BUFFER); 794 if (pkt->buf == NULL) { 795 /* Out of buffers - drop this msg. */ 796 pkt->rx_state = WAITING_FOR_SYNC; 797 break; 798 } 799 DPRINTF(rcs, DPKT, (CE_CONT, "drecv first char %x\n", 800 (uchar_t)*pkt->inbuf)); 801 802 pkt->buf[1] = *pkt->inbuf; 803 pkt->bufpos = 2; 804 pkt->rx_state = RECEIVING_HDR; 805 806 pkt->inbuf++; 807 pkt->inbuflen--; 808 break; 809 810 case RECEIVING_HDR: 811 quit = 0; 812 while ((pkt->inbuflen > 0) && 813 (*pkt->inbuf != SYNC_CHAR) && 814 (*pkt->inbuf != ESC_CHAR)) { 815 pkt->buf[pkt->bufpos++] = *pkt->inbuf; 816 pkt->inbuf++; 817 pkt->inbuflen--; 818 if (pkt->bufpos >= sizeof (dp_header_t)) { 819 dp_got_full_hdr(rcs, pkt); 820 quit = 1; 821 break; 822 } else if ((pkt->bufpos >= sizeof (bp_msg_t)) && 823 (IS_BOOT_MSG(pkt->buf[1]))) { 824 dp_got_bp_msg(rcs, pkt); 825 quit = 1; 826 break; 827 } 828 } 829 830 if (quit) 831 break; 832 833 if (pkt->inbuflen > 0) { 834 /* Must have gotten an ESC_CHAR or SYNC_CHAR. */ 835 if (*pkt->inbuf == SYNC_CHAR) { 836 837 DPRINTF(rcs, DPKT, 838 (CE_CONT, "drecv sync in hdr, " 839 "bufpos=%d\n", pkt->bufpos)); 840 841 dp_release_buffer(rcs, DP_RX_BUFFER); 842 pkt->buf = NULL; 843 pkt->rx_state = WAITING_FOR_HDR; 844 } else { 845 pkt->rx_state = RECEIVING_HDR_ESC; 846 } 847 pkt->inbuf++; 848 pkt->inbuflen--; 849 } 850 break; 851 852 case RECEIVING_HDR_ESC: 853 pkt->buf[pkt->bufpos++] = *pkt->inbuf; 854 pkt->inbuf++; 855 pkt->inbuflen--; 856 if (pkt->bufpos >= sizeof (dp_header_t)) { 857 dp_got_full_hdr(rcs, pkt); 858 } else if ((pkt->bufpos >= sizeof (bp_msg_t)) && 859 (IS_BOOT_MSG(pkt->buf[1]))) { 860 dp_got_bp_msg(rcs, pkt); 861 } else { 862 pkt->rx_state = RECEIVING_HDR; 863 } 864 break; 865 866 case RECEIVING_BODY: 867 max = pkt->full_length - pkt->bufpos; 868 if (max > pkt->inbuflen) 869 max = pkt->inbuflen; 870 871 for (count = 0; count < max; count++) 872 if ((pkt->inbuf[count] == SYNC_CHAR) || 873 (pkt->inbuf[count] == ESC_CHAR)) 874 break; 875 876 if (count > 0) { 877 bcopy(pkt->inbuf, pkt->buf + pkt->bufpos, 878 count); 879 pkt->inbuf += count; 880 pkt->inbuflen -= count; 881 pkt->bufpos += count; 882 883 if (pkt->bufpos >= pkt->full_length) { 884 dp_got_full_msg(rcs, pkt); 885 break; 886 } 887 } 888 889 if (count < max) { 890 /* Must have gotten an ESC_CHAR or SYNC_CHAR. */ 891 if (*pkt->inbuf == SYNC_CHAR) { 892 dp_release_buffer(rcs, DP_RX_BUFFER); 893 pkt->buf = NULL; 894 pkt->rx_state = WAITING_FOR_HDR; 895 } else { 896 pkt->rx_state = RECEIVING_BODY_ESC; 897 } 898 pkt->inbuf++; 899 pkt->inbuflen--; 900 } 901 break; 902 903 case RECEIVING_BODY_ESC: 904 pkt->buf[pkt->bufpos] = *pkt->inbuf; 905 pkt->inbuf++; 906 pkt->inbuflen--; 907 pkt->bufpos++; 908 if (pkt->bufpos >= pkt->full_length) { 909 dp_got_full_msg(rcs, pkt); 910 } else { 911 pkt->rx_state = RECEIVING_BODY; 912 } 913 break; 914 } 915 } 916 } 917 918 /* 919 * Handle an incoming message. CRCs have been already checked so message 920 * is good. check if sequence numbers are ok. 921 * Handles: control message, asynchronous notification, reply to requests 922 * and notify the leaf driver of those events. 923 * (it must have the dp_mutex) 924 */ 925 void 926 rmc_comm_dp_mrecv(struct rmc_comm_state *rcs, uint8_t *buf) 927 { 928 rmc_comm_dp_state_t *dps = &rcs->dp_state; 929 dp_header_t *dp_msgp; 930 uint8_t *datap; 931 int datalen; 932 dp_msg_intr_t *dmi = &dps->msg_intr; 933 dp_req_resp_t *drr = &dps->req_resp; 934 935 ASSERT(MUTEX_HELD(dps->dp_mutex)); 936 937 dp_msgp = (dp_header_t *)buf; 938 939 datalen = dp_msgp->length - 940 (sizeof (dp_header_t) - sizeof (dp_msgp->pad)); 941 942 if (datalen > 0) { 943 datalen = datalen - sizeof (uint16_t); /* don't count msg CRC */ 944 datap = buf + sizeof (dp_header_t); 945 } else { 946 datap = NULL; 947 } 948 949 DPRINTF(rcs, DPRO, (CE_CONT, 950 "[t%03dr%03d] mrecv msgtype: %02x, len=%d\n", 951 dp_msgp->txnum, dp_msgp->rxnum, dp_msgp->type, datalen)); 952 953 /* 954 * Handle control messages first 955 */ 956 if (IS_UNNUMBERED_MSG(dp_msgp->type)) { 957 switch (dp_msgp->type) { 958 case DP_CTL_START: 959 /* 960 * CTL:start 961 * Re-init protocol processing. 962 * Enable data link 963 * Stop data link setup timer if running 964 */ 965 DPRINTF(rcs, DPRO, (CE_CONT, "mrecv data link ok\n")); 966 967 dp_reset(rcs, dp_msgp->txnum, 1, 0); 968 969 dp_wake_up_waiter(rcs, 0); 970 971 /* Send CTL:stack message. */ 972 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_STACK); 973 974 dps->start_cnt++; 975 976 dp_enable_data_link(rcs); 977 978 break; 979 980 case DP_CTL_STACK: 981 /* 982 * CTL:stack 983 * Enable data link 984 * Stop data link setup timer if running 985 */ 986 DPRINTF(rcs, DPRO, (CE_CONT, "mrecv data link ok\n")); 987 988 dp_reset(rcs, dp_msgp->txnum, 0, 0); 989 990 dp_wake_up_waiter(rcs, 0); 991 992 dps->stack_cnt++; 993 994 dp_enable_data_link(rcs); 995 break; 996 997 case DP_CTL_RESPOND: 998 /* 999 * CTL:respond (heartbeat) 1000 * Send a CTL:ack. 1001 */ 1002 if (dps->data_link_ok) { 1003 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_ACK); 1004 } 1005 break; 1006 1007 case DP_CTL_ACK: 1008 /* 1009 * CTL:ack 1010 * Call a transmit-side routine to handle it. 1011 */ 1012 dp_tx_handle_ack(rcs, dp_msgp->rxnum); 1013 break; 1014 1015 case DP_CTL_NAK: 1016 /* 1017 * CTL:nak 1018 * Call a transmit-side routine to handle it. 1019 */ 1020 dp_tx_handle_nak(rcs, dp_msgp->rxnum); 1021 break; 1022 1023 default: 1024 /* Drop message. */ 1025 DPRINTF(rcs, DPRO, 1026 (CE_CONT, "mrecv unknown ctrlmsg\n")); 1027 break; 1028 } 1029 return; 1030 } 1031 1032 /* 1033 * Before processing the received message (NUMBERED), check that the 1034 * data link protocol is up. If not, ignore this message 1035 */ 1036 if (!dps->data_link_ok) { 1037 DPRINTF(rcs, DPRO, (CE_CONT, "mrecv drop msg: no data link\n")); 1038 return; 1039 } 1040 1041 /* 1042 * we received a message (NUMBERED) and data link is ok. 1043 * First, instead of ACKing this message now, we delay it. The reason 1044 * why is that a message can be sent (from this side) in the meantime 1045 * and it can ACK the received message (it will spare us to send 1046 * the ACK message across the wire). 1047 */ 1048 1049 /* 1050 * Handle acknowledgements even if this is a duplicate message. 1051 */ 1052 if (dps->timer_delay_ack == (timeout_id_t)0) { 1053 dps->timer_delay_ack = timeout(dp_delay_ack_tohandler, 1054 (void *) rcs, drv_usectohz(TX_RETRY_TIME/2 * 1000)); 1055 DPRINTF(rcs, DGEN, (CE_CONT, "mrecv start ack t/o %p\n", 1056 dps->timer_delay_ack)); 1057 } 1058 dp_tx_handle_ack(rcs, dp_msgp->rxnum); 1059 1060 if (dp_msgp->txnum != NEXT_SEQID(dps->last_rx_seqid)) { 1061 /* Duplicate message - free it up & return. */ 1062 DPRINTF(rcs, DPRO, (CE_CONT, "mrecv dup msg txnum=%03d\n", 1063 dp_msgp->txnum)); 1064 return; 1065 } 1066 dps->last_rx_seqid = dp_msgp->txnum; 1067 1068 #ifdef DEBUG_ERROR_INJECTION 1069 1070 if ((erri_test_number == ERRI_SEND_CTL_STACK || 1071 erri_test_number == ERRI_SEND_CTL_START) && 1072 erri_test_repeat >= 0 && 1073 erri_test_count++ > 0 && !(erri_test_count % erri_test_intrvl)) { 1074 1075 if (erri_test_number == ERRI_SEND_CTL_STACK) { 1076 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_STACK); 1077 1078 } else if (erri_test_number == ERRI_SEND_CTL_START) { 1079 (void) rmc_comm_dp_ctlsend(rcs, DP_CTL_START); 1080 1081 } 1082 if (erri_test_repeat == 0) 1083 erri_test_repeat--; /* will not repeat the test */ 1084 } 1085 1086 #endif 1087 1088 /* 1089 * At this point, we know this is a good message. We've 1090 * checked checksums, message types, and sequence id's. 1091 */ 1092 1093 /* 1094 * First, check if a driver has register for this message 1095 * Second, check if this message is a reply to a request 1096 * Third, check to see if ALOM is telling us it doesn't 1097 * know about the command code. 1098 */ 1099 1100 if (dmi->intr_handler != NULL && 1101 dmi->intr_msg_type == dp_msgp->type) { 1102 1103 rmc_comm_msg_t *msgi = (rmc_comm_msg_t *)dmi->intr_arg; 1104 1105 DPRINTF(rcs, DPRO, (CE_CONT, 1106 "mrecv process async msg len=%d, max=%d\n", 1107 datalen, msgi->msg_len)); 1108 /* 1109 * process asynchronous notification only if the registered 1110 * driver is not currently processing any other notification 1111 */ 1112 mutex_enter(dmi->intr_lock); 1113 if (dmi->intr_state == NULL || 1114 (dmi->intr_state != NULL && 1115 *(dmi->intr_state) == RMC_COMM_INTR_IDLE)) { 1116 /* 1117 * check that the buffer is big enough. do not want to 1118 * cross boundaries here.. 1119 */ 1120 if (datalen <= msgi->msg_len) { 1121 bcopy(datap, msgi->msg_buf, datalen); 1122 msgi->msg_bytes = datalen; 1123 1124 } else { 1125 msgi->msg_bytes = -1; 1126 } 1127 /* 1128 * trigger soft intr. in any case. 1129 * if message is too big, at least, the leaf driver 1130 * will be notified (bytes returned will be -1) 1131 */ 1132 ddi_trigger_softintr(dmi->intr_id); 1133 } 1134 mutex_exit(dmi->intr_lock); 1135 1136 } else if ((drr->flags & MSG_SENT) != 0 && 1137 drr->response.msg_type == dp_msgp->type) { 1138 1139 DPRINTF(rcs, DPRO, (CE_CONT, 1140 "mrecv process reply len=%d, max=%d\n", 1141 datalen, drr->response.msg_bufsiz)); 1142 1143 /* 1144 * check that the recv buffer is big enough. 1145 */ 1146 if (datalen <= drr->response.msg_bufsiz) { 1147 bcopy(datap, drr->response.msg_buf, datalen); 1148 drr->response.msg_msglen = datalen; 1149 dp_wake_up_waiter(rcs, MSG_REPLY_RXED); 1150 } else { 1151 drr->response.msg_msglen = -1; 1152 dp_wake_up_waiter(rcs, MSG_REPLY_RXED); 1153 } 1154 } else if (dp_msgp->type == DP_INVCMD && 1155 (drr->flags & MSG_SENT) != 0 && 1156 ((dp_invcmd_t *)datap)->inv_type == drr->request.msg_type) { 1157 drr->error_status = RCEINVCMD; 1158 dp_wake_up_waiter(rcs, MSG_ERROR); 1159 } 1160 } 1161 1162 /* 1163 * to send a control message (unnumbered message) 1164 * (it must have the dp_mutex) 1165 */ 1166 int 1167 rmc_comm_dp_ctlsend(struct rmc_comm_state *rcs, uint8_t type) 1168 { 1169 dp_message_t ctlmsg; 1170 int err = RCNOERR; 1171 1172 ctlmsg.msg_type = type; 1173 ctlmsg.msg_buf = NULL; 1174 ctlmsg.msg_msglen = 0; 1175 1176 err = rmc_comm_dp_msend(rcs, &ctlmsg); 1177 1178 return (err); 1179 } 1180 1181 /* 1182 * to send data to the remote party. 1183 * 1184 * NUMBERED messages carry payload data of variable size. A buffer is allocated 1185 * dynamically for the trasmission of data. NUMBERED message trasmission 1186 * data status is stored in the dp_state request_response data structure. 1187 * This because: data sent must be acknowledged, trasmission can be re-tried, 1188 * upper layer has to know the state/result of the trasmission. Upper layer has 1189 * to: initialize the data struct, send data (this function), read result, 1190 * clean up the data struct. 1191 * 1192 * UNUMBERED data are just only control command which do not carry any payload 1193 * A local buffer is used (ctlbuf) instead. UNNUMBERED message are transient 1194 * data which is sent once and not re-tried. It does not use the 1195 * request_response data structure 1196 * 1197 * (it must have the dp_mutex) 1198 */ 1199 int 1200 rmc_comm_dp_msend(struct rmc_comm_state *rcs, dp_message_t *req) 1201 { 1202 rmc_comm_dp_state_t *dps = &rcs->dp_state; 1203 dp_req_resp_t *drr = &dps->req_resp; 1204 dp_message_t *pkt; 1205 dp_header_t *dp_msgp; 1206 dp_message_t ctl; 1207 dp_header_t ctlbuf; 1208 uint16_t data_crc; 1209 timeout_id_t timer_delay_ack = 0; 1210 char first_time = 0; 1211 1212 ASSERT(MUTEX_HELD(dps->dp_mutex)); 1213 1214 DPRINTF(rcs, DPRO, (CE_CONT, "msend msgtype=%02x\n", req->msg_type)); 1215 1216 if (IS_NUMBERED_MSG(req->msg_type)) { 1217 /* 1218 * if there was an error, just return the error. 1219 * Otherwise if the message was already acknowledged 1220 * (NUMBERED message) then, there is no need to (re)send it. 1221 * just wait for an expected reply (hence, do not return an 1222 * error) 1223 */ 1224 if ((drr->flags & MSG_ERROR) != 0) { 1225 1226 DPRINTF(rcs, DPRO, (CE_CONT, 1227 "msg send error flag=%02x\n", drr->flags)); 1228 return (RCEGENERIC); 1229 1230 } else if ((drr->flags & MSG_ACKED) != 0) { 1231 1232 DPRINTF(rcs, DPRO, (CE_CONT, 1233 "msg already ACKed flag=%02x\n", drr->flags)); 1234 return (RCNOERR); 1235 1236 } else if ((drr->flags & MSG_SENT) == 0) { 1237 1238 first_time = 1; 1239 } 1240 1241 /* 1242 * everything is ok. Now check that the data protocol is up 1243 * and running: messages cannot be sent if the link is down. 1244 */ 1245 if (!dps->data_link_ok) { 1246 DPRINTF(rcs, DPRO, (CE_CONT, 1247 "msend: can't send msg - no data link\n")); 1248 1249 /* 1250 * do not return error, since it can be retried 1251 * later (hoping that the data link will come 1252 * up, in the meantime) 1253 */ 1254 return (RCNOERR); 1255 1256 } 1257 } else { 1258 first_time = 1; 1259 } 1260 1261 /* 1262 * if the message has never been sent (and, hence, it is the first 1263 * time), then prepare the protocol packet: allocate a buffer, 1264 * create the message header, copy the message body into the buffer and 1265 * calculate CRCs 1266 */ 1267 if (first_time) { 1268 1269 if (IS_NUMBERED_MSG(req->msg_type)) { 1270 1271 drr->retries_left = TX_RETRIES; 1272 1273 /* 1274 * Check length of the message. 1275 */ 1276 if (req->msg_msglen > DP_MAX_MSGLEN) { 1277 DPRINTF(rcs, DPRO, 1278 (CE_CONT, "msend err: msg too big\n")); 1279 return (RCEGENERIC); 1280 } 1281 1282 pkt = &drr->request; 1283 1284 /* 1285 * check that the message buffer is not already 1286 * in use (race condition). If so, return error 1287 */ 1288 if (pkt->msg_buf != NULL) { 1289 DPRINTF(rcs, DPRO, (CE_CONT, 1290 "msend err: buf already in use\n")); 1291 return (RCENOMEM); 1292 } 1293 1294 /* 1295 * allocate a buffer for the protocol packet 1296 */ 1297 if ((pkt->msg_buf = dp_get_buffer(rcs, 1298 DP_TX_BUFFER)) == NULL) { 1299 DPRINTF(rcs, DPRO, (CE_CONT, 1300 "msend err: no mem\n")); 1301 return (RCENOMEM); 1302 } 1303 pkt->msg_bufsiz = DP_BUFFER_SIZE; 1304 1305 /* 1306 * increment tx sequence number if sending a NUMBERED 1307 * message 1308 */ 1309 dps->last_tx_seqid = NEXT_SEQID(dps->last_tx_seqid); 1310 } else { 1311 /* 1312 * UNUMBERED messages (or control messages) do not 1313 * carry any data and, hence, have a 'small' fixed size 1314 * (the size of the header). In this case, 1315 * a 'local' buffer (ctlbuf) is used. 1316 */ 1317 pkt = &ctl; 1318 pkt->msg_buf = (uint8_t *)&ctlbuf; 1319 pkt->msg_bufsiz = sizeof (dp_header_t); 1320 } 1321 1322 #ifdef DEBUG_ERROR_INJECTION 1323 1324 if (((erri_test_number == ERRI_RX_SEQ_NUMBER && 1325 IS_NUMBERED_MSG(req->msg_type)) || 1326 (erri_test_number == ERRI_CTL_RX_SEQ_NUMBER && 1327 IS_UNNUMBERED_MSG(req->msg_type))) && 1328 erri_test_repeat >= 0 && 1329 erri_test_count++ > 0 && 1330 !(erri_test_count % erri_test_intrvl)) { 1331 1332 dps->last_rx_seqid--; 1333 1334 if (erri_test_repeat == 0) 1335 erri_test_repeat--; /* will not repeat it */ 1336 } 1337 #endif 1338 1339 /* 1340 * create the protocol packet 1341 */ 1342 pkt->msg_type = req->msg_type; 1343 1344 /* 1345 * length of the packet (including pad bytes) 1346 */ 1347 pkt->msg_msglen = req->msg_msglen + sizeof (dp_header_t); 1348 1349 /* 1350 * message header: 1351 * set the message type 1352 * set the length of the message (excluding pad bytes) 1353 * set tx/rx sequence numbers 1354 * calculate CRC 1355 */ 1356 dp_msgp = (dp_header_t *)pkt->msg_buf; 1357 dp_msgp->type = pkt->msg_type; 1358 1359 if (req->msg_msglen == 0) 1360 dp_msgp->length = pkt->msg_msglen - 1361 sizeof (dp_msgp->pad); 1362 else 1363 dp_msgp->length = sizeof (data_crc) + 1364 pkt->msg_msglen - sizeof (dp_msgp->pad); 1365 1366 dp_msgp->txnum = dps->last_tx_seqid; 1367 dp_msgp->rxnum = dps->last_rx_seqid; 1368 1369 dp_msgp->crc = dp_calc_crc16(pkt->msg_buf + 1370 sizeof (dp_msgp->pad), sizeof (dp_header_t) - 1371 sizeof (dp_msgp->crc) - sizeof (dp_msgp->pad)); 1372 1373 #ifdef DEBUG_ERROR_INJECTION 1374 1375 if (((erri_test_number == ERRI_CRC_HEADER && 1376 IS_NUMBERED_MSG(pkt->msg_type)) || 1377 (erri_test_number == ERRI_CTL_CRC_HEADER && 1378 IS_UNNUMBERED_MSG(pkt->msg_type))) && 1379 erri_test_repeat >= 0 && 1380 erri_test_count++ > 0 && 1381 !(erri_test_count % erri_test_intrvl)) { 1382 1383 dp_msgp->crc = dp_msgp->crc/2; 1384 if (erri_test_repeat == 0) 1385 erri_test_repeat--; /* will not repeat it */ 1386 } 1387 #endif 1388 1389 /* 1390 * copy message body (if present) into the buffer 1391 * and calculate message CRC 1392 */ 1393 if (req->msg_msglen > 0) { 1394 bcopy(req->msg_buf, pkt->msg_buf + sizeof (dp_header_t), 1395 req->msg_msglen); 1396 data_crc = dp_calc_crc16(pkt->msg_buf + 1397 sizeof (dp_header_t), 1398 req->msg_msglen); 1399 1400 #ifdef DEBUG_ERROR_INJECTION 1401 1402 if (erri_test_number == ERRI_CRC_MSG && 1403 erri_test_repeat >= 0 && 1404 erri_test_count++ > 0 && 1405 !(erri_test_count % erri_test_intrvl)) { 1406 1407 data_crc = data_crc/2; 1408 if (erri_test_repeat == 0) 1409 erri_test_repeat--; 1410 } 1411 #endif 1412 bcopy((void *) &data_crc, 1413 pkt->msg_buf + (sizeof (dp_header_t) + 1414 req->msg_msglen), 1415 sizeof (data_crc)); 1416 } 1417 } else { 1418 /* 1419 * message has already been sent (and packetized). 1420 * get the message packet from the request/response 1421 * data structure 1422 */ 1423 pkt = &drr->request; 1424 dp_msgp = (dp_header_t *)pkt->msg_buf; 1425 dps->retries_cnt++; 1426 } 1427 1428 /* 1429 * NUMBERED messages 1430 */ 1431 if (IS_NUMBERED_MSG(pkt->msg_type)) { 1432 1433 /* 1434 * check that we have not exceeded the maximum number of 1435 * retries 1436 */ 1437 if (drr->retries_left-- <= 0) { 1438 1439 drr->flags |= MSG_ERROR; /* set error flag */ 1440 1441 /* 1442 * restart the data protocol link 1443 */ 1444 dp_reset(rcs, INITIAL_SEQID, 0, 1); 1445 1446 return (RCEMAXRETRIES); 1447 } 1448 1449 if (dps->timer_delay_ack != (timeout_id_t)0) { 1450 /* 1451 * Cancel any pending acknowledgements - we're 1452 * going to send a message which will include 1453 * an acknowledgement. 1454 */ 1455 timer_delay_ack = dps->timer_delay_ack; 1456 1457 /* 1458 * the timer is actually removed at the end of this 1459 * function since I need to release the dp_mutex. 1460 * Instead I clear the timer variable so that the 1461 * timeout callback will not do any processing in the 1462 * meantime. 1463 */ 1464 dps->timer_delay_ack = 0; 1465 } 1466 1467 drr->flags |= MSG_SENT; 1468 } 1469 1470 /* 1471 * set rx sequence number (as we might have received a message in the 1472 * meantime). tx sequence number to be the same (we can only send one 1473 * message per time) 1474 */ 1475 if (dp_msgp->rxnum != dps->last_rx_seqid) { 1476 1477 dp_msgp->rxnum = dps->last_rx_seqid; 1478 1479 /* 1480 * re-calculate CRC (header) 1481 */ 1482 dp_msgp->crc = dp_calc_crc16(pkt->msg_buf + 1483 sizeof (dp_msgp->pad), sizeof (dp_header_t) - 1484 sizeof (dp_msgp->crc) - sizeof (dp_msgp->pad)); 1485 } 1486 1487 DPRINTF(rcs, DPRO, (CE_CONT, "[t%03dr%03d] msend msgtype=%02x\n", 1488 dp_msgp->txnum, dp_msgp->rxnum, dp_msgp->type)); 1489 1490 /* 1491 * send this message 1492 */ 1493 1494 dp_send_packet(rcs, pkt->msg_buf); 1495 1496 /* 1497 * remove delay ack timer (if any is running) 1498 * Note that the dp_mutex must be released before calling 1499 * untimeout. Otherwise we may have a deadlock situation. 1500 */ 1501 if (timer_delay_ack != 0) { 1502 DPRINTF(rcs, DGEN, (CE_CONT, "msend remove ack timer %p\n", 1503 timer_delay_ack)); 1504 mutex_exit(dps->dp_mutex); 1505 (void) untimeout(timer_delay_ack); 1506 mutex_enter(dps->dp_mutex); 1507 } 1508 1509 return (RCNOERR); 1510 } 1511 1512 /* 1513 * to send a boot protocol message 1514 * (this is to support the firmware download feature) 1515 */ 1516 void 1517 rmc_comm_bp_msend(struct rmc_comm_state *rcs, bp_msg_t *bp_msg) 1518 { 1519 char syncbuf[2]; 1520 1521 ASSERT(MUTEX_HELD(rcs->dp_state.dp_mutex)); 1522 1523 DPRINTF(rcs, DPRO, (CE_CONT, "send bp msg: %02x %02x %02x\n", 1524 bp_msg->cmd, bp_msg->dat1, bp_msg->dat2)); 1525 1526 rcs->dp_state.req_resp.flags |= MSG_SENT_BP; 1527 1528 /* First, send out two SYNC characters. */ 1529 syncbuf[0] = syncbuf[1] = SYNC_CHAR; 1530 rmc_comm_serdev_send(rcs, (char *)syncbuf, 2); 1531 1532 /* Next, send the BP message. */ 1533 rmc_comm_serdev_send(rcs, (char *)&bp_msg->cmd, 1534 sizeof (bp_msg_t) - sizeof (bp_msg->pad)); 1535 } 1536 1537 /* 1538 * to send a fw s-record 1539 * (this is to support the firmware download feature) 1540 */ 1541 void 1542 rmc_comm_bp_srecsend(struct rmc_comm_state *rcs, char *buf, int buflen) 1543 { 1544 ASSERT(MUTEX_HELD(rcs->dp_state.dp_mutex)); 1545 1546 rcs->dp_state.req_resp.flags |= MSG_SENT_BP; 1547 1548 rmc_comm_serdev_send(rcs, buf, buflen); 1549 } 1550 1551 /* 1552 * clean up a request/response session 1553 * (it must have the dp_mutex) 1554 */ 1555 1556 void 1557 rmc_comm_dp_mcleanup(struct rmc_comm_state *rcs) 1558 { 1559 rmc_comm_dp_state_t *dps = &rcs->dp_state; 1560 dp_req_resp_t *drr = &dps->req_resp; 1561 dp_message_t *req = &drr->request; 1562 dp_message_t *resp = &drr->response; 1563 1564 ASSERT(MUTEX_HELD(dps->dp_mutex)); 1565 1566 DPRINTF(rcs, DGEN, (CE_CONT, "msg cleanup\n")); 1567 1568 /* 1569 * 'release' memory 1570 * memory is only 'dynamically allocated for NUMBERED messages 1571 */ 1572 if (req->msg_buf != NULL) 1573 dp_release_buffer(rcs, DP_TX_BUFFER); 1574 1575 drr->flags = 0; 1576 drr->error_status = 0; 1577 1578 req->msg_type = DP_NULL_MSG; 1579 req->msg_buf = NULL; 1580 req->msg_msglen = 0; 1581 req->msg_bufsiz = 0; 1582 resp->msg_type = DP_NULL_MSG; 1583 resp->msg_buf = NULL; 1584 resp->msg_msglen = 0; 1585 resp->msg_bufsiz = 0; 1586 } 1587