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