Changes in uspace/lib/drv/generic/remote_nic.c [acdb5bac:f9b2cb4c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_nic.c
racdb5bac rf9b2cb4c 40 40 #include <ipc/services.h> 41 41 #include <sys/time.h> 42 #include <macros.h> 43 42 44 #include "ops/nic.h" 45 #include "nic_iface.h" 46 47 typedef enum { 48 NIC_SEND_MESSAGE = 0, 49 NIC_CALLBACK_CREATE, 50 NIC_GET_STATE, 51 NIC_SET_STATE, 52 NIC_GET_ADDRESS, 53 NIC_SET_ADDRESS, 54 NIC_GET_STATS, 55 NIC_GET_DEVICE_INFO, 56 NIC_GET_CABLE_STATE, 57 NIC_GET_OPERATION_MODE, 58 NIC_SET_OPERATION_MODE, 59 NIC_AUTONEG_ENABLE, 60 NIC_AUTONEG_DISABLE, 61 NIC_AUTONEG_PROBE, 62 NIC_AUTONEG_RESTART, 63 NIC_GET_PAUSE, 64 NIC_SET_PAUSE, 65 NIC_UNICAST_GET_MODE, 66 NIC_UNICAST_SET_MODE, 67 NIC_MULTICAST_GET_MODE, 68 NIC_MULTICAST_SET_MODE, 69 NIC_BROADCAST_GET_MODE, 70 NIC_BROADCAST_SET_MODE, 71 NIC_DEFECTIVE_GET_MODE, 72 NIC_DEFECTIVE_SET_MODE, 73 NIC_BLOCKED_SOURCES_GET, 74 NIC_BLOCKED_SOURCES_SET, 75 NIC_VLAN_GET_MASK, 76 NIC_VLAN_SET_MASK, 77 NIC_VLAN_SET_TAG, 78 NIC_WOL_VIRTUE_ADD, 79 NIC_WOL_VIRTUE_REMOVE, 80 NIC_WOL_VIRTUE_PROBE, 81 NIC_WOL_VIRTUE_LIST, 82 NIC_WOL_VIRTUE_GET_CAPS, 83 NIC_WOL_LOAD_INFO, 84 NIC_OFFLOAD_PROBE, 85 NIC_OFFLOAD_SET, 86 NIC_POLL_GET_MODE, 87 NIC_POLL_SET_MODE, 88 NIC_POLL_NOW 89 } nic_funcs_t; 90 91 /** Send frame from NIC 92 * 93 * @param[in] dev_sess 94 * @param[in] data Frame data 95 * @param[in] size Frame size in bytes 96 * 97 * @return EOK If the operation was successfully completed 98 * 99 */ 100 int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size) 101 { 102 async_exch_t *exch = async_exchange_begin(dev_sess); 103 104 ipc_call_t answer; 105 aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 106 NIC_SEND_MESSAGE, &answer); 107 sysarg_t retval = async_data_write_start(exch, data, size); 108 109 async_exchange_end(exch); 110 111 if (retval != EOK) { 112 async_forget(req); 113 return retval; 114 } 115 116 async_wait_for(req, &retval); 117 return retval; 118 } 119 120 /** Create callback connection from NIC service 121 * 122 * @param[in] dev_sess 123 * @param[in] device_id 124 * 125 * @return EOK If the operation was successfully completed 126 * 127 */ 128 int nic_callback_create(async_sess_t *dev_sess, async_port_handler_t cfun, 129 void *carg) 130 { 131 ipc_call_t answer; 132 int rc; 133 sysarg_t retval; 134 135 async_exch_t *exch = async_exchange_begin(dev_sess); 136 aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 137 NIC_CALLBACK_CREATE, &answer); 138 139 port_id_t port; 140 rc = async_create_callback_port(exch, INTERFACE_NIC_CB, 0, 0, 141 cfun, carg, &port); 142 if (rc != EOK) { 143 async_forget(req); 144 return rc; 145 } 146 async_exchange_end(exch); 147 148 async_wait_for(req, &retval); 149 return (int) retval; 150 } 151 152 /** Get the current state of the device 153 * 154 * @param[in] dev_sess 155 * @param[out] state Current state 156 * 157 * @return EOK If the operation was successfully completed 158 * 159 */ 160 int nic_get_state(async_sess_t *dev_sess, nic_device_state_t *state) 161 { 162 assert(state); 163 164 sysarg_t _state; 165 166 async_exch_t *exch = async_exchange_begin(dev_sess); 167 int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 168 NIC_GET_STATE, &_state); 169 async_exchange_end(exch); 170 171 *state = (nic_device_state_t) _state; 172 173 return rc; 174 } 175 176 /** Request the device to change its state 177 * 178 * @param[in] dev_sess 179 * @param[in] state New state 180 * 181 * @return EOK If the operation was successfully completed 182 * 183 */ 184 int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state) 185 { 186 async_exch_t *exch = async_exchange_begin(dev_sess); 187 int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 188 NIC_SET_STATE, state); 189 async_exchange_end(exch); 190 191 return rc; 192 } 193 194 /** Request the MAC address of the device 195 * 196 * @param[in] dev_sess 197 * @param[out] address Structure with buffer for the address 198 * 199 * @return EOK If the operation was successfully completed 200 * 201 */ 202 int nic_get_address(async_sess_t *dev_sess, nic_address_t *address) 203 { 204 assert(address); 205 206 async_exch_t *exch = async_exchange_begin(dev_sess); 207 aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 208 NIC_GET_ADDRESS, NULL); 209 int rc = async_data_read_start(exch, address, sizeof(nic_address_t)); 210 async_exchange_end(exch); 211 212 sysarg_t res; 213 async_wait_for(aid, &res); 214 215 if (rc != EOK) 216 return rc; 217 218 return (int) res; 219 } 220 221 /** Set the address of the device (e.g. MAC on Ethernet) 222 * 223 * @param[in] dev_sess 224 * @param[in] address Pointer to the address 225 * 226 * @return EOK If the operation was successfully completed 227 * 228 */ 229 int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address) 230 { 231 assert(address); 232 233 async_exch_t *exch = async_exchange_begin(dev_sess); 234 aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 235 NIC_SET_ADDRESS, NULL); 236 int rc = async_data_write_start(exch, address, sizeof(nic_address_t)); 237 async_exchange_end(exch); 238 239 sysarg_t res; 240 async_wait_for(aid, &res); 241 242 if (rc != EOK) 243 return rc; 244 245 return (int) res; 246 } 247 248 /** Request statistic data about NIC operation. 249 * 250 * @param[in] dev_sess 251 * @param[out] stats Structure with the statistics 252 * 253 * @return EOK If the operation was successfully completed 254 * 255 */ 256 int nic_get_stats(async_sess_t *dev_sess, nic_device_stats_t *stats) 257 { 258 assert(stats); 259 260 async_exch_t *exch = async_exchange_begin(dev_sess); 261 262 int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 263 NIC_GET_STATS); 264 if (rc != EOK) { 265 async_exchange_end(exch); 266 return rc; 267 } 268 269 rc = async_data_read_start(exch, stats, sizeof(nic_device_stats_t)); 270 271 async_exchange_end(exch); 272 273 return rc; 274 } 275 276 /** Request information about the device. 277 * 278 * @see nic_device_info_t 279 * 280 * @param[in] dev_sess 281 * @param[out] device_info Information about the device 282 * 283 * @return EOK If the operation was successfully completed 284 * 285 */ 286 int nic_get_device_info(async_sess_t *dev_sess, nic_device_info_t *device_info) 287 { 288 assert(device_info); 289 290 async_exch_t *exch = async_exchange_begin(dev_sess); 291 292 aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 293 NIC_GET_DEVICE_INFO, NULL); 294 int rc = async_data_read_start(exch, device_info, sizeof(nic_device_info_t)); 295 async_exchange_end(exch); 296 297 sysarg_t res; 298 async_wait_for(aid, &res); 299 300 if (rc != EOK) 301 return rc; 302 303 return (int) res; 304 } 305 306 /** Request status of the cable (plugged/unplugged) 307 * 308 * @param[in] dev_sess 309 * @param[out] cable_state Current cable state 310 * 311 * @return EOK If the operation was successfully completed 312 * 313 */ 314 int nic_get_cable_state(async_sess_t *dev_sess, nic_cable_state_t *cable_state) 315 { 316 assert(cable_state); 317 318 sysarg_t _cable_state; 319 320 async_exch_t *exch = async_exchange_begin(dev_sess); 321 int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 322 NIC_GET_CABLE_STATE, &_cable_state); 323 async_exchange_end(exch); 324 325 *cable_state = (nic_cable_state_t) _cable_state; 326 327 return rc; 328 } 329 330 /** Request current operation mode. 331 * 332 * @param[in] dev_sess 333 * @param[out] speed Current operation speed in Mbps. Can be NULL. 334 * @param[out] duplex Full duplex/half duplex. Can be NULL. 335 * @param[out] role Master/slave/auto. Can be NULL. 336 * 337 * @return EOK If the operation was successfully completed 338 * 339 */ 340 int nic_get_operation_mode(async_sess_t *dev_sess, int *speed, 341 nic_channel_mode_t *duplex, nic_role_t *role) 342 { 343 sysarg_t _speed; 344 sysarg_t _duplex; 345 sysarg_t _role; 346 347 async_exch_t *exch = async_exchange_begin(dev_sess); 348 int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 349 NIC_GET_OPERATION_MODE, &_speed, &_duplex, &_role); 350 async_exchange_end(exch); 351 352 if (speed) 353 *speed = (int) _speed; 354 355 if (duplex) 356 *duplex = (nic_channel_mode_t) _duplex; 357 358 if (role) 359 *role = (nic_role_t) _role; 360 361 return rc; 362 } 363 364 /** Set current operation mode. 365 * 366 * If the NIC has auto-negotiation enabled, this command 367 * disables auto-negotiation and sets the operation mode. 368 * 369 * @param[in] dev_sess 370 * @param[in] speed Operation speed in Mbps 371 * @param[in] duplex Full duplex/half duplex 372 * @param[in] role Master/slave/auto (e.g. in Gbit Ethernet] 373 * 374 * @return EOK If the operation was successfully completed 375 * 376 */ 377 int nic_set_operation_mode(async_sess_t *dev_sess, int speed, 378 nic_channel_mode_t duplex, nic_role_t role) 379 { 380 async_exch_t *exch = async_exchange_begin(dev_sess); 381 int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 382 NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex, 383 (sysarg_t) role); 384 async_exchange_end(exch); 385 386 return rc; 387 } 388 389 /** Enable auto-negotiation. 390 * 391 * The advertisement argument can only limit some modes, 392 * it can never force the NIC to advertise unsupported modes. 393 * 394 * The allowed modes are defined in "nic/eth_phys.h" in the C library. 395 * 396 * @param[in] dev_sess 397 * @param[in] advertisement Allowed advertised modes. Use 0 for all modes. 398 * 399 * @return EOK If the operation was successfully completed 400 * 401 */ 402 int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement) 403 { 404 async_exch_t *exch = async_exchange_begin(dev_sess); 405 int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 406 NIC_AUTONEG_ENABLE, (sysarg_t) advertisement); 407 async_exchange_end(exch); 408 409 return rc; 410 } 411 412 /** Disable auto-negotiation. 413 * 414 * @param[in] dev_sess 415 * 416 * @return EOK If the operation was successfully completed 417 * 418 */ 419 int nic_autoneg_disable(async_sess_t *dev_sess) 420 { 421 async_exch_t *exch = async_exchange_begin(dev_sess); 422 int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 423 NIC_AUTONEG_DISABLE); 424 async_exchange_end(exch); 425 426 return rc; 427 } 428 429 /** Probe current state of auto-negotiation. 430 * 431 * Modes are defined in the "nic/eth_phys.h" in the C library. 432 * 433 * @param[in] dev_sess 434 * @param[out] our_advertisement Modes advertised by this NIC. 435 * Can be NULL. 436 * @param[out] their_advertisement Modes advertised by the other side. 437 * Can be NULL. 438 * @param[out] result General state of auto-negotiation. 439 * Can be NULL. 440 * @param[out] their_result State of other side auto-negotiation. 441 * Can be NULL. 442 * 443 * @return EOK If the operation was successfully completed 444 * 445 */ 446 int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement, 447 uint32_t *their_advertisement, nic_result_t *result, 448 nic_result_t *their_result) 449 { 450 sysarg_t _our_advertisement; 451 sysarg_t _their_advertisement; 452 sysarg_t _result; 453 sysarg_t _their_result; 454 455 async_exch_t *exch = async_exchange_begin(dev_sess); 456 int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 457 NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement, 458 &_result, &_their_result); 459 async_exchange_end(exch); 460 461 if (our_advertisement) 462 *our_advertisement = (uint32_t) _our_advertisement; 463 464 if (*their_advertisement) 465 *their_advertisement = (uint32_t) _their_advertisement; 466 467 if (result) 468 *result = (nic_result_t) _result; 469 470 if (their_result) 471 *their_result = (nic_result_t) _their_result; 472 473 return rc; 474 } 475 476 /** Restart the auto-negotiation process. 477 * 478 * @param[in] dev_sess 479 * 480 * @return EOK If the operation was successfully completed 481 * 482 */ 483 int nic_autoneg_restart(async_sess_t *dev_sess) 484 { 485 async_exch_t *exch = async_exchange_begin(dev_sess); 486 int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 487 NIC_AUTONEG_RESTART); 488 async_exchange_end(exch); 489 490 return rc; 491 } 492 493 /** Query party's sending and reception of the PAUSE frame. 494 * 495 * @param[in] dev_sess 496 * @param[out] we_send This NIC sends the PAUSE frame (true/false) 497 * @param[out] we_receive This NIC receives the PAUSE frame (true/false) 498 * @param[out] pause The time set to transmitted PAUSE frames. 499 * 500 * @return EOK If the operation was successfully completed 501 * 502 */ 503 int nic_get_pause(async_sess_t *dev_sess, nic_result_t *we_send, 504 nic_result_t *we_receive, uint16_t *pause) 505 { 506 sysarg_t _we_send; 507 sysarg_t _we_receive; 508 sysarg_t _pause; 509 510 async_exch_t *exch = async_exchange_begin(dev_sess); 511 int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 512 NIC_GET_PAUSE, &_we_send, &_we_receive, &_pause); 513 async_exchange_end(exch); 514 515 if (we_send) 516 *we_send = _we_send; 517 518 if (we_receive) 519 *we_receive = _we_receive; 520 521 if (pause) 522 *pause = _pause; 523 524 return rc; 525 } 526 527 /** Control sending and reception of the PAUSE frame. 528 * 529 * @param[in] dev_sess 530 * @param[in] allow_send Allow sending the PAUSE frame (true/false) 531 * @param[in] allow_receive Allow reception of the PAUSE frame (true/false) 532 * @param[in] pause Pause length in 512 bit units written 533 * to transmitted frames. The value 0 means 534 * auto value (the best). If the requested 535 * time cannot be set the driver is allowed 536 * to set the nearest supported value. 537 * 538 * @return EOK If the operation was successfully completed 539 * 540 */ 541 int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive, 542 uint16_t pause) 543 { 544 async_exch_t *exch = async_exchange_begin(dev_sess); 545 int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 546 NIC_SET_PAUSE, allow_send, allow_receive, pause); 547 async_exchange_end(exch); 548 549 return rc; 550 } 551 552 /** Retrieve current settings of unicast frames reception. 553 * 554 * Note: In case of mode != NIC_UNICAST_LIST the contents of 555 * address_list and address_count are undefined. 556 * 557 * @param[in] dev_sess 558 * @param[out] mode Current operation mode 559 * @param[in] max_count Maximal number of addresses that could 560 * be written into the list buffer. 561 * @param[out] address_list Buffer for the list (array). Can be NULL. 562 * @param[out] address_count Number of addresses in the list before 563 * possible truncation due to the max_count. 564 * 565 * @return EOK If the operation was successfully completed 566 * 567 */ 568 int nic_unicast_get_mode(async_sess_t *dev_sess, nic_unicast_mode_t *mode, 569 size_t max_count, nic_address_t *address_list, size_t *address_count) 570 { 571 assert(mode); 572 573 sysarg_t _mode; 574 sysarg_t _address_count; 575 576 if (!address_list) 577 max_count = 0; 578 579 async_exch_t *exch = async_exchange_begin(dev_sess); 580 581 int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 582 NIC_UNICAST_GET_MODE, max_count, &_mode, &_address_count); 583 if (rc != EOK) { 584 async_exchange_end(exch); 585 return rc; 586 } 587 588 *mode = (nic_unicast_mode_t) _mode; 589 if (address_count) 590 *address_count = (size_t) _address_count; 591 592 if ((max_count) && (_address_count)) 593 rc = async_data_read_start(exch, address_list, 594 max_count * sizeof(nic_address_t)); 595 596 async_exchange_end(exch); 597 598 return rc; 599 } 600 601 /** Set which unicast frames are received. 602 * 603 * @param[in] dev_sess 604 * @param[in] mode Current operation mode 605 * @param[in] address_list The list of addresses. Can be NULL. 606 * @param[in] address_count Number of addresses in the list. 607 * 608 * @return EOK If the operation was successfully completed 609 * 610 */ 611 int nic_unicast_set_mode(async_sess_t *dev_sess, nic_unicast_mode_t mode, 612 const nic_address_t *address_list, size_t address_count) 613 { 614 if (address_list == NULL) 615 address_count = 0; 616 617 async_exch_t *exch = async_exchange_begin(dev_sess); 618 619 aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 620 NIC_UNICAST_SET_MODE, (sysarg_t) mode, address_count, NULL); 621 622 int rc; 623 if (address_count) 624 rc = async_data_write_start(exch, address_list, 625 address_count * sizeof(nic_address_t)); 626 else 627 rc = EOK; 628 629 async_exchange_end(exch); 630 631 sysarg_t res; 632 async_wait_for(message_id, &res); 633 634 if (rc != EOK) 635 return rc; 636 637 return (int) res; 638 } 639 640 /** Retrieve current settings of multicast frames reception. 641 * 642 * Note: In case of mode != NIC_MULTICAST_LIST the contents of 643 * address_list and address_count are undefined. 644 * 645 * @param[in] dev_sess 646 * @param[out] mode Current operation mode 647 * @param[in] max_count Maximal number of addresses that could 648 * be written into the list buffer. 649 * @param[out] address_list Buffer for the list (array). Can be NULL. 650 * @param[out] address_count Number of addresses in the list before 651 * possible truncation due to the max_count. 652 * Can be NULL. 653 * 654 * @return EOK If the operation was successfully completed 655 * 656 */ 657 int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode, 658 size_t max_count, nic_address_t *address_list, size_t *address_count) 659 { 660 assert(mode); 661 662 sysarg_t _mode; 663 664 if (!address_list) 665 max_count = 0; 666 667 async_exch_t *exch = async_exchange_begin(dev_sess); 668 669 sysarg_t ac; 670 int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 671 NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac); 672 if (rc != EOK) { 673 async_exchange_end(exch); 674 return rc; 675 } 676 677 *mode = (nic_multicast_mode_t) _mode; 678 if (address_count) 679 *address_count = (size_t) ac; 680 681 if ((max_count) && (ac)) 682 rc = async_data_read_start(exch, address_list, 683 max_count * sizeof(nic_address_t)); 684 685 async_exchange_end(exch); 686 return rc; 687 } 688 689 /** Set which multicast frames are received. 690 * 691 * @param[in] dev_sess 692 * @param[in] mode Current operation mode 693 * @param[in] address_list The list of addresses. Can be NULL. 694 * @param[in] address_count Number of addresses in the list. 695 * 696 * @return EOK If the operation was successfully completed 697 * 698 */ 699 int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode, 700 const nic_address_t *address_list, size_t address_count) 701 { 702 if (address_list == NULL) 703 address_count = 0; 704 705 async_exch_t *exch = async_exchange_begin(dev_sess); 706 707 aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 708 NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL); 709 710 int rc; 711 if (address_count) 712 rc = async_data_write_start(exch, address_list, 713 address_count * sizeof(nic_address_t)); 714 else 715 rc = EOK; 716 717 async_exchange_end(exch); 718 719 sysarg_t res; 720 async_wait_for(message_id, &res); 721 722 if (rc != EOK) 723 return rc; 724 725 return (int) res; 726 } 727 728 /** Determine if broadcast packets are received. 729 * 730 * @param[in] dev_sess 731 * @param[out] mode Current operation mode 732 * 733 * @return EOK If the operation was successfully completed 734 * 735 */ 736 int nic_broadcast_get_mode(async_sess_t *dev_sess, nic_broadcast_mode_t *mode) 737 { 738 assert(mode); 739 740 sysarg_t _mode; 741 742 async_exch_t *exch = async_exchange_begin(dev_sess); 743 int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 744 NIC_BROADCAST_GET_MODE, &_mode); 745 async_exchange_end(exch); 746 747 *mode = (nic_broadcast_mode_t) _mode; 748 749 return rc; 750 } 751 752 /** Set whether broadcast packets are received. 753 * 754 * @param[in] dev_sess 755 * @param[in] mode Current operation mode 756 * 757 * @return EOK If the operation was successfully completed 758 * 759 */ 760 int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode) 761 { 762 async_exch_t *exch = async_exchange_begin(dev_sess); 763 int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 764 NIC_BROADCAST_SET_MODE, mode); 765 async_exchange_end(exch); 766 767 return rc; 768 } 769 770 /** Determine if defective (erroneous) packets are received. 771 * 772 * @param[in] dev_sess 773 * @param[out] mode Bitmask specifying allowed errors 774 * 775 * @return EOK If the operation was successfully completed 776 * 777 */ 778 int nic_defective_get_mode(async_sess_t *dev_sess, uint32_t *mode) 779 { 780 assert(mode); 781 782 sysarg_t _mode; 783 784 async_exch_t *exch = async_exchange_begin(dev_sess); 785 int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 786 NIC_DEFECTIVE_GET_MODE, &_mode); 787 async_exchange_end(exch); 788 789 *mode = (uint32_t) _mode; 790 791 return rc; 792 } 793 794 /** Set whether defective (erroneous) packets are received. 795 * 796 * @param[in] dev_sess 797 * @param[out] mode Bitmask specifying allowed errors 798 * 799 * @return EOK If the operation was successfully completed 800 * 801 */ 802 int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode) 803 { 804 async_exch_t *exch = async_exchange_begin(dev_sess); 805 int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 806 NIC_DEFECTIVE_SET_MODE, mode); 807 async_exchange_end(exch); 808 809 return rc; 810 } 811 812 /** Retrieve the currently blocked source MAC addresses. 813 * 814 * @param[in] dev_sess 815 * @param[in] max_count Maximal number of addresses that could 816 * be written into the list buffer. 817 * @param[out] address_list Buffer for the list (array). Can be NULL. 818 * @param[out] address_count Number of addresses in the list before 819 * possible truncation due to the max_count. 820 * 821 * @return EOK If the operation was successfully completed 822 * 823 */ 824 int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count, 825 nic_address_t *address_list, size_t *address_count) 826 { 827 if (!address_list) 828 max_count = 0; 829 830 async_exch_t *exch = async_exchange_begin(dev_sess); 831 832 sysarg_t ac; 833 int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 834 NIC_BLOCKED_SOURCES_GET, max_count, &ac); 835 if (rc != EOK) { 836 async_exchange_end(exch); 837 return rc; 838 } 839 840 if (address_count) 841 *address_count = (size_t) ac; 842 843 if ((max_count) && (ac)) 844 rc = async_data_read_start(exch, address_list, 845 max_count * sizeof(nic_address_t)); 846 847 async_exchange_end(exch); 848 return rc; 849 } 850 851 /** Set which source MACs are blocked 852 * 853 * @param[in] dev_sess 854 * @param[in] address_list The list of addresses. Can be NULL. 855 * @param[in] address_count Number of addresses in the list. 856 * 857 * @return EOK If the operation was successfully completed 858 * 859 */ 860 int nic_blocked_sources_set(async_sess_t *dev_sess, 861 const nic_address_t *address_list, size_t address_count) 862 { 863 if (address_list == NULL) 864 address_count = 0; 865 866 async_exch_t *exch = async_exchange_begin(dev_sess); 867 868 aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 869 NIC_BLOCKED_SOURCES_SET, address_count, NULL); 870 871 int rc; 872 if (address_count) 873 rc = async_data_write_start(exch, address_list, 874 address_count * sizeof(nic_address_t)); 875 else 876 rc = EOK; 877 878 async_exchange_end(exch); 879 880 sysarg_t res; 881 async_wait_for(message_id, &res); 882 883 if (rc != EOK) 884 return rc; 885 886 return (int) res; 887 } 888 889 /** Request current VLAN filtering mask. 890 * 891 * @param[in] dev_sess 892 * @param[out] stats Structure with the statistics 893 * 894 * @return EOK If the operation was successfully completed 895 * 896 */ 897 int nic_vlan_get_mask(async_sess_t *dev_sess, nic_vlan_mask_t *mask) 898 { 899 assert(mask); 900 901 async_exch_t *exch = async_exchange_begin(dev_sess); 902 int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 903 NIC_VLAN_GET_MASK); 904 if (rc != EOK) { 905 async_exchange_end(exch); 906 return rc; 907 } 908 909 rc = async_data_read_start(exch, mask, sizeof(nic_vlan_mask_t)); 910 async_exchange_end(exch); 911 912 return rc; 913 } 914 915 /** Set the mask used for VLAN filtering. 916 * 917 * If NULL, VLAN filtering is disabled. 918 * 919 * @param[in] dev_sess 920 * @param[in] mask Pointer to mask structure or NULL to disable. 921 * 922 * @return EOK If the operation was successfully completed 923 * 924 */ 925 int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask) 926 { 927 async_exch_t *exch = async_exchange_begin(dev_sess); 928 929 aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 930 NIC_VLAN_SET_MASK, mask != NULL, NULL); 931 932 int rc; 933 if (mask != NULL) 934 rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t)); 935 else 936 rc = EOK; 937 938 async_exchange_end(exch); 939 940 sysarg_t res; 941 async_wait_for(message_id, &res); 942 943 if (rc != EOK) 944 return rc; 945 946 return (int) res; 947 } 948 949 /** Set VLAN (802.1q) tag. 950 * 951 * Set whether the tag is to be signaled in offload info and 952 * if the tag should be stripped from received frames and added 953 * to sent frames automatically. Not every combination of add 954 * and strip must be supported. 955 * 956 * @param[in] dev_sess 957 * @param[in] tag VLAN priority (top 3 bits) and 958 * the VLAN tag (bottom 12 bits) 959 * @param[in] add Add the VLAN tag automatically (boolean) 960 * @param[in] strip Strip the VLAN tag automatically (boolean) 961 * 962 * @return EOK If the operation was successfully completed 963 * 964 */ 965 int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip) 966 { 967 async_exch_t *exch = async_exchange_begin(dev_sess); 968 int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 969 NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip); 970 async_exchange_end(exch); 971 972 return rc; 973 } 974 975 /** Add new Wake-On-LAN virtue. 976 * 977 * @param[in] dev_sess 978 * @param[in] type Type of the virtue 979 * @param[in] data Data required for this virtue 980 * (depends on type) 981 * @param[in] length Length of the data 982 * @param[out] id Identifier of the new virtue 983 * 984 * @return EOK If the operation was successfully completed 985 * 986 */ 987 int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type, 988 const void *data, size_t length, nic_wv_id_t *id) 989 { 990 assert(id); 991 992 bool send_data = ((data != NULL) && (length != 0)); 993 async_exch_t *exch = async_exchange_begin(dev_sess); 994 995 ipc_call_t result; 996 aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 997 NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result); 998 999 sysarg_t res; 1000 if (send_data) { 1001 int rc = async_data_write_start(exch, data, length); 1002 if (rc != EOK) { 1003 async_exchange_end(exch); 1004 async_wait_for(message_id, &res); 1005 return rc; 1006 } 1007 } 1008 1009 async_exchange_end(exch); 1010 async_wait_for(message_id, &res); 1011 1012 *id = IPC_GET_ARG1(result); 1013 return (int) res; 1014 } 1015 1016 /** Remove Wake-On-LAN virtue. 1017 * 1018 * @param[in] dev_sess 1019 * @param[in] id Virtue identifier 1020 * 1021 * @return EOK If the operation was successfully completed 1022 * 1023 */ 1024 int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id) 1025 { 1026 async_exch_t *exch = async_exchange_begin(dev_sess); 1027 int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1028 NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id); 1029 async_exchange_end(exch); 1030 1031 return rc; 1032 } 1033 1034 /** Get information about virtue. 1035 * 1036 * @param[in] dev_sess 1037 * @param[in] id Virtue identifier 1038 * @param[out] type Type of the filter. Can be NULL. 1039 * @param[out] max_length Size of the data buffer. 1040 * @param[out] data Buffer for data used when the 1041 * virtue was created. Can be NULL. 1042 * @param[out] length Length of the data. Can be NULL. 1043 * 1044 * @return EOK If the operation was successfully completed 1045 * 1046 */ 1047 int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id, 1048 nic_wv_type_t *type, size_t max_length, void *data, size_t *length) 1049 { 1050 sysarg_t _type; 1051 sysarg_t _length; 1052 1053 if (data == NULL) 1054 max_length = 0; 1055 1056 async_exch_t *exch = async_exchange_begin(dev_sess); 1057 1058 int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1059 NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length, 1060 &_type, &_length); 1061 if (rc != EOK) { 1062 async_exchange_end(exch); 1063 return rc; 1064 } 1065 1066 if (type) 1067 *type = _type; 1068 1069 if (length) 1070 *length = _length; 1071 1072 if ((max_length) && (_length != 0)) 1073 rc = async_data_read_start(exch, data, max_length); 1074 1075 async_exchange_end(exch); 1076 return rc; 1077 } 1078 1079 /** Get a list of all virtues of the specified type. 1080 * 1081 * When NIC_WV_NONE is specified as the virtue type the function 1082 * lists virtues of all types. 1083 * 1084 * @param[in] dev_sess 1085 * @param[in] type Type of the virtues 1086 * @param[in] max_count Maximum number of ids that can be 1087 * written into the list buffer. 1088 * @param[out] id_list Buffer for to the list of virtue ids. 1089 * Can be NULL. 1090 * @param[out] id_count Number of virtue identifiers in the list 1091 * before possible truncation due to the 1092 * max_count. Can be NULL. 1093 * 1094 * @return EOK If the operation was successfully completed 1095 * 1096 */ 1097 int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type, 1098 size_t max_count, nic_wv_id_t *id_list, size_t *id_count) 1099 { 1100 if (id_list == NULL) 1101 max_count = 0; 1102 1103 async_exch_t *exch = async_exchange_begin(dev_sess); 1104 1105 sysarg_t count; 1106 int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1107 NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count); 1108 1109 if (id_count) 1110 *id_count = (size_t) count; 1111 1112 if ((rc != EOK) || (!max_count)) { 1113 async_exchange_end(exch); 1114 return rc; 1115 } 1116 1117 rc = async_data_read_start(exch, id_list, 1118 max_count * sizeof(nic_wv_id_t)); 1119 1120 async_exchange_end(exch); 1121 return rc; 1122 } 1123 1124 /** Get number of virtues that can be enabled yet. 1125 * 1126 * Count: < 0 => Virtue of this type can be never used 1127 * = 0 => No more virtues can be enabled 1128 * > 0 => #count virtues can be enabled yet 1129 * 1130 * @param[in] dev_sess 1131 * @param[in] type Virtue type 1132 * @param[out] count Number of virtues 1133 * 1134 * @return EOK If the operation was successfully completed 1135 * 1136 */ 1137 int nic_wol_virtue_get_caps(async_sess_t *dev_sess, nic_wv_type_t type, 1138 int *count) 1139 { 1140 assert(count); 1141 1142 sysarg_t _count; 1143 1144 async_exch_t *exch = async_exchange_begin(dev_sess); 1145 int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1146 NIC_WOL_VIRTUE_GET_CAPS, (sysarg_t) type, &_count); 1147 async_exchange_end(exch); 1148 1149 *count = (int) _count; 1150 return rc; 1151 } 1152 1153 /** Load the frame that issued the wakeup. 1154 * 1155 * The NIC can support only matched_type, only part of the frame 1156 * can be available or not at all. Sometimes even the type can be 1157 * uncertain -- in this case the matched_type contains NIC_WV_NONE. 1158 * 1159 * Frame_length can be greater than max_length, but at most max_length 1160 * bytes will be copied into the frame buffer. 1161 * 1162 * Note: Only the type of the filter can be detected, not the concrete 1163 * filter, because the driver is probably not running when the wakeup 1164 * is issued. 1165 * 1166 * @param[in] dev_sess 1167 * @param[out] matched_type Type of the filter that issued wakeup. 1168 * @param[in] max_length Size of the buffer 1169 * @param[out] frame Buffer for the frame. Can be NULL. 1170 * @param[out] frame_length Length of the stored frame. Can be NULL. 1171 * 1172 * @return EOK If the operation was successfully completed 1173 * 1174 */ 1175 int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type, 1176 size_t max_length, uint8_t *frame, size_t *frame_length) 1177 { 1178 assert(matched_type); 1179 1180 sysarg_t _matched_type; 1181 sysarg_t _frame_length; 1182 1183 if (frame == NULL) 1184 max_length = 0; 1185 1186 async_exch_t *exch = async_exchange_begin(dev_sess); 1187 1188 int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1189 NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length); 1190 if (rc != EOK) { 1191 async_exchange_end(exch); 1192 return rc; 1193 } 1194 1195 *matched_type = (nic_wv_type_t) _matched_type; 1196 if (frame_length) 1197 *frame_length = (size_t) _frame_length; 1198 1199 if ((max_length != 0) && (_frame_length != 0)) 1200 rc = async_data_read_start(exch, frame, max_length); 1201 1202 async_exchange_end(exch); 1203 return rc; 1204 } 1205 1206 /** Probe supported options and current setting of offload computations 1207 * 1208 * @param[in] dev_sess 1209 * @param[out] supported Supported offload options 1210 * @param[out] active Currently active offload options 1211 * 1212 * @return EOK If the operation was successfully completed 1213 * 1214 */ 1215 int nic_offload_probe(async_sess_t *dev_sess, uint32_t *supported, 1216 uint32_t *active) 1217 { 1218 assert(supported); 1219 assert(active); 1220 1221 sysarg_t _supported; 1222 sysarg_t _active; 1223 1224 async_exch_t *exch = async_exchange_begin(dev_sess); 1225 int rc = async_req_1_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1226 NIC_OFFLOAD_PROBE, &_supported, &_active); 1227 async_exchange_end(exch); 1228 1229 *supported = (uint32_t) _supported; 1230 *active = (uint32_t) _active; 1231 return rc; 1232 } 1233 1234 /** Set which offload computations can be performed on the NIC. 1235 * 1236 * @param[in] dev_sess 1237 * @param[in] mask Mask for the options (only those set here will be set) 1238 * @param[in] active Which options should be enabled and which disabled 1239 * 1240 * @return EOK If the operation was successfully completed 1241 * 1242 */ 1243 int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active) 1244 { 1245 async_exch_t *exch = async_exchange_begin(dev_sess); 1246 int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1247 NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active); 1248 async_exchange_end(exch); 1249 1250 return rc; 1251 } 1252 1253 /** Query the current interrupt/poll mode of the NIC 1254 * 1255 * @param[in] dev_sess 1256 * @param[out] mode Current poll mode 1257 * @param[out] period Period used in periodic polling. 1258 * Can be NULL. 1259 * 1260 * @return EOK If the operation was successfully completed 1261 * 1262 */ 1263 int nic_poll_get_mode(async_sess_t *dev_sess, nic_poll_mode_t *mode, 1264 struct timeval *period) 1265 { 1266 assert(mode); 1267 1268 sysarg_t _mode; 1269 1270 async_exch_t *exch = async_exchange_begin(dev_sess); 1271 1272 int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1273 NIC_POLL_GET_MODE, period != NULL, &_mode); 1274 if (rc != EOK) { 1275 async_exchange_end(exch); 1276 return rc; 1277 } 1278 1279 *mode = (nic_poll_mode_t) _mode; 1280 1281 if (period != NULL) 1282 rc = async_data_read_start(exch, period, sizeof(struct timeval)); 1283 1284 async_exchange_end(exch); 1285 return rc; 1286 } 1287 1288 /** Set the interrupt/poll mode of the NIC. 1289 * 1290 * @param[in] dev_sess 1291 * @param[in] mode New poll mode 1292 * @param[in] period Period used in periodic polling. Can be NULL. 1293 * 1294 * @return EOK If the operation was successfully completed 1295 * 1296 */ 1297 int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode, 1298 const struct timeval *period) 1299 { 1300 async_exch_t *exch = async_exchange_begin(dev_sess); 1301 1302 aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 1303 NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL); 1304 1305 int rc; 1306 if (period) 1307 rc = async_data_write_start(exch, period, sizeof(struct timeval)); 1308 else 1309 rc = EOK; 1310 1311 async_exchange_end(exch); 1312 1313 sysarg_t res; 1314 async_wait_for(message_id, &res); 1315 1316 if (rc != EOK) 1317 return rc; 1318 1319 return (int) res; 1320 } 1321 1322 /** Request the driver to poll the NIC. 1323 * 1324 * @param[in] dev_sess 1325 * 1326 * @return EOK If the operation was successfully completed 1327 * 1328 */ 1329 int nic_poll_now(async_sess_t *dev_sess) 1330 { 1331 async_exch_t *exch = async_exchange_begin(dev_sess); 1332 int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW); 1333 async_exchange_end(exch); 1334 1335 return rc; 1336 } 43 1337 44 1338 static void remote_nic_send_frame(ddf_fun_t *dev, void *iface, … … 1198 2492 * 1199 2493 */ 1200 static remote_iface_func_ptr_t remote_nic_iface_ops[] = {1201 &remote_nic_send_frame,1202 &remote_nic_callback_create,1203 &remote_nic_get_state,1204 &remote_nic_set_state,1205 &remote_nic_get_address,1206 &remote_nic_set_address,1207 &remote_nic_get_stats,1208 &remote_nic_get_device_info,1209 &remote_nic_get_cable_state,1210 &remote_nic_get_operation_mode,1211 &remote_nic_set_operation_mode,1212 &remote_nic_autoneg_enable,1213 &remote_nic_autoneg_disable,1214 &remote_nic_autoneg_probe,1215 &remote_nic_autoneg_restart,1216 &remote_nic_get_pause,1217 &remote_nic_set_pause,1218 &remote_nic_unicast_get_mode,1219 &remote_nic_unicast_set_mode,1220 &remote_nic_multicast_get_mode,1221 &remote_nic_multicast_set_mode,1222 &remote_nic_broadcast_get_mode,1223 &remote_nic_broadcast_set_mode,1224 &remote_nic_defective_get_mode,1225 &remote_nic_defective_set_mode,1226 &remote_nic_blocked_sources_get,1227 &remote_nic_blocked_sources_set,1228 &remote_nic_vlan_get_mask,1229 &remote_nic_vlan_set_mask,1230 &remote_nic_vlan_set_tag,1231 &remote_nic_wol_virtue_add,1232 &remote_nic_wol_virtue_remove,1233 &remote_nic_wol_virtue_probe,1234 &remote_nic_wol_virtue_list,1235 &remote_nic_wol_virtue_get_caps,1236 &remote_nic_wol_load_info,1237 &remote_nic_offload_probe,1238 &remote_nic_offload_set,1239 &remote_nic_poll_get_mode,1240 &remote_nic_poll_set_mode,1241 &remote_nic_poll_now2494 static const remote_iface_func_ptr_t remote_nic_iface_ops[] = { 2495 [NIC_SEND_MESSAGE] = remote_nic_send_frame, 2496 [NIC_CALLBACK_CREATE] = remote_nic_callback_create, 2497 [NIC_GET_STATE] = remote_nic_get_state, 2498 [NIC_SET_STATE] = remote_nic_set_state, 2499 [NIC_GET_ADDRESS] = remote_nic_get_address, 2500 [NIC_SET_ADDRESS] = remote_nic_set_address, 2501 [NIC_GET_STATS] = remote_nic_get_stats, 2502 [NIC_GET_DEVICE_INFO] = remote_nic_get_device_info, 2503 [NIC_GET_CABLE_STATE] = remote_nic_get_cable_state, 2504 [NIC_GET_OPERATION_MODE] = remote_nic_get_operation_mode, 2505 [NIC_SET_OPERATION_MODE] = remote_nic_set_operation_mode, 2506 [NIC_AUTONEG_ENABLE] = remote_nic_autoneg_enable, 2507 [NIC_AUTONEG_DISABLE] = remote_nic_autoneg_disable, 2508 [NIC_AUTONEG_PROBE] = remote_nic_autoneg_probe, 2509 [NIC_AUTONEG_RESTART] = remote_nic_autoneg_restart, 2510 [NIC_GET_PAUSE] = remote_nic_get_pause, 2511 [NIC_SET_PAUSE] = remote_nic_set_pause, 2512 [NIC_UNICAST_GET_MODE] = remote_nic_unicast_get_mode, 2513 [NIC_UNICAST_SET_MODE] = remote_nic_unicast_set_mode, 2514 [NIC_MULTICAST_GET_MODE] = remote_nic_multicast_get_mode, 2515 [NIC_MULTICAST_SET_MODE] = remote_nic_multicast_set_mode, 2516 [NIC_BROADCAST_GET_MODE] = remote_nic_broadcast_get_mode, 2517 [NIC_BROADCAST_SET_MODE] = remote_nic_broadcast_set_mode, 2518 [NIC_DEFECTIVE_GET_MODE] = remote_nic_defective_get_mode, 2519 [NIC_DEFECTIVE_SET_MODE] = remote_nic_defective_set_mode, 2520 [NIC_BLOCKED_SOURCES_GET] = remote_nic_blocked_sources_get, 2521 [NIC_BLOCKED_SOURCES_SET] = remote_nic_blocked_sources_set, 2522 [NIC_VLAN_GET_MASK] = remote_nic_vlan_get_mask, 2523 [NIC_VLAN_SET_MASK] = remote_nic_vlan_set_mask, 2524 [NIC_VLAN_SET_TAG] = remote_nic_vlan_set_tag, 2525 [NIC_WOL_VIRTUE_ADD] = remote_nic_wol_virtue_add, 2526 [NIC_WOL_VIRTUE_REMOVE] = remote_nic_wol_virtue_remove, 2527 [NIC_WOL_VIRTUE_PROBE] = remote_nic_wol_virtue_probe, 2528 [NIC_WOL_VIRTUE_LIST] = remote_nic_wol_virtue_list, 2529 [NIC_WOL_VIRTUE_GET_CAPS] = remote_nic_wol_virtue_get_caps, 2530 [NIC_WOL_LOAD_INFO] = remote_nic_wol_load_info, 2531 [NIC_OFFLOAD_PROBE] = remote_nic_offload_probe, 2532 [NIC_OFFLOAD_SET] = remote_nic_offload_set, 2533 [NIC_POLL_GET_MODE] = remote_nic_poll_get_mode, 2534 [NIC_POLL_SET_MODE] = remote_nic_poll_set_mode, 2535 [NIC_POLL_NOW] = remote_nic_poll_now 1242 2536 }; 1243 2537 … … 1248 2542 * 1249 2543 */ 1250 remote_iface_t remote_nic_iface = { 1251 .method_count = sizeof(remote_nic_iface_ops) / 1252 sizeof(remote_iface_func_ptr_t), 2544 const remote_iface_t remote_nic_iface = { 2545 .method_count = ARRAY_SIZE(remote_nic_iface_ops), 1253 2546 .methods = remote_nic_iface_ops 1254 2547 };
Note:
See TracChangeset
for help on using the changeset viewer.