Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fjes: buffer address regist/unregistration routine

This patch adds buffer address regist/unregistration routine.

This function is mainly invoked when network device's
activation (open) and deactivation (close)
in order to retist/unregist shared buffer address.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Taku Izumi and committed by
David S. Miller
7950e6c5 3bb025d4

+194 -1
+186
drivers/net/fjes/fjes_hw.c
··· 452 452 return result; 453 453 } 454 454 455 + int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid, 456 + struct ep_share_mem_info *buf_pair) 457 + { 458 + union fjes_device_command_req *req_buf = hw->hw_info.req_buf; 459 + union fjes_device_command_res *res_buf = hw->hw_info.res_buf; 460 + enum fjes_dev_command_response_e ret; 461 + int page_count; 462 + int timeout; 463 + int i, idx; 464 + void *addr; 465 + int result; 466 + 467 + if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit)) 468 + return 0; 469 + 470 + memset(req_buf, 0, hw->hw_info.req_buf_size); 471 + memset(res_buf, 0, hw->hw_info.res_buf_size); 472 + 473 + req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN( 474 + buf_pair->tx.size, 475 + buf_pair->rx.size); 476 + req_buf->share_buffer.epid = dest_epid; 477 + 478 + idx = 0; 479 + req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size; 480 + page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE; 481 + for (i = 0; i < page_count; i++) { 482 + addr = ((u8 *)(buf_pair->tx.buffer)) + 483 + (i * EP_BUFFER_INFO_SIZE); 484 + req_buf->share_buffer.buffer[idx++] = 485 + (__le64)(page_to_phys(vmalloc_to_page(addr)) + 486 + offset_in_page(addr)); 487 + } 488 + 489 + req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size; 490 + page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE; 491 + for (i = 0; i < page_count; i++) { 492 + addr = ((u8 *)(buf_pair->rx.buffer)) + 493 + (i * EP_BUFFER_INFO_SIZE); 494 + req_buf->share_buffer.buffer[idx++] = 495 + (__le64)(page_to_phys(vmalloc_to_page(addr)) + 496 + offset_in_page(addr)); 497 + } 498 + 499 + res_buf->share_buffer.length = 0; 500 + res_buf->share_buffer.code = 0; 501 + 502 + ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER); 503 + 504 + timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000; 505 + while ((ret == FJES_CMD_STATUS_NORMAL) && 506 + (res_buf->share_buffer.length == 507 + FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) && 508 + (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) && 509 + (timeout > 0)) { 510 + msleep(200 + hw->my_epid * 20); 511 + timeout -= (200 + hw->my_epid * 20); 512 + 513 + res_buf->share_buffer.length = 0; 514 + res_buf->share_buffer.code = 0; 515 + 516 + ret = fjes_hw_issue_request_command( 517 + hw, FJES_CMD_REQ_SHARE_BUFFER); 518 + } 519 + 520 + result = 0; 521 + 522 + if (res_buf->share_buffer.length != 523 + FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) 524 + result = -ENOMSG; 525 + else if (ret == FJES_CMD_STATUS_NORMAL) { 526 + switch (res_buf->share_buffer.code) { 527 + case FJES_CMD_REQ_RES_CODE_NORMAL: 528 + result = 0; 529 + set_bit(dest_epid, &hw->hw_info.buffer_share_bit); 530 + break; 531 + case FJES_CMD_REQ_RES_CODE_BUSY: 532 + result = -EBUSY; 533 + break; 534 + default: 535 + result = -EPERM; 536 + break; 537 + } 538 + } else { 539 + switch (ret) { 540 + case FJES_CMD_STATUS_UNKNOWN: 541 + result = -EPERM; 542 + break; 543 + case FJES_CMD_STATUS_TIMEOUT: 544 + result = -EBUSY; 545 + break; 546 + case FJES_CMD_STATUS_ERROR_PARAM: 547 + case FJES_CMD_STATUS_ERROR_STATUS: 548 + default: 549 + result = -EPERM; 550 + break; 551 + } 552 + } 553 + 554 + return result; 555 + } 556 + 557 + int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid) 558 + { 559 + union fjes_device_command_req *req_buf = hw->hw_info.req_buf; 560 + union fjes_device_command_res *res_buf = hw->hw_info.res_buf; 561 + struct fjes_device_shared_info *share = hw->hw_info.share; 562 + enum fjes_dev_command_response_e ret; 563 + int timeout; 564 + int result; 565 + 566 + if (!hw->base) 567 + return -EPERM; 568 + 569 + if (!req_buf || !res_buf || !share) 570 + return -EPERM; 571 + 572 + if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit)) 573 + return 0; 574 + 575 + memset(req_buf, 0, hw->hw_info.req_buf_size); 576 + memset(res_buf, 0, hw->hw_info.res_buf_size); 577 + 578 + req_buf->unshare_buffer.length = 579 + FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN; 580 + req_buf->unshare_buffer.epid = dest_epid; 581 + 582 + res_buf->unshare_buffer.length = 0; 583 + res_buf->unshare_buffer.code = 0; 584 + 585 + ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER); 586 + 587 + timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000; 588 + while ((ret == FJES_CMD_STATUS_NORMAL) && 589 + (res_buf->unshare_buffer.length == 590 + FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) && 591 + (res_buf->unshare_buffer.code == 592 + FJES_CMD_REQ_RES_CODE_BUSY) && 593 + (timeout > 0)) { 594 + msleep(200 + hw->my_epid * 20); 595 + timeout -= (200 + hw->my_epid * 20); 596 + 597 + res_buf->unshare_buffer.length = 0; 598 + res_buf->unshare_buffer.code = 0; 599 + 600 + ret = 601 + fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER); 602 + } 603 + 604 + result = 0; 605 + 606 + if (res_buf->unshare_buffer.length != 607 + FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) { 608 + result = -ENOMSG; 609 + } else if (ret == FJES_CMD_STATUS_NORMAL) { 610 + switch (res_buf->unshare_buffer.code) { 611 + case FJES_CMD_REQ_RES_CODE_NORMAL: 612 + result = 0; 613 + clear_bit(dest_epid, &hw->hw_info.buffer_share_bit); 614 + break; 615 + case FJES_CMD_REQ_RES_CODE_BUSY: 616 + result = -EBUSY; 617 + break; 618 + default: 619 + result = -EPERM; 620 + break; 621 + } 622 + } else { 623 + switch (ret) { 624 + case FJES_CMD_STATUS_UNKNOWN: 625 + result = -EPERM; 626 + break; 627 + case FJES_CMD_STATUS_TIMEOUT: 628 + result = -EBUSY; 629 + break; 630 + case FJES_CMD_STATUS_ERROR_PARAM: 631 + case FJES_CMD_STATUS_ERROR_STATUS: 632 + default: 633 + result = -EPERM; 634 + break; 635 + } 636 + } 637 + 638 + return result; 639 + } 640 + 455 641 void fjes_hw_set_irqmask(struct fjes_hw *hw, 456 642 enum REG_ICTL_MASK intr_mask, bool mask) 457 643 {
+8 -1
drivers/net/fjes/fjes_hw.h
··· 35 35 36 36 #define FJES_DEVICE_RESET_TIMEOUT ((17 + 1) * 3) /* sec */ 37 37 #define FJES_COMMAND_REQ_TIMEOUT (5 + 1) /* sec */ 38 + #define FJES_COMMAND_REQ_BUFF_TIMEOUT (8 * 3) /* sec */ 38 39 39 40 #define FJES_CMD_REQ_ERR_INFO_PARAM (0x0001) 40 41 #define FJES_CMD_REQ_ERR_INFO_STATUS (0x0002) 41 42 42 43 #define FJES_CMD_REQ_RES_CODE_NORMAL (0) 44 + #define FJES_CMD_REQ_RES_CODE_BUSY (1) 43 45 44 46 #define EP_BUFFER_SIZE \ 45 47 (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ ··· 62 60 #define FJES_DEV_COMMAND_INFO_RES_LEN(epnum) (8 + 2 * (epnum)) 63 61 #define FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(txb, rxb) \ 64 62 (24 + (8 * ((txb) / EP_BUFFER_INFO_SIZE + (rxb) / EP_BUFFER_INFO_SIZE))) 63 + #define FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN (8) 64 + #define FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN (8) 65 + #define FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN (8) 65 66 66 67 #define FJES_DEV_REQ_BUF_SIZE(maxep) \ 67 68 FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(EP_BUFFER_SIZE, EP_BUFFER_SIZE) ··· 272 267 void fjes_hw_exit(struct fjes_hw *); 273 268 int fjes_hw_reset(struct fjes_hw *); 274 269 int fjes_hw_request_info(struct fjes_hw *); 275 - 270 + int fjes_hw_register_buff_addr(struct fjes_hw *, int, 271 + struct ep_share_mem_info *); 272 + int fjes_hw_unregister_buff_addr(struct fjes_hw *, int); 276 273 void fjes_hw_init_command_registers(struct fjes_hw *, 277 274 struct fjes_device_command_param *); 278 275 void fjes_hw_setup_epbuf(struct epbuf_handler *, u8 *, u32);