Changes in uspace/lib/drv/generic/remote_nic.c [f9b2cb4c:acdb5bac] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_nic.c
rf9b2cb4c racdb5bac 40 40 #include <ipc/services.h> 41 41 #include <sys/time.h> 42 #include <macros.h>43 44 42 #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_NOW89 } nic_funcs_t;90 91 /** Send frame from NIC92 *93 * @param[in] dev_sess94 * @param[in] data Frame data95 * @param[in] size Frame size in bytes96 *97 * @return EOK If the operation was successfully completed98 *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 service121 *122 * @param[in] dev_sess123 * @param[in] device_id124 *125 * @return EOK If the operation was successfully completed126 *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 device153 *154 * @param[in] dev_sess155 * @param[out] state Current state156 *157 * @return EOK If the operation was successfully completed158 *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 state177 *178 * @param[in] dev_sess179 * @param[in] state New state180 *181 * @return EOK If the operation was successfully completed182 *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 device195 *196 * @param[in] dev_sess197 * @param[out] address Structure with buffer for the address198 *199 * @return EOK If the operation was successfully completed200 *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_sess224 * @param[in] address Pointer to the address225 *226 * @return EOK If the operation was successfully completed227 *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_sess251 * @param[out] stats Structure with the statistics252 *253 * @return EOK If the operation was successfully completed254 *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_t279 *280 * @param[in] dev_sess281 * @param[out] device_info Information about the device282 *283 * @return EOK If the operation was successfully completed284 *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_sess309 * @param[out] cable_state Current cable state310 *311 * @return EOK If the operation was successfully completed312 *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_sess333 * @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 completed338 *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 command367 * disables auto-negotiation and sets the operation mode.368 *369 * @param[in] dev_sess370 * @param[in] speed Operation speed in Mbps371 * @param[in] duplex Full duplex/half duplex372 * @param[in] role Master/slave/auto (e.g. in Gbit Ethernet]373 *374 * @return EOK If the operation was successfully completed375 *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_sess397 * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.398 *399 * @return EOK If the operation was successfully completed400 *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_sess415 *416 * @return EOK If the operation was successfully completed417 *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_sess434 * @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 completed444 *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_sess479 *480 * @return EOK If the operation was successfully completed481 *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_sess496 * @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 completed501 *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_sess530 * @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 written533 * to transmitted frames. The value 0 means534 * auto value (the best). If the requested535 * time cannot be set the driver is allowed536 * to set the nearest supported value.537 *538 * @return EOK If the operation was successfully completed539 *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 of555 * address_list and address_count are undefined.556 *557 * @param[in] dev_sess558 * @param[out] mode Current operation mode559 * @param[in] max_count Maximal number of addresses that could560 * 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 before563 * possible truncation due to the max_count.564 *565 * @return EOK If the operation was successfully completed566 *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_sess604 * @param[in] mode Current operation mode605 * @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 completed609 *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 else627 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 of643 * address_list and address_count are undefined.644 *645 * @param[in] dev_sess646 * @param[out] mode Current operation mode647 * @param[in] max_count Maximal number of addresses that could648 * 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 before651 * possible truncation due to the max_count.652 * Can be NULL.653 *654 * @return EOK If the operation was successfully completed655 *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_sess692 * @param[in] mode Current operation mode693 * @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 completed697 *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 else715 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_sess731 * @param[out] mode Current operation mode732 *733 * @return EOK If the operation was successfully completed734 *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_sess755 * @param[in] mode Current operation mode756 *757 * @return EOK If the operation was successfully completed758 *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_sess773 * @param[out] mode Bitmask specifying allowed errors774 *775 * @return EOK If the operation was successfully completed776 *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_sess797 * @param[out] mode Bitmask specifying allowed errors798 *799 * @return EOK If the operation was successfully completed800 *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_sess815 * @param[in] max_count Maximal number of addresses that could816 * 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 before819 * possible truncation due to the max_count.820 *821 * @return EOK If the operation was successfully completed822 *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 blocked852 *853 * @param[in] dev_sess854 * @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 completed858 *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 else876 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_sess892 * @param[out] stats Structure with the statistics893 *894 * @return EOK If the operation was successfully completed895 *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_sess920 * @param[in] mask Pointer to mask structure or NULL to disable.921 *922 * @return EOK If the operation was successfully completed923 *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 else936 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 and952 * if the tag should be stripped from received frames and added953 * to sent frames automatically. Not every combination of add954 * and strip must be supported.955 *956 * @param[in] dev_sess957 * @param[in] tag VLAN priority (top 3 bits) and958 * 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 completed963 *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_sess978 * @param[in] type Type of the virtue979 * @param[in] data Data required for this virtue980 * (depends on type)981 * @param[in] length Length of the data982 * @param[out] id Identifier of the new virtue983 *984 * @return EOK If the operation was successfully completed985 *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_sess1019 * @param[in] id Virtue identifier1020 *1021 * @return EOK If the operation was successfully completed1022 *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_sess1037 * @param[in] id Virtue identifier1038 * @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 the1041 * 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 completed1045 *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 function1082 * lists virtues of all types.1083 *1084 * @param[in] dev_sess1085 * @param[in] type Type of the virtues1086 * @param[in] max_count Maximum number of ids that can be1087 * 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 list1091 * before possible truncation due to the1092 * max_count. Can be NULL.1093 *1094 * @return EOK If the operation was successfully completed1095 *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 used1127 * = 0 => No more virtues can be enabled1128 * > 0 => #count virtues can be enabled yet1129 *1130 * @param[in] dev_sess1131 * @param[in] type Virtue type1132 * @param[out] count Number of virtues1133 *1134 * @return EOK If the operation was successfully completed1135 *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 frame1156 * can be available or not at all. Sometimes even the type can be1157 * 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_length1160 * bytes will be copied into the frame buffer.1161 *1162 * Note: Only the type of the filter can be detected, not the concrete1163 * filter, because the driver is probably not running when the wakeup1164 * is issued.1165 *1166 * @param[in] dev_sess1167 * @param[out] matched_type Type of the filter that issued wakeup.1168 * @param[in] max_length Size of the buffer1169 * @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 completed1173 *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 computations1207 *1208 * @param[in] dev_sess1209 * @param[out] supported Supported offload options1210 * @param[out] active Currently active offload options1211 *1212 * @return EOK If the operation was successfully completed1213 *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_sess1237 * @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 disabled1239 *1240 * @return EOK If the operation was successfully completed1241 *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 NIC1254 *1255 * @param[in] dev_sess1256 * @param[out] mode Current poll mode1257 * @param[out] period Period used in periodic polling.1258 * Can be NULL.1259 *1260 * @return EOK If the operation was successfully completed1261 *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_sess1291 * @param[in] mode New poll mode1292 * @param[in] period Period used in periodic polling. Can be NULL.1293 *1294 * @return EOK If the operation was successfully completed1295 *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 else1309 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_sess1325 *1326 * @return EOK If the operation was successfully completed1327 *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 }1337 43 1338 44 static void remote_nic_send_frame(ddf_fun_t *dev, void *iface, … … 2492 1198 * 2493 1199 */ 2494 static constremote_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_now1200 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_now 2536 1242 }; 2537 1243 … … 2542 1248 * 2543 1249 */ 2544 const remote_iface_t remote_nic_iface = { 2545 .method_count = ARRAY_SIZE(remote_nic_iface_ops), 1250 remote_iface_t remote_nic_iface = { 1251 .method_count = sizeof(remote_nic_iface_ops) / 1252 sizeof(remote_iface_func_ptr_t), 2546 1253 .methods = remote_nic_iface_ops 2547 1254 };
Note:
See TracChangeset
for help on using the changeset viewer.