/** Set which multicast frames are received. * * @param[in] dev_sess * @param[in] mode Current operation mode * @param[in] address_list The list of addresses. Can be NULL. * @param[in] address_count Number of addresses in the list. * * @return EOK If the operation was successfully completed * */ int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode, const nic_address_t *address_list, size_t address_count) { if (address_list == NULL) address_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL); int rc; if (address_count) rc = async_data_write_start(exch, address_list, address_count * sizeof(nic_address_t)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** Retrieve current settings of multicast frames reception. * * Note: In case of mode != NIC_MULTICAST_LIST the contents of * address_list and address_count are undefined. * * @param[in] dev_sess * @param[out] mode Current operation mode * @param[in] max_count Maximal number of addresses that could * be written into the list buffer. * @param[out] address_list Buffer for the list (array). Can be NULL. * @param[out] address_count Number of addresses in the list before * possible truncation due to the max_count. * Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode, size_t max_count, nic_address_t *address_list, size_t *address_count) { assert(mode); sysarg_t _mode; if (!address_list) max_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); sysarg_t ac; int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac); if (rc != EOK) { async_exchange_end(exch); return rc; } *mode = (nic_multicast_mode_t) _mode; if (address_count) *address_count = (size_t) ac; if ((max_count) && (ac)) rc = async_data_read_start(exch, address_list, max_count * sizeof(nic_address_t)); async_exchange_end(exch); return rc; }
/** Set which source MACs are blocked * * @param[in] dev_sess * @param[in] address_list The list of addresses. Can be NULL. * @param[in] address_count Number of addresses in the list. * * @return EOK If the operation was successfully completed * */ int nic_blocked_sources_set(async_sess_t *dev_sess, const nic_address_t *address_list, size_t address_count) { if (address_list == NULL) address_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_BLOCKED_SOURCES_SET, address_count, NULL); int rc; if (address_count) rc = async_data_write_start(exch, address_list, address_count * sizeof(nic_address_t)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** Retrieve the currently blocked source MAC addresses. * * @param[in] dev_sess * @param[in] max_count Maximal number of addresses that could * be written into the list buffer. * @param[out] address_list Buffer for the list (array). Can be NULL. * @param[out] address_count Number of addresses in the list before * possible truncation due to the max_count. * * @return EOK If the operation was successfully completed * */ int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count, nic_address_t *address_list, size_t *address_count) { if (!address_list) max_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); sysarg_t ac; int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_BLOCKED_SOURCES_GET, max_count, &ac); if (rc != EOK) { async_exchange_end(exch); return rc; } if (address_count) *address_count = (size_t) ac; if ((max_count) && (ac)) rc = async_data_read_start(exch, address_list, max_count * sizeof(nic_address_t)); async_exchange_end(exch); return rc; }
/** Add new Wake-On-LAN virtue. * * @param[in] dev_sess * @param[in] type Type of the virtue * @param[in] data Data required for this virtue * (depends on type) * @param[in] length Length of the data * @param[out] id Identifier of the new virtue * * @return EOK If the operation was successfully completed * */ int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type, const void *data, size_t length, nic_wv_id_t *id) { assert(id); bool send_data = ((data != NULL) && (length != 0)); async_exch_t *exch = async_exchange_begin(dev_sess); ipc_call_t result; aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result); sysarg_t res; if (send_data) { int rc = async_data_write_start(exch, data, length); if (rc != EOK) { async_exchange_end(exch); async_wait_for(message_id, &res); return rc; } } async_exchange_end(exch); async_wait_for(message_id, &res); *id = IPC_GET_ARG1(result); return (int) res; }
/** Get a list of all virtues of the specified type. * * When NIC_WV_NONE is specified as the virtue type the function * lists virtues of all types. * * @param[in] dev_sess * @param[in] type Type of the virtues * @param[in] max_count Maximum number of ids that can be * written into the list buffer. * @param[out] id_list Buffer for to the list of virtue ids. * Can be NULL. * @param[out] id_count Number of virtue identifiers in the list * before possible truncation due to the * max_count. Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type, size_t max_count, nic_wv_id_t *id_list, size_t *id_count) { if (id_list == NULL) max_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); sysarg_t count; int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count); if (id_count) *id_count = (size_t) count; if ((rc != EOK) || (!max_count)) { async_exchange_end(exch); return rc; } rc = async_data_read_start(exch, id_list, max_count * sizeof(nic_wv_id_t)); async_exchange_end(exch); return rc; }
/** Load the frame that issued the wakeup. * * The NIC can support only matched_type, only part of the frame * can be available or not at all. Sometimes even the type can be * uncertain -- in this case the matched_type contains NIC_WV_NONE. * * Frame_length can be greater than max_length, but at most max_length * bytes will be copied into the frame buffer. * * Note: Only the type of the filter can be detected, not the concrete * filter, because the driver is probably not running when the wakeup * is issued. * * @param[in] dev_sess * @param[out] matched_type Type of the filter that issued wakeup. * @param[in] max_length Size of the buffer * @param[out] frame Buffer for the frame. Can be NULL. * @param[out] frame_length Length of the stored frame. Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type, size_t max_length, uint8_t *frame, size_t *frame_length) { assert(matched_type); sysarg_t _matched_type; sysarg_t _frame_length; if (frame == NULL) max_length = 0; async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length); if (rc != EOK) { async_exchange_end(exch); return rc; } *matched_type = (nic_wv_type_t) _matched_type; if (frame_length) *frame_length = (size_t) _frame_length; if ((max_length != 0) && (_frame_length != 0)) rc = async_data_read_start(exch, frame, max_length); async_exchange_end(exch); return rc; }
/** Get information about virtue. * * @param[in] dev_sess * @param[in] id Virtue identifier * @param[out] type Type of the filter. Can be NULL. * @param[out] max_length Size of the data buffer. * @param[out] data Buffer for data used when the * virtue was created. Can be NULL. * @param[out] length Length of the data. Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id, nic_wv_type_t *type, size_t max_length, void *data, size_t *length) { sysarg_t _type; sysarg_t _length; if (data == NULL) max_length = 0; async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length, &_type, &_length); if (rc != EOK) { async_exchange_end(exch); return rc; } if (type) *type = _type; if (length) *length = _length; if ((max_length) && (_length != 0)) rc = async_data_read_start(exch, data, max_length); async_exchange_end(exch); return rc; }
/** * Query audio mixer for basic info (name and items count). * @param[in] exch IPC exchange connected to the device * @param[out] name Audio mixer string identifier * @param[out] items Number of items controlled by the mixer. * @return Error code. */ int audio_mixer_get_info(async_exch_t *exch, const char **name, unsigned *items) { if (!exch) return EINVAL; sysarg_t name_size, itemc; const int ret = async_req_1_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), IPC_M_AUDIO_MIXER_GET_INFO, &name_size, &itemc); if (ret == EOK && name) { char *name_place = calloc(1, name_size); if (!name_place) { /* Make the other side fail * as it waits for read request */ async_data_read_start(exch, (void*)-1, 0); return ENOMEM; } const int ret = async_data_read_start(exch, name_place, name_size); if (ret != EOK) { free(name_place); return ret; } *name = name_place; } if (ret == EOK && items) *items = itemc; return ret; }
/** Probe current state of auto-negotiation. * * Modes are defined in the "nic/eth_phys.h" in the C library. * * @param[in] dev_sess * @param[out] our_advertisement Modes advertised by this NIC. * Can be NULL. * @param[out] their_advertisement Modes advertised by the other side. * Can be NULL. * @param[out] result General state of auto-negotiation. * Can be NULL. * @param[out] their_result State of other side auto-negotiation. * Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement, uint32_t *their_advertisement, nic_result_t *result, nic_result_t *their_result) { sysarg_t _our_advertisement; sysarg_t _their_advertisement; sysarg_t _result; sysarg_t _their_result; async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement, &_result, &_their_result); async_exchange_end(exch); if (our_advertisement) *our_advertisement = (uint32_t) _our_advertisement; if (*their_advertisement) *their_advertisement = (uint32_t) _their_advertisement; if (result) *result = (nic_result_t) _result; if (their_result) *their_result = (nic_result_t) _their_result; return rc; }
/** Request the driver to poll the NIC. * * @param[in] dev_sess * * @return EOK If the operation was successfully completed * */ int nic_poll_now(async_sess_t *dev_sess) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW); async_exchange_end(exch); return rc; }
int graph_dev_connect(async_sess_t *sess) { async_exch_t *exch = async_exchange_begin(sess); int ret = async_req_1_0(exch, DEV_IFACE_ID(GRAPH_DEV_IFACE), GRAPH_DEV_CONNECT); async_exchange_end(exch); return ret; }
/** * Set control item to a new level. * @param[in] exch IPC exchange connected to the device. * @param[in] item The control item controlling the channel. * @param[in] level The new value. * @return Error code. */ int audio_mixer_set_item_level(async_exch_t *exch, unsigned item, unsigned level) { if (!exch) return EINVAL; return async_req_3_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL, item, level); }
/** Connect to specified network. * * @param[in] dev_sess Device session. * @param[in] ssid_start Network SSID prefix. * @param[in] password Network password (pass empty string if not needed). * * @return EOK If the operation was successfully completed, * negative error code otherwise. * */ int ieee80211_connect(async_sess_t *dev_sess, char *ssid_start, char *password) { assert(ssid_start); sysarg_t rc_orig; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t aid = async_send_1(exch, DEV_IFACE_ID(IEEE80211_DEV_IFACE), IEEE80211_CONNECT, NULL); sysarg_t rc = async_data_write_start(exch, ssid_start, str_size(ssid_start) + 1); if (rc != EOK) { async_exchange_end(exch); async_wait_for(aid, &rc_orig); if (rc_orig == EOK) return (int) rc; return (int) rc_orig; } // FIXME: Typecasting string literal if (password == NULL) password = (char *) ""; rc = async_data_write_start(exch, password, str_size(password) + 1); if (rc != EOK) { async_exchange_end(exch); async_wait_for(aid, &rc_orig); if (rc_orig == EOK) return (int) rc; return (int) rc_orig; } async_exchange_end(exch); async_wait_for(aid, &rc); if (rc != EOK) return rc; /* Send DHCP discover. */ nic_address_t wifi_mac; rc = nic_get_address(dev_sess, &wifi_mac); if (rc != EOK) return rc; sysarg_t link_id = get_link_id(wifi_mac.address); if (link_id == ((sysarg_t) -1)) return EINVAL; rc = dhcp_discover(link_id); return (int) rc; }
int pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val) { async_exch_t *exch = async_exchange_begin(sess); int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), IPC_M_CONFIG_SPACE_WRITE_8, address, val); async_exchange_end(exch); return rc; }
/** Set which offload computations can be performed on the NIC. * * @param[in] dev_sess * @param[in] mask Mask for the options (only those set here will be set) * @param[in] active Which options should be enabled and which disabled * * @return EOK If the operation was successfully completed * */ int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active); async_exchange_end(exch); return rc; }
/** Remove Wake-On-LAN virtue. * * @param[in] dev_sess * @param[in] id Virtue identifier * * @return EOK If the operation was successfully completed * */ int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id); async_exchange_end(exch); return rc; }
/** Request the device to change its state * * @param[in] dev_sess * @param[in] state New state * * @return EOK If the operation was successfully completed * */ int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SET_STATE, state); async_exchange_end(exch); return rc; }
/** Set VLAN (802.1q) tag. * * Set whether the tag is to be signaled in offload info and * if the tag should be stripped from received frames and added * to sent frames automatically. Not every combination of add * and strip must be supported. * * @param[in] dev_sess * @param[in] tag VLAN priority (top 3 bits) and * the VLAN tag (bottom 12 bits) * @param[in] add Add the VLAN tag automatically (boolean) * @param[in] strip Strip the VLAN tag automatically (boolean) * * @return EOK If the operation was successfully completed * */ int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip); async_exchange_end(exch); return rc; }
/** Set whether defective (erroneous) packets are received. * * @param[in] dev_sess * @param[out] mode Bitmask specifying allowed errors * * @return EOK If the operation was successfully completed * */ int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_DEFECTIVE_SET_MODE, mode); async_exchange_end(exch); return rc; }
/** Set whether broadcast packets are received. * * @param[in] dev_sess * @param[in] mode Current operation mode * * @return EOK If the operation was successfully completed * */ int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_BROADCAST_SET_MODE, mode); async_exchange_end(exch); return rc; }
/** Enable auto-negotiation. * * The advertisement argument can only limit some modes, * it can never force the NIC to advertise unsupported modes. * * The allowed modes are defined in "nic/eth_phys.h" in the C library. * * @param[in] dev_sess * @param[in] advertisement Allowed advertised modes. Use 0 for all modes. * * @return EOK If the operation was successfully completed * */ int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_AUTONEG_ENABLE, (sysarg_t) advertisement); async_exchange_end(exch); return rc; }
/** Disable auto-negotiation. * * @param[in] dev_sess * * @return EOK If the operation was successfully completed * */ int nic_autoneg_disable(async_sess_t *dev_sess) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_AUTONEG_DISABLE); async_exchange_end(exch); return rc; }
/** Restart the auto-negotiation process. * * @param[in] dev_sess * * @return EOK If the operation was successfully completed * */ int nic_autoneg_restart(async_sess_t *dev_sess) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_AUTONEG_RESTART); async_exchange_end(exch); return rc; }
/** Control sending and reception of the PAUSE frame. * * @param[in] dev_sess * @param[in] allow_send Allow sending the PAUSE frame (true/false) * @param[in] allow_receive Allow reception of the PAUSE frame (true/false) * @param[in] pause Pause length in 512 bit units written * to transmitted frames. The value 0 means * auto value (the best). If the requested * time cannot be set the driver is allowed * to set the nearest supported value. * * @return EOK If the operation was successfully completed * */ int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive, uint16_t pause) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SET_PAUSE, allow_send, allow_receive, pause); async_exchange_end(exch); return rc; }
/** Set current operation mode. * * If the NIC has auto-negotiation enabled, this command * disables auto-negotiation and sets the operation mode. * * @param[in] dev_sess * @param[in] speed Operation speed in Mbps * @param[in] duplex Full duplex/half duplex * @param[in] role Master/slave/auto (e.g. in Gbit Ethernet] * * @return EOK If the operation was successfully completed * */ int nic_set_operation_mode(async_sess_t *dev_sess, int speed, nic_channel_mode_t duplex, nic_role_t role) { async_exch_t *exch = async_exchange_begin(dev_sess); int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex, (sysarg_t) role); async_exchange_end(exch); return rc; }
int pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val) { sysarg_t res = 0; async_exch_t *exch = async_exchange_begin(sess); int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE), IPC_M_CONFIG_SPACE_READ_8, address, &res); async_exchange_end(exch); *val = (uint8_t) res; return rc; }
/** * Get current level of a control item. * @param[in] exch IPC exchange connected to the device. * @param[in] item The control item controlling the channel. * @param[in] channel The channel index. * @param[out] level Currently set value. * @return Error code. */ int audio_mixer_get_item_level(async_exch_t *exch, unsigned item, unsigned *level) { if (!exch) return EINVAL; sysarg_t current; const int ret = async_req_2_1(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL, item, ¤t); if (ret == EOK && level) *level = current; return ret; }
int led_dev_color_set(async_sess_t *sess, pixel_t pixel) { async_exch_t *exch = async_exchange_begin(sess); aid_t req = async_send_2(exch, DEV_IFACE_ID(LED_DEV_IFACE), LED_DEV_COLOR_SET, (sysarg_t) pixel, NULL); async_exchange_end(exch); sysarg_t rc; async_wait_for(req, &rc); return (int) rc; }
/** Read to or write from device. * * Helper function to read to or write from a device * using its character interface. * * @param sess Session to the device. * @param buf Buffer for the data read from or written to the device. * @param size Maximum size of data (in bytes) to be read or written. * @param read Read from the device if true, write to it otherwise. * * @return Non-negative number of bytes actually read from or * written to the device on success, negative error number * otherwise. * */ static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read) { ipc_call_t answer; aid_t req; int ret; async_exch_t *exch = async_exchange_begin(sess); if (read) { req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_DEV_READ, &answer); ret = async_data_read_start(exch, buf, size); } else { req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_DEV_WRITE, &answer); ret = async_data_write_start(exch, buf, size); } async_exchange_end(exch); sysarg_t rc; if (ret != EOK) { async_wait_for(req, &rc); if (rc == EOK) return (ssize_t) ret; return (ssize_t) rc; } async_wait_for(req, &rc); ret = (int) rc; if (ret != EOK) return (ssize_t) ret; return (ssize_t) IPC_GET_ARG1(answer); }