Changes in uspace/lib/drv/generic/remote_nic.c [7858acbf:acdb5bac] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_nic.c
r7858acbf 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_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 device151 *152 * @param[in] dev_sess153 * @param[out] state Current state154 *155 * @return EOK If the operation was successfully completed156 *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 state175 *176 * @param[in] dev_sess177 * @param[in] state New state178 *179 * @return EOK If the operation was successfully completed180 *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 device193 *194 * @param[in] dev_sess195 * @param[out] address Structure with buffer for the address196 *197 * @return EOK If the operation was successfully completed198 *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_sess222 * @param[in] address Pointer to the address223 *224 * @return EOK If the operation was successfully completed225 *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_sess249 * @param[out] stats Structure with the statistics250 *251 * @return EOK If the operation was successfully completed252 *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_t277 *278 * @param[in] dev_sess279 * @param[out] device_info Information about the device280 *281 * @return EOK If the operation was successfully completed282 *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_sess307 * @param[out] cable_state Current cable state308 *309 * @return EOK If the operation was successfully completed310 *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_sess331 * @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 completed336 *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 command365 * disables auto-negotiation and sets the operation mode.366 *367 * @param[in] dev_sess368 * @param[in] speed Operation speed in Mbps369 * @param[in] duplex Full duplex/half duplex370 * @param[in] role Master/slave/auto (e.g. in Gbit Ethernet]371 *372 * @return EOK If the operation was successfully completed373 *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_sess395 * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.396 *397 * @return EOK If the operation was successfully completed398 *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_sess413 *414 * @return EOK If the operation was successfully completed415 *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_sess432 * @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 completed442 *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_sess477 *478 * @return EOK If the operation was successfully completed479 *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_sess494 * @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 completed499 *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_sess528 * @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 written531 * to transmitted frames. The value 0 means532 * auto value (the best). If the requested533 * time cannot be set the driver is allowed534 * to set the nearest supported value.535 *536 * @return EOK If the operation was successfully completed537 *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 of553 * address_list and address_count are undefined.554 *555 * @param[in] dev_sess556 * @param[out] mode Current operation mode557 * @param[in] max_count Maximal number of addresses that could558 * 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 before561 * possible truncation due to the max_count.562 *563 * @return EOK If the operation was successfully completed564 *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_sess602 * @param[in] mode Current operation mode603 * @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 completed607 *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 else625 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 of641 * address_list and address_count are undefined.642 *643 * @param[in] dev_sess644 * @param[out] mode Current operation mode645 * @param[in] max_count Maximal number of addresses that could646 * 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 before649 * possible truncation due to the max_count.650 * Can be NULL.651 *652 * @return EOK If the operation was successfully completed653 *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_sess690 * @param[in] mode Current operation mode691 * @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 completed695 *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 else713 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_sess729 * @param[out] mode Current operation mode730 *731 * @return EOK If the operation was successfully completed732 *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_sess753 * @param[in] mode Current operation mode754 *755 * @return EOK If the operation was successfully completed756 *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_sess771 * @param[out] mode Bitmask specifying allowed errors772 *773 * @return EOK If the operation was successfully completed774 *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_sess795 * @param[out] mode Bitmask specifying allowed errors796 *797 * @return EOK If the operation was successfully completed798 *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_sess813 * @param[in] max_count Maximal number of addresses that could814 * 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 before817 * possible truncation due to the max_count.818 *819 * @return EOK If the operation was successfully completed820 *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 blocked850 *851 * @param[in] dev_sess852 * @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 completed856 *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 else874 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_sess890 * @param[out] stats Structure with the statistics891 *892 * @return EOK If the operation was successfully completed893 *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_sess918 * @param[in] mask Pointer to mask structure or NULL to disable.919 *920 * @return EOK If the operation was successfully completed921 *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 else934 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 and950 * if the tag should be stripped from received frames and added951 * to sent frames automatically. Not every combination of add952 * and strip must be supported.953 *954 * @param[in] dev_sess955 * @param[in] tag VLAN priority (top 3 bits) and956 * 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 completed961 *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_sess976 * @param[in] type Type of the virtue977 * @param[in] data Data required for this virtue978 * (depends on type)979 * @param[in] length Length of the data980 * @param[out] id Identifier of the new virtue981 *982 * @return EOK If the operation was successfully completed983 *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_sess1017 * @param[in] id Virtue identifier1018 *1019 * @return EOK If the operation was successfully completed1020 *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_sess1035 * @param[in] id Virtue identifier1036 * @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 the1039 * 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 completed1043 *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 function1080 * lists virtues of all types.1081 *1082 * @param[in] dev_sess1083 * @param[in] type Type of the virtues1084 * @param[in] max_count Maximum number of ids that can be1085 * 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 list1089 * before possible truncation due to the1090 * max_count. Can be NULL.1091 *1092 * @return EOK If the operation was successfully completed1093 *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 used1125 * = 0 => No more virtues can be enabled1126 * > 0 => #count virtues can be enabled yet1127 *1128 * @param[in] dev_sess1129 * @param[in] type Virtue type1130 * @param[out] count Number of virtues1131 *1132 * @return EOK If the operation was successfully completed1133 *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 frame1154 * can be available or not at all. Sometimes even the type can be1155 * 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_length1158 * bytes will be copied into the frame buffer.1159 *1160 * Note: Only the type of the filter can be detected, not the concrete1161 * filter, because the driver is probably not running when the wakeup1162 * is issued.1163 *1164 * @param[in] dev_sess1165 * @param[out] matched_type Type of the filter that issued wakeup.1166 * @param[in] max_length Size of the buffer1167 * @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 completed1171 *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 computations1205 *1206 * @param[in] dev_sess1207 * @param[out] supported Supported offload options1208 * @param[out] active Currently active offload options1209 *1210 * @return EOK If the operation was successfully completed1211 *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_sess1235 * @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 disabled1237 *1238 * @return EOK If the operation was successfully completed1239 *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 NIC1252 *1253 * @param[in] dev_sess1254 * @param[out] mode Current poll mode1255 * @param[out] period Period used in periodic polling.1256 * Can be NULL.1257 *1258 * @return EOK If the operation was successfully completed1259 *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_sess1289 * @param[in] mode New poll mode1290 * @param[in] period Period used in periodic polling. Can be NULL.1291 *1292 * @return EOK If the operation was successfully completed1293 *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 else1307 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_sess1323 *1324 * @return EOK If the operation was successfully completed1325 *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 }1335 43 1336 44 static void remote_nic_send_frame(ddf_fun_t *dev, void *iface, … … 2490 1198 * 2491 1199 */ 2492 static constremote_iface_func_ptr_t remote_nic_iface_ops[] = {2493 [NIC_SEND_MESSAGE] =remote_nic_send_frame,2494 [NIC_CALLBACK_CREATE] =remote_nic_callback_create,2495 [NIC_GET_STATE] =remote_nic_get_state,2496 [NIC_SET_STATE] =remote_nic_set_state,2497 [NIC_GET_ADDRESS] =remote_nic_get_address,2498 [NIC_SET_ADDRESS] =remote_nic_set_address,2499 [NIC_GET_STATS] =remote_nic_get_stats,2500 [NIC_GET_DEVICE_INFO] =remote_nic_get_device_info,2501 [NIC_GET_CABLE_STATE] =remote_nic_get_cable_state,2502 [NIC_GET_OPERATION_MODE] =remote_nic_get_operation_mode,2503 [NIC_SET_OPERATION_MODE] =remote_nic_set_operation_mode,2504 [NIC_AUTONEG_ENABLE] =remote_nic_autoneg_enable,2505 [NIC_AUTONEG_DISABLE] =remote_nic_autoneg_disable,2506 [NIC_AUTONEG_PROBE] =remote_nic_autoneg_probe,2507 [NIC_AUTONEG_RESTART] =remote_nic_autoneg_restart,2508 [NIC_GET_PAUSE] =remote_nic_get_pause,2509 [NIC_SET_PAUSE] =remote_nic_set_pause,2510 [NIC_UNICAST_GET_MODE] =remote_nic_unicast_get_mode,2511 [NIC_UNICAST_SET_MODE] =remote_nic_unicast_set_mode,2512 [NIC_MULTICAST_GET_MODE] =remote_nic_multicast_get_mode,2513 [NIC_MULTICAST_SET_MODE] =remote_nic_multicast_set_mode,2514 [NIC_BROADCAST_GET_MODE] =remote_nic_broadcast_get_mode,2515 [NIC_BROADCAST_SET_MODE] =remote_nic_broadcast_set_mode,2516 [NIC_DEFECTIVE_GET_MODE] =remote_nic_defective_get_mode,2517 [NIC_DEFECTIVE_SET_MODE] =remote_nic_defective_set_mode,2518 [NIC_BLOCKED_SOURCES_GET] =remote_nic_blocked_sources_get,2519 [NIC_BLOCKED_SOURCES_SET] =remote_nic_blocked_sources_set,2520 [NIC_VLAN_GET_MASK] =remote_nic_vlan_get_mask,2521 [NIC_VLAN_SET_MASK] =remote_nic_vlan_set_mask,2522 [NIC_VLAN_SET_TAG] =remote_nic_vlan_set_tag,2523 [NIC_WOL_VIRTUE_ADD] =remote_nic_wol_virtue_add,2524 [NIC_WOL_VIRTUE_REMOVE] =remote_nic_wol_virtue_remove,2525 [NIC_WOL_VIRTUE_PROBE] =remote_nic_wol_virtue_probe,2526 [NIC_WOL_VIRTUE_LIST] =remote_nic_wol_virtue_list,2527 [NIC_WOL_VIRTUE_GET_CAPS] =remote_nic_wol_virtue_get_caps,2528 [NIC_WOL_LOAD_INFO] =remote_nic_wol_load_info,2529 [NIC_OFFLOAD_PROBE] =remote_nic_offload_probe,2530 [NIC_OFFLOAD_SET] =remote_nic_offload_set,2531 [NIC_POLL_GET_MODE] =remote_nic_poll_get_mode,2532 [NIC_POLL_SET_MODE] =remote_nic_poll_set_mode,2533 [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 2534 1242 }; 2535 1243 … … 2540 1248 * 2541 1249 */ 2542 const remote_iface_t remote_nic_iface = { 2543 .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), 2544 1253 .methods = remote_nic_iface_ops 2545 1254 };
Note:
See TracChangeset
for help on using the changeset viewer.