Changeset cfb79747 in mainline for uspace/lib
- Timestamp:
- 2012-02-14T22:06:15Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a31aad1
- Parents:
- 199112e4 (diff), e10d41a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 4 added
- 32 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/device/nic.c
r199112e4 rcfb79747 73 73 } 74 74 75 /** Connect the driver to the NET and NIL services 76 * 77 * @param[in] dev_sess 78 * @param[in] nil_service Service identifier for the NIL service 75 /** Create callback connection from NIC service 76 * 77 * @param[in] dev_sess 79 78 * @param[in] device_id 80 79 * … … 82 81 * 83 82 */ 84 int nic_connect_to_nil(async_sess_t *dev_sess, services_t nil_service, 85 nic_device_id_t device_id) 86 { 87 async_exch_t *exch = async_exchange_begin(dev_sess); 88 int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 89 NIC_CONNECT_TO_NIL, nil_service, device_id); 90 async_exchange_end(exch); 91 92 return rc; 83 int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun, 84 void *carg) 85 { 86 ipc_call_t answer; 87 int rc; 88 sysarg_t retval; 89 90 async_exch_t *exch = async_exchange_begin(dev_sess); 91 aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), 92 NIC_CALLBACK_CREATE, &answer); 93 94 rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg); 95 if (rc != EOK) { 96 async_wait_for(req, NULL); 97 return rc; 98 } 99 async_exchange_end(exch); 100 101 async_wait_for(req, &retval); 102 return (int) retval; 93 103 } 94 104 … … 335 345 * it can never force the NIC to advertise unsupported modes. 336 346 * 337 * The allowed modes are defined in "n et/eth_phys.h" in the C library.347 * The allowed modes are defined in "nic/eth_phys.h" in the C library. 338 348 * 339 349 * @param[in] dev_sess … … 372 382 /** Probe current state of auto-negotiation. 373 383 * 374 * Modes are defined in the "n et/eth_phys.h" in the C library.384 * Modes are defined in the "nic/eth_phys.h" in the C library. 375 385 * 376 386 * @param[in] dev_sess -
uspace/lib/c/generic/loc.c
r199112e4 rcfb79747 47 47 static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex); 48 48 static bool loc_callback_created = false; 49 static loc_cat_change_cb_t cat_change_cb = NULL; 49 50 50 51 static async_sess_t *loc_supp_block_sess = NULL; … … 54 55 static async_sess_t *loc_consumer_sess = NULL; 55 56 56 static loc_cat_change_cb_t cat_change_cb = NULL;57 58 57 static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 59 58 { 60 loc_cat_change_cb_t cb_fun;61 62 59 while (true) { 63 60 ipc_call_t call; … … 69 66 } 70 67 71 int retval;72 73 68 switch (IPC_GET_IMETHOD(call)) { 74 69 case LOC_EVENT_CAT_CHANGE: 75 70 fibril_mutex_lock(&loc_callback_mutex); 76 cb_fun = cat_change_cb; 77 if (cb_fun != NULL) { 71 loc_cat_change_cb_t cb_fun = cat_change_cb; 72 fibril_mutex_unlock(&loc_callback_mutex); 73 74 async_answer_0(callid, EOK); 75 76 if (cb_fun != NULL) 78 77 (*cb_fun)(); 79 } 80 fibril_mutex_unlock(&loc_callback_mutex); 81 retval = 0; 78 82 79 break; 83 80 default: 84 retval = ENOTSUP;81 async_answer_0(callid, ENOTSUP); 85 82 } 86 87 async_answer_0(callid, retval);88 83 } 89 84 } … … 101 96 } 102 97 98 /** Create callback 99 * 100 * Must be called with loc_callback_mutex locked. 101 * 102 * @return EOK on success. 103 * 104 */ 103 105 static int loc_callback_create(void) 104 106 { 105 async_exch_t *exch;106 sysarg_t retval;107 int rc = EOK;108 109 fibril_mutex_lock(&loc_callback_mutex);110 111 107 if (!loc_callback_created) { 112 exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); 108 async_exch_t *exch = 109 loc_exchange_begin_blocking(LOC_PORT_CONSUMER); 113 110 114 111 ipc_call_t answer; 115 112 aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer); 116 async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);113 int rc = async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL); 117 114 loc_exchange_end(exch); 118 115 116 if (rc != EOK) 117 return rc; 118 119 sysarg_t retval; 119 120 async_wait_for(req, &retval); 120 if (rc != EOK) 121 goto done; 122 123 if (retval != EOK) { 124 rc = retval; 125 goto done; 126 } 121 if (retval != EOK) 122 return retval; 127 123 128 124 loc_callback_created = true; 129 125 } 130 126 131 rc = EOK; 132 done: 133 fibril_mutex_unlock(&loc_callback_mutex); 134 return rc; 127 return EOK; 135 128 } 136 129 … … 795 788 sysarg_t **data, size_t *count) 796 789 { 797 service_id_t *ids;798 size_t act_size;799 size_t alloc_size;800 int rc;801 802 790 *data = NULL; 803 act_size = 0; /* silence warning */ 804 805 rc = loc_category_get_ids_once(method, arg1, NULL, 0, 791 *count = 0; 792 793 size_t act_size = 0; 794 int rc = loc_category_get_ids_once(method, arg1, NULL, 0, 806 795 &act_size); 807 796 if (rc != EOK) 808 797 return rc; 809 810 alloc_size = act_size;811 ids = malloc(alloc_size);798 799 size_t alloc_size = act_size; 800 service_id_t *ids = malloc(alloc_size); 812 801 if (ids == NULL) 813 802 return ENOMEM; 814 803 815 804 while (true) { 816 805 rc = loc_category_get_ids_once(method, arg1, ids, alloc_size, … … 818 807 if (rc != EOK) 819 808 return rc; 820 809 821 810 if (act_size <= alloc_size) 822 811 break; 823 824 alloc_size *= 2; 825 free(ids); 826 827 ids = malloc(alloc_size); 812 813 alloc_size = act_size; 814 ids = realloc(ids, alloc_size); 828 815 if (ids == NULL) 829 816 return ENOMEM; 830 817 } 831 818 832 819 *count = act_size / sizeof(category_id_t); 833 820 *data = ids; … … 867 854 int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun) 868 855 { 869 if (loc_callback_create() != EOK) 856 fibril_mutex_lock(&loc_callback_mutex); 857 if (loc_callback_create() != EOK) { 858 fibril_mutex_unlock(&loc_callback_mutex); 870 859 return EIO; 871 860 } 861 872 862 cat_change_cb = cb_fun; 863 fibril_mutex_unlock(&loc_callback_mutex); 864 873 865 return EOK; 874 866 } -
uspace/lib/c/include/device/nic.h
r199112e4 rcfb79747 37 37 38 38 #include <async.h> 39 #include <net/device.h> 40 #include <net/packet.h> 41 #include <ipc/services.h> 39 #include <nic/nic.h> 40 #include <ipc/common.h> 42 41 43 42 typedef enum { 44 43 NIC_SEND_MESSAGE = 0, 45 NIC_C ONNECT_TO_NIL,44 NIC_CALLBACK_CREATE, 46 45 NIC_GET_STATE, 47 46 NIC_SET_STATE, … … 85 84 } nic_funcs_t; 86 85 86 typedef enum { 87 NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD, 88 NIC_EV_RECEIVED, 89 NIC_EV_DEVICE_STATE 90 } nic_event_t; 91 87 92 extern int nic_send_frame(async_sess_t *, void *, size_t); 88 extern int nic_c onnect_to_nil(async_sess_t *, services_t, nic_device_id_t);93 extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *); 89 94 extern int nic_get_state(async_sess_t *, nic_device_state_t *); 90 95 extern int nic_set_state(async_sess_t *, nic_device_state_t); -
uspace/lib/c/include/ipc/devman.h
r199112e4 rcfb79747 146 146 typedef enum { 147 147 DRIVER_DEV_ADD = IPC_FIRST_USER_METHOD, 148 DRIVER_DEV_ADDED,149 148 DRIVER_DEV_REMOVE, 150 149 DRIVER_DEV_GONE, -
uspace/lib/c/include/ipc/net.h
r199112e4 rcfb79747 305 305 * 306 306 */ 307 #define IPC_GET_DEVICE_HANDLE(call) (( devman_handle_t) IPC_GET_ARG2(call))307 #define IPC_GET_DEVICE_HANDLE(call) ((service_id_t) IPC_GET_ARG2(call)) 308 308 309 309 /** Return the device driver service message argument. -
uspace/lib/c/include/ipc/net_net.h
r199112e4 rcfb79747 54 54 NET_NET_GET_DEVICES_COUNT, 55 55 /** Return names and device IDs of all devices */ 56 NET_NET_GET_DEVICES, 57 /** Notify the networking service about a ready device */ 58 NET_NET_DRIVER_READY 56 NET_NET_GET_DEVICES 59 57 } net_messages; 60 58 -
uspace/lib/c/include/ipc/nil.h
r199112e4 rcfb79747 46 46 */ 47 47 NET_NIL_DEVICE = NET_NIL_FIRST, 48 /** New device state message.49 * @see nil_device_state_msg()50 */51 NET_NIL_DEVICE_STATE,52 /** Received packet queue message.53 * @see nil_received_msg()54 */55 NET_NIL_RECEIVED,56 48 /** Send packet queue message. 57 49 * @see nil_send_msg() … … 69 61 * @see nil_get_broadcast_addr() 70 62 */ 71 NET_NIL_BROADCAST_ADDR, 72 /** Device has changed address 73 * @see nil_addr_changed_msg() 74 */ 75 NET_NIL_ADDR_CHANGED 63 NET_NIL_BROADCAST_ADDR 76 64 } nil_messages; 77 65 -
uspace/lib/c/include/net/device.h
r199112e4 rcfb79747 1 1 /* 2 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Radim Vansa4 3 * All rights reserved. 5 4 * … … 33 32 34 33 /** @file 35 * Device identifier, state and usage statistics.34 * Network device. 36 35 */ 37 36 38 #ifndef LIBC_ DEVICE_ID_TYPE_H_39 #define LIBC_ DEVICE_ID_TYPE_H_37 #ifndef LIBC_NET_DEVICE_H_ 38 #define LIBC_NET_DEVICE_H_ 40 39 41 40 #include <adt/int_map.h> 42 #include <net/eth_phys.h> 43 #include <bool.h> 44 45 /** Ethernet address length. */ 46 #define ETH_ADDR 6 47 48 /** MAC printing format */ 49 #define PRIMAC "%02x:%02x:%02x:%02x:%02x:%02x" 50 51 /** MAC arguments */ 52 #define ARGSMAC(__a) \ 53 (__a)[0], (__a)[1], (__a)[2], (__a)[3], (__a)[4], (__a)[5] 54 55 /* Compare MAC address with specific value */ 56 #define MAC_EQUALS_VALUE(__a, __a0, __a1, __a2, __a3, __a4, __a5) \ 57 ((__a)[0] == (__a0) && (__a)[1] == (__a1) && (__a)[2] == (__a2) \ 58 && (__a)[3] == (__a3) && (__a)[4] == (__a4) && (__a)[5] == (__a5)) 59 60 #define MAC_IS_ZERO(__x) \ 61 MAC_EQUALS_VALUE(__x, 0, 0, 0, 0, 0, 0) 41 #include <nic/nic.h> 62 42 63 43 /** Device identifier to generic type map declaration. */ … … 67 47 #define DEVICE_MAP_IMPLEMENT INT_MAP_IMPLEMENT 68 48 69 /** Max length of any hw nic address (currently only eth)*/70 #define NIC_MAX_ADDRESS_LENGTH 16 49 /** Device identifier type. */ 50 typedef int nic_device_id_t; 71 51 72 52 /** Invalid device identifier. */ 73 53 #define NIC_DEVICE_INVALID_ID (-1) 74 75 #define NIC_VENDOR_MAX_LENGTH 6476 #define NIC_MODEL_MAX_LENGTH 6477 #define NIC_PART_NUMBER_MAX_LENGTH 6478 #define NIC_SERIAL_NUMBER_MAX_LENGTH 6479 80 #define NIC_DEFECTIVE_LONG 0x000181 #define NIC_DEFECTIVE_SHORT 0x000282 #define NIC_DEFECTIVE_BAD_CRC 0x001083 #define NIC_DEFECTIVE_BAD_IPV4_CHECKSUM 0x002084 #define NIC_DEFECTIVE_BAD_IPV6_CHECKSUM 0x004085 #define NIC_DEFECTIVE_BAD_TCP_CHECKSUM 0x008086 #define NIC_DEFECTIVE_BAD_UDP_CHECKSUM 0x010087 88 /**89 * The bitmap uses single bit for each of the 2^12 = 4096 possible VLAN tags.90 * This means its size is 4096/8 = 512 bytes.91 */92 #define NIC_VLAN_BITMAP_SIZE 51293 94 #define NIC_DEVICE_PRINT_FMT "%x"95 96 /** Device identifier type. */97 typedef int nic_device_id_t;98 99 /**100 * Structure covering the MAC address.101 */102 typedef struct nic_address {103 uint8_t address[ETH_ADDR];104 } nic_address_t;105 106 /** Device state. */107 typedef enum nic_device_state {108 /**109 * Device present and stopped. Moving device to this state means to discard110 * all settings and WOL virtues, rebooting the NIC to state as if the111 * computer just booted (or the NIC was just inserted in case of removable112 * NIC).113 */114 NIC_STATE_STOPPED,115 /**116 * If the NIC is in this state no packets (frames) are transmitted nor117 * received. However, the settings are not restarted. You can use this state118 * to temporarily disable transmition/reception or atomically (with respect119 * to incoming/outcoming packets) change frames acceptance etc.120 */121 NIC_STATE_DOWN,122 /** Device is normally operating. */123 NIC_STATE_ACTIVE,124 /** Just a constant to limit the state numbers */125 NIC_STATE_MAX,126 } nic_device_state_t;127 128 /**129 * Channel operating mode used on the medium.130 */131 typedef enum {132 NIC_CM_UNKNOWN,133 NIC_CM_FULL_DUPLEX,134 NIC_CM_HALF_DUPLEX,135 NIC_CM_SIMPLEX136 } nic_channel_mode_t;137 138 /**139 * Role for the device (used e.g. for 1000Gb ethernet)140 */141 typedef enum {142 NIC_ROLE_UNKNOWN,143 NIC_ROLE_AUTO,144 NIC_ROLE_MASTER,145 NIC_ROLE_SLAVE146 } nic_role_t;147 148 /**149 * Current state of the cable in the device150 */151 typedef enum {152 NIC_CS_UNKNOWN,153 NIC_CS_PLUGGED,154 NIC_CS_UNPLUGGED155 } nic_cable_state_t;156 157 /**158 * Result of the requested operation159 */160 typedef enum {161 /** Successfully disabled */162 NIC_RESULT_DISABLED,163 /** Successfully enabled */164 NIC_RESULT_ENABLED,165 /** Not supported at all */166 NIC_RESULT_NOT_SUPPORTED,167 /** Temporarily not available */168 NIC_RESULT_NOT_AVAILABLE,169 /** Result extensions */170 NIC_RESULT_FIRST_EXTENSION171 } nic_result_t;172 173 /** Device usage statistics. */174 typedef struct nic_device_stats {175 /** Total packets received (accepted). */176 unsigned long receive_packets;177 /** Total packets transmitted. */178 unsigned long send_packets;179 /** Total bytes received (accepted). */180 unsigned long receive_bytes;181 /** Total bytes transmitted. */182 unsigned long send_bytes;183 /** Bad packets received counter. */184 unsigned long receive_errors;185 /** Packet transmition problems counter. */186 unsigned long send_errors;187 /** Number of frames dropped due to insufficient space in RX buffers */188 unsigned long receive_dropped;189 /** Number of frames dropped due to insufficient space in TX buffers */190 unsigned long send_dropped;191 /** Total multicast packets received (accepted). */192 unsigned long receive_multicast;193 /** Total broadcast packets received (accepted). */194 unsigned long receive_broadcast;195 /** The number of collisions due to congestion on the medium. */196 unsigned long collisions;197 /** Unicast packets received but not accepted (filtered) */198 unsigned long receive_filtered_unicast;199 /** Multicast packets received but not accepted (filtered) */200 unsigned long receive_filtered_multicast;201 /** Broadcast packets received but not accepted (filtered) */202 unsigned long receive_filtered_broadcast;203 204 /* detailed receive_errors */205 206 /** Received packet length error counter. */207 unsigned long receive_length_errors;208 /** Receiver buffer overflow counter. */209 unsigned long receive_over_errors;210 /** Received packet with crc error counter. */211 unsigned long receive_crc_errors;212 /** Received frame alignment error counter. */213 unsigned long receive_frame_errors;214 /** Receiver fifo overrun counter. */215 unsigned long receive_fifo_errors;216 /** Receiver missed packet counter. */217 unsigned long receive_missed_errors;218 219 /* detailed send_errors */220 221 /** Transmitter aborted counter. */222 unsigned long send_aborted_errors;223 /** Transmitter carrier errors counter. */224 unsigned long send_carrier_errors;225 /** Transmitter fifo overrun counter. */226 unsigned long send_fifo_errors;227 /** Transmitter carrier errors counter. */228 unsigned long send_heartbeat_errors;229 /** Transmitter window errors counter. */230 unsigned long send_window_errors;231 232 /* for cslip etc */233 234 /** Total compressed packets received. */235 unsigned long receive_compressed;236 /** Total compressed packet transmitted. */237 unsigned long send_compressed;238 } nic_device_stats_t;239 240 /** Errors corresponding to those in the nic_device_stats_t */241 typedef enum {242 NIC_SEC_BUFFER_FULL,243 NIC_SEC_ABORTED,244 NIC_SEC_CARRIER_LOST,245 NIC_SEC_FIFO_OVERRUN,246 NIC_SEC_HEARTBEAT,247 NIC_SEC_WINDOW_ERROR,248 /* Error encountered during TX but with other type of error */249 NIC_SEC_OTHER250 } nic_send_error_cause_t;251 252 /** Errors corresponding to those in the nic_device_stats_t */253 typedef enum {254 NIC_REC_BUFFER_FULL,255 NIC_REC_LENGTH,256 NIC_REC_BUFFER_OVERFLOW,257 NIC_REC_CRC,258 NIC_REC_FRAME_ALIGNMENT,259 NIC_REC_FIFO_OVERRUN,260 NIC_REC_MISSED,261 /* Error encountered during RX but with other type of error */262 NIC_REC_OTHER263 } nic_receive_error_cause_t;264 265 /**266 * Information about the NIC that never changes - name, vendor, model,267 * capabilites and so on.268 */269 typedef struct nic_device_info {270 /* Device identification */271 char vendor_name[NIC_VENDOR_MAX_LENGTH];272 char model_name[NIC_MODEL_MAX_LENGTH];273 char part_number[NIC_PART_NUMBER_MAX_LENGTH];274 char serial_number[NIC_SERIAL_NUMBER_MAX_LENGTH];275 uint16_t vendor_id;276 uint16_t device_id;277 uint16_t subsystem_vendor_id;278 uint16_t subsystem_id;279 /* Device capabilities */280 uint16_t ethernet_support[ETH_PHYS_LAYERS];281 282 /** The mask of all modes which the device can advertise283 *284 * see ETH_AUTONEG_ macros in net/eth_phys.h of libc285 */286 uint32_t autoneg_support;287 } nic_device_info_t;288 289 /**290 * Type of the ethernet frame291 */292 typedef enum nic_frame_type {293 NIC_FRAME_UNICAST,294 NIC_FRAME_MULTICAST,295 NIC_FRAME_BROADCAST296 } nic_frame_type_t;297 298 /**299 * Specifies which unicast frames is the NIC receiving.300 */301 typedef enum nic_unicast_mode {302 NIC_UNICAST_UNKNOWN,303 /** No unicast frames are received */304 NIC_UNICAST_BLOCKED,305 /** Only the frames with this NIC's MAC as destination are received */306 NIC_UNICAST_DEFAULT,307 /**308 * Both frames with this NIC's MAC and those specified in the list are309 * received310 */311 NIC_UNICAST_LIST,312 /** All unicast frames are received */313 NIC_UNICAST_PROMISC314 } nic_unicast_mode_t;315 316 typedef enum nic_multicast_mode {317 NIC_MULTICAST_UNKNOWN,318 /** No multicast frames are received */319 NIC_MULTICAST_BLOCKED,320 /** Frames with multicast addresses specified in this list are received */321 NIC_MULTICAST_LIST,322 /** All multicast frames are received */323 NIC_MULTICAST_PROMISC324 } nic_multicast_mode_t;325 326 typedef enum nic_broadcast_mode {327 NIC_BROADCAST_UNKNOWN,328 /** Broadcast frames are dropped */329 NIC_BROADCAST_BLOCKED,330 /** Broadcast frames are received */331 NIC_BROADCAST_ACCEPTED332 } nic_broadcast_mode_t;333 334 /**335 * Structure covering the bitmap with VLAN tags.336 */337 typedef struct nic_vlan_mask {338 uint8_t bitmap[NIC_VLAN_BITMAP_SIZE];339 } nic_vlan_mask_t;340 341 /* WOL virtue identifier */342 typedef unsigned int nic_wv_id_t;343 344 /**345 * Structure passed as argument for virtue NIC_WV_MAGIC_PACKET.346 */347 typedef struct nic_wv_magic_packet_data {348 uint8_t password[6];349 } nic_wv_magic_packet_data_t;350 351 /**352 * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV4353 */354 typedef struct nic_wv_ipv4_data {355 uint8_t address[4];356 } nic_wv_ipv4_data_t;357 358 /**359 * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV6360 */361 typedef struct nic_wv_ipv6_data {362 uint8_t address[16];363 } nic_wv_ipv6_data_t;364 365 /**366 * WOL virtue types defining the interpretation of data passed to the virtue.367 * Those tagged with S can have only single virtue active at one moment, those368 * tagged with M can have multiple ones.369 */370 typedef enum nic_wv_type {371 /**372 * Used for deletion of the virtue - in this case the mask, data and length373 * arguments are ignored.374 */375 NIC_WV_NONE,376 /** S377 * Enabled <=> wakeup upon link change378 */379 NIC_WV_LINK_CHANGE,380 /** S381 * If this virtue is set up, wakeup can be issued by a magic packet frame.382 * If the data argument is not NULL, it must contain383 * nic_wv_magic_packet_data structure with the SecureOn password.384 */385 NIC_WV_MAGIC_PACKET,386 /** M387 * If the virtue is set up, wakeup can be issued by a frame targeted to388 * device with MAC address specified in data. The data must contain389 * nic_address_t structure.390 */391 NIC_WV_DESTINATION,392 /** S393 * Enabled <=> wakeup upon receiving broadcast frame394 */395 NIC_WV_BROADCAST,396 /** S397 * Enabled <=> wakeup upon receiving ARP Request398 */399 NIC_WV_ARP_REQUEST,400 /** M401 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet402 * with IPv4 address specified in data. The data must contain403 * nic_wv_ipv4_data structure.404 */405 NIC_WV_DIRECTED_IPV4,406 /** M407 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet408 * with IPv6 address specified in data. The data must contain409 * nic_wv_ipv6_data structure.410 */411 NIC_WV_DIRECTED_IPV6,412 /** M413 * First length/2 bytes in the argument are interpreted as mask, second414 * length/2 bytes are interpreted as content.415 * If enabled, the wakeup is issued upon receiving frame where the bytes416 * with non-zero value in the mask equal to those in the content.417 */418 NIC_WV_FULL_MATCH,419 /**420 * Dummy value, do not use.421 */422 NIC_WV_MAX423 } nic_wv_type_t;424 425 /**426 * Specifies the interrupt/polling mode used by the driver and NIC427 */428 typedef enum nic_poll_mode {429 /**430 * NIC issues interrupts upon events.431 */432 NIC_POLL_IMMEDIATE,433 /**434 * Some uspace app calls nic_poll_now(...) in order to check the NIC state435 * - no interrupts are received from the NIC.436 */437 NIC_POLL_ON_DEMAND,438 /**439 * The driver itself issues a poll request in a periodic manner. It is440 * allowed to use hardware timer if the NIC supports it.441 */442 NIC_POLL_PERIODIC,443 /**444 * The driver itself issued a poll request in a periodic manner. The driver445 * must create software timer, internal hardware timer of NIC must not be446 * used even if the NIC supports it.447 */448 NIC_POLL_SOFTWARE_PERIODIC449 } nic_poll_mode_t;450 451 /**452 * Says if this virtue type is a multi-virtue (there can be multiple virtues of453 * this type at once).454 *455 * @param type456 *457 * @return true or false458 */459 static inline int nic_wv_is_multi(nic_wv_type_t type) {460 switch (type) {461 case NIC_WV_FULL_MATCH:462 case NIC_WV_DESTINATION:463 case NIC_WV_DIRECTED_IPV4:464 case NIC_WV_DIRECTED_IPV6:465 return true;466 default:467 return false;468 }469 }470 471 static inline const char *nic_device_state_to_string(nic_device_state_t state)472 {473 switch (state) {474 case NIC_STATE_STOPPED:475 return "stopped";476 case NIC_STATE_DOWN:477 return "down";478 case NIC_STATE_ACTIVE:479 return "active";480 default:481 return "undefined";482 }483 }484 54 485 55 #endif -
uspace/lib/c/include/nic/eth_phys.h
r199112e4 rcfb79747 28 28 */ 29 29 30 #ifndef LIBC_N ET_ETH_PHYS_H_31 #define LIBC_N ET_ETH_PHYS_H_30 #ifndef LIBC_NIC_ETH_PHYS_H_ 31 #define LIBC_NIC_ETH_PHYS_H_ 32 32 33 33 #include <sys/types.h> -
uspace/lib/drv/Makefile
r199112e4 rcfb79747 35 35 generic/driver.c \ 36 36 generic/dev_iface.c \ 37 generic/interrupt.c \ 37 38 generic/log.c \ 38 39 generic/logbuf.c \ -
uspace/lib/drv/generic/driver.c
r199112e4 rcfb79747 70 70 FIBRIL_MUTEX_INITIALIZE(functions_mutex); 71 71 72 /** Interrupts */73 static interrupt_context_list_t interrupt_contexts;74 75 static irq_cmd_t default_cmds[] = {76 {77 .cmd = CMD_ACCEPT78 }79 };80 81 static irq_code_t default_pseudocode = {82 0,83 NULL,84 sizeof(default_cmds) / sizeof(irq_cmd_t),85 default_cmds86 };87 88 72 static ddf_dev_t *create_device(void); 89 73 static void delete_device(ddf_dev_t *); … … 95 79 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); 96 80 97 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)98 {99 int id = (int)IPC_GET_IMETHOD(*icall);100 interrupt_context_t *ctx;101 102 ctx = find_interrupt_context_by_id(&interrupt_contexts, id);103 if (ctx != NULL && ctx->handler != NULL)104 (*ctx->handler)(ctx->dev, iid, icall);105 }106 107 interrupt_context_t *create_interrupt_context(void)108 {109 interrupt_context_t *ctx;110 111 ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));112 if (ctx != NULL)113 memset(ctx, 0, sizeof(interrupt_context_t));114 115 return ctx;116 }117 118 void delete_interrupt_context(interrupt_context_t *ctx)119 {120 if (ctx != NULL)121 free(ctx);122 }123 124 void init_interrupt_context_list(interrupt_context_list_t *list)125 {126 memset(list, 0, sizeof(interrupt_context_list_t));127 fibril_mutex_initialize(&list->mutex);128 list_initialize(&list->contexts);129 }130 131 void132 add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)133 {134 fibril_mutex_lock(&list->mutex);135 ctx->id = list->curr_id++;136 list_append(&ctx->link, &list->contexts);137 fibril_mutex_unlock(&list->mutex);138 }139 140 void remove_interrupt_context(interrupt_context_list_t *list,141 interrupt_context_t *ctx)142 {143 fibril_mutex_lock(&list->mutex);144 list_remove(&ctx->link);145 fibril_mutex_unlock(&list->mutex);146 }147 148 interrupt_context_t *149 find_interrupt_context_by_id(interrupt_context_list_t *list, int id)150 {151 interrupt_context_t *ctx;152 153 fibril_mutex_lock(&list->mutex);154 155 list_foreach(list->contexts, link) {156 ctx = list_get_instance(link, interrupt_context_t, link);157 if (ctx->id == id) {158 fibril_mutex_unlock(&list->mutex);159 return ctx;160 }161 }162 163 fibril_mutex_unlock(&list->mutex);164 return NULL;165 }166 167 interrupt_context_t *168 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)169 {170 interrupt_context_t *ctx;171 172 fibril_mutex_lock(&list->mutex);173 174 list_foreach(list->contexts, link) {175 ctx = list_get_instance(link, interrupt_context_t, link);176 if (ctx->irq == irq && ctx->dev == dev) {177 fibril_mutex_unlock(&list->mutex);178 return ctx;179 }180 }181 182 fibril_mutex_unlock(&list->mutex);183 return NULL;184 }185 186 187 int188 register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,189 irq_code_t *pseudocode)190 {191 interrupt_context_t *ctx = create_interrupt_context();192 193 ctx->dev = dev;194 ctx->irq = irq;195 ctx->handler = handler;196 197 add_interrupt_context(&interrupt_contexts, ctx);198 199 if (pseudocode == NULL)200 pseudocode = &default_pseudocode;201 202 int res = irq_register(irq, dev->handle, ctx->id, pseudocode);203 if (res != EOK) {204 remove_interrupt_context(&interrupt_contexts, ctx);205 delete_interrupt_context(ctx);206 }207 208 return res;209 }210 211 int unregister_interrupt_handler(ddf_dev_t *dev, int irq)212 {213 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,214 dev, irq);215 int res = irq_unregister(irq, dev->handle);216 217 if (ctx != NULL) {218 remove_interrupt_context(&interrupt_contexts, ctx);219 delete_interrupt_context(ctx);220 }221 222 return res;223 }224 225 81 static void add_to_functions_list(ddf_fun_t *fun) 226 82 { … … 303 159 304 160 async_answer_0(iid, res); 305 }306 307 static void driver_dev_added(ipc_callid_t iid, ipc_call_t *icall)308 {309 fibril_mutex_lock(&devices_mutex);310 ddf_dev_t *dev = driver_get_device(IPC_GET_ARG1(*icall));311 fibril_mutex_unlock(&devices_mutex);312 313 if (dev != NULL && driver->driver_ops->device_added != NULL)314 driver->driver_ops->device_added(dev);315 161 } 316 162 … … 462 308 case DRIVER_DEV_ADD: 463 309 driver_dev_add(callid, &call); 464 break;465 case DRIVER_DEV_ADDED:466 async_answer_0(callid, EOK);467 driver_dev_added(callid, &call);468 310 break; 469 311 case DRIVER_DEV_REMOVE: … … 753 595 754 596 /** Allocate driver-specific device data. */ 755 externvoid *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)597 void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size) 756 598 { 757 599 void *data; … … 815 657 816 658 /** Allocate driver-specific function data. */ 817 externvoid *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)659 void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size) 818 660 { 819 661 void *data; … … 1008 850 driver = drv; 1009 851 1010 /* Initialize the list of interrupt contexts. */ 1011 init_interrupt_context_list(&interrupt_contexts); 1012 1013 /* Set generic interrupt handler. */ 1014 async_set_interrupt_received(driver_irq_handler); 852 /* Initialize interrupt module */ 853 interrupt_init(); 1015 854 1016 855 /* -
uspace/lib/drv/generic/remote_nic.c
r199112e4 rcfb79747 63 63 } 64 64 65 static void remote_nic_connect_to_nil(ddf_fun_t *dev, void *iface, 66 ipc_callid_t callid, ipc_call_t *call) 67 { 68 nic_iface_t *nic_iface = (nic_iface_t *) iface; 69 assert(nic_iface->connect_to_nil); 70 71 services_t nil_service = (services_t) IPC_GET_ARG2(*call); 72 nic_device_id_t device_id = (nic_device_id_t) IPC_GET_ARG3(*call); 73 74 int rc = nic_iface->connect_to_nil(dev, nil_service, device_id); 65 static void remote_nic_callback_create(ddf_fun_t *dev, void *iface, 66 ipc_callid_t callid, ipc_call_t *call) 67 { 68 nic_iface_t *nic_iface = (nic_iface_t *) iface; 69 assert(nic_iface->callback_create); 70 71 int rc = nic_iface->callback_create(dev); 75 72 async_answer_0(callid, rc); 76 73 } … … 1203 1200 static remote_iface_func_ptr_t remote_nic_iface_ops[] = { 1204 1201 &remote_nic_send_frame, 1205 &remote_nic_c onnect_to_nil,1202 &remote_nic_callback_create, 1206 1203 &remote_nic_get_state, 1207 1204 &remote_nic_set_state, -
uspace/lib/drv/include/ddf/driver.h
r199112e4 rcfb79747 145 145 /** Ask driver to offline a specific function */ 146 146 int (*fun_offline)(ddf_fun_t *); 147 148 /**149 * Notification that the device was succesfully added.150 * The driver can do any blocking operation without151 * blocking the device manager.152 *153 * XXX REMOVE THIS154 */155 void (*device_added)(ddf_dev_t *dev);156 147 } driver_ops_t; 157 148 -
uspace/lib/drv/include/ddf/interrupt.h
r199112e4 rcfb79747 64 64 } interrupt_context_list_t; 65 65 66 extern interrupt_context_t *create_interrupt_context(void); 67 extern void delete_interrupt_context(interrupt_context_t *); 68 extern void init_interrupt_context_list(interrupt_context_list_t *); 69 extern void add_interrupt_context(interrupt_context_list_t *, 70 interrupt_context_t *); 71 extern void remove_interrupt_context(interrupt_context_list_t *, 72 interrupt_context_t *); 73 extern interrupt_context_t *find_interrupt_context_by_id( 74 interrupt_context_list_t *, int); 75 extern interrupt_context_t *find_interrupt_context( 76 interrupt_context_list_t *, ddf_dev_t *, int); 77 66 extern void interrupt_init(void); 78 67 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *, 79 68 irq_code_t *); -
uspace/lib/drv/include/ops/nic.h
r199112e4 rcfb79747 38 38 39 39 #include <ipc/services.h> 40 #include <n et/device.h>40 #include <nic/nic.h> 41 41 #include <sys/time.h> 42 42 … … 46 46 /** Mandatory methods */ 47 47 int (*send_frame)(ddf_fun_t *, void *, size_t); 48 int (*c onnect_to_nil)(ddf_fun_t *, services_t, nic_device_id_t);48 int (*callback_create)(ddf_fun_t *); 49 49 int (*get_state)(ddf_fun_t *, nic_device_state_t *); 50 50 int (*set_state)(ddf_fun_t *, nic_device_state_t); -
uspace/lib/drv/include/usbhc_iface.h
r199112e4 rcfb79747 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 */ 29 29 30 /** @addtogroup libdrv 30 31 * @addtogroup usb 31 32 * @{ 32 33 */ 34 33 35 /** @file 34 36 * @brief USB host controller interface definition. -
uspace/lib/net/generic/net_checksum.c
r199112e4 rcfb79747 45 45 #define CRC_DIVIDER_LE 0xedb88320 46 46 47 /** Polynomial used in multicast address hashing */48 #define CRC_MCAST_POLYNOMIAL 0x04c11db649 50 47 /** Compacts the computed checksum to the 16 bit number adding the carries. 51 48 * … … 224 221 } 225 222 226 /** Compute the standard hash from MAC227 *228 * Hashing MAC into 64 possible values and using the value as index to229 * 64bit number.230 *231 * The code is copied from qemu-0.13's implementation of ne2000 and rt8139232 * drivers, but according to documentation there it originates in FreeBSD.233 *234 * @param[in] addr The 6-byte MAC address to be hashed235 *236 * @return 64-bit number with only single bit set to 1237 *238 */239 uint64_t multicast_hash(const uint8_t addr[6])240 {241 uint32_t crc;242 int carry, i, j;243 uint8_t b;244 245 crc = 0xffffffff;246 for (i = 0; i < 6; i++) {247 b = addr[i];248 for (j = 0; j < 8; j++) {249 carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);250 crc <<= 1;251 b >>= 1;252 if (carry)253 crc = ((crc ^ CRC_MCAST_POLYNOMIAL) | carry);254 }255 }256 257 uint64_t one64 = 1;258 return one64 << (crc >> 26);259 }260 261 223 /** @} 262 224 */ -
uspace/lib/net/generic/net_remote.c
r199112e4 rcfb79747 167 167 } 168 168 169 int net_driver_ready(async_sess_t *sess, devman_handle_t handle)170 {171 async_exch_t *exch = async_exchange_begin(sess);172 int rc = async_req_1_0(exch, NET_NET_DRIVER_READY, handle);173 async_exchange_end(exch);174 175 return rc;176 }177 178 169 /** @} 179 170 */ -
uspace/lib/net/include/net_checksum.h
r199112e4 rcfb79747 67 67 extern uint16_t flip_checksum(uint16_t); 68 68 extern uint16_t ip_checksum(uint8_t *, size_t); 69 extern uint64_t multicast_hash(const uint8_t addr[6]);70 69 71 70 #endif -
uspace/lib/net/include/net_interface.h
r199112e4 rcfb79747 52 52 extern int net_get_devices_req(async_sess_t *, measured_string_t **, size_t *, 53 53 uint8_t **); 54 extern int net_driver_ready(async_sess_t *, devman_handle_t);55 54 extern async_sess_t *net_connect_module(void); 56 55 -
uspace/lib/net/include/nil_remote.h
r199112e4 rcfb79747 34 34 #define __NET_NIL_REMOTE_H__ 35 35 36 #include <ipc/loc.h> 36 37 #include <net/device.h> 37 38 #include <net/packet.h> … … 39 40 #include <generic.h> 40 41 #include <async.h> 42 #include <sys/types.h> 41 43 42 44 #define nil_bind_service(service, device_id, me, receiver) \ … … 60 62 extern int nil_device_req(async_sess_t *, nic_device_id_t, devman_handle_t, 61 63 size_t); 62 extern int nil_device_state_msg(async_sess_t *, nic_device_id_t, sysarg_t);63 extern int nil_received_msg(async_sess_t *, nic_device_id_t, packet_id_t);64 extern int nil_addr_changed_msg(async_sess_t *, nic_device_id_t,65 const nic_address_t *);66 64 67 65 #endif -
uspace/lib/net/nil/nil_remote.c
r199112e4 rcfb79747 36 36 */ 37 37 38 #include <ipc/loc.h> 38 39 #include <nil_remote.h> 39 40 #include <generic.h> … … 43 44 #include <ipc/nil.h> 44 45 45 /** Notify the network interface layer about the device state change.46 *47 * @param[in] sess Network interface layer session.48 * @param[in] device_id Device identifier.49 * @param[in] state New device state.50 *51 * @return EOK on success.52 * @return Other error codes as defined for each specific module53 * device state function.54 *55 */56 int nil_device_state_msg(async_sess_t *sess, nic_device_id_t device_id,57 sysarg_t state)58 {59 return generic_device_state_msg_remote(sess, NET_NIL_DEVICE_STATE,60 device_id, state, 0);61 }62 63 /** Pass the packet queue to the network interface layer.64 *65 * Process and redistribute the received packet queue to the registered66 * upper layers.67 *68 * @param[in] sess Network interface layer session.69 * @param[in] device_id Source device identifier.70 * @param[in] packet Received packet or the received packet queue.71 * @param[in] target Target service. Ignored parameter.72 *73 * @return EOK on success.74 * @return Other error codes as defined for each specific module75 * received function.76 *77 */78 int nil_received_msg(async_sess_t *sess, nic_device_id_t device_id,79 packet_id_t packet_id)80 {81 return generic_received_msg_remote(sess, NET_NIL_RECEIVED,82 device_id, packet_id, 0, 0);83 }84 85 /** Notify upper layers that device address has changed86 *87 */88 int nil_addr_changed_msg(async_sess_t *sess, nic_device_id_t device_id,89 const nic_address_t *address)90 {91 assert(sess);92 93 async_exch_t *exch = async_exchange_begin(sess);94 95 aid_t message_id = async_send_1(exch, NET_NIL_ADDR_CHANGED,96 (sysarg_t) device_id, NULL);97 int rc = async_data_write_start(exch, address, sizeof (nic_address_t));98 99 async_exchange_end(exch);100 101 sysarg_t res;102 async_wait_for(message_id, &res);103 104 if (rc != EOK)105 return rc;106 107 return (int) res;108 }109 110 46 int nil_device_req(async_sess_t *sess, nic_device_id_t device_id, 111 devman_handle_t handle, size_t mtu)47 service_id_t sid, size_t mtu) 112 48 { 113 49 async_exch_t *exch = async_exchange_begin(sess); 114 50 int rc = async_req_3_0(exch, NET_NIL_DEVICE, (sysarg_t) device_id, 115 (sysarg_t) handle, (sysarg_t) mtu);51 (sysarg_t) sid, (sysarg_t) mtu); 116 52 async_exchange_end(exch); 117 53 return rc; -
uspace/lib/nic/Makefile
r199112e4 rcfb79747 29 29 USPACE_PREFIX = ../.. 30 30 LIBRARY = libnic 31 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a 32 EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include 31 EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include 33 32 34 33 SOURCES = \ 35 34 src/nic_driver.c \ 35 src/nic_ev.c \ 36 36 src/nic_addr_db.c \ 37 37 src/nic_rx_control.c \ -
uspace/lib/nic/include/nic.h
r199112e4 rcfb79747 42 42 #include <ddf/driver.h> 43 43 #include <device/hw_res_parsed.h> 44 #include <net/packet.h>45 44 #include <ops/nic.h> 45 46 #define DEVICE_CATEGORY_NIC "nic" 46 47 47 48 struct nic; … … 61 62 62 63 /** 63 * Simple structure for sending the allocated frames (packets) in a list.64 * Simple structure for sending lists of frames. 64 65 */ 65 66 typedef struct { 66 67 link_t link; 67 packet_t *packet; 68 void *data; 69 size_t size; 68 70 } nic_frame_t; 69 71 … … 71 73 72 74 /** 73 * Handler for writing packetdata to the NIC device.74 * The function is responsible for releasing the packet.75 * Handler for writing frame data to the NIC device. 76 * The function is responsible for releasing the frame. 75 77 * It does not return anything, if some error is detected the function just 76 78 * silently fails (logging on debug level is suggested). … … 158 160 * @return ENOTSUP If this filter cannot work on this NIC (e.g. the NIC 159 161 * cannot run in promiscuous node or the limit of WOL 160 * packets' specifications was reached).162 * frames' specifications was reached). 161 163 * @return ELIMIT If this filter must implemented in HW but currently the 162 164 * limit of these HW filters was reached. … … 204 206 /* Functions called in add_device */ 205 207 extern int nic_connect_to_services(nic_t *); 206 extern int nic_register_as_ddf_fun(nic_t *, ddf_dev_ops_t *);207 208 extern int nic_get_resources(nic_t *, hw_res_list_parsed_t *); 208 209 extern void nic_set_specific(nic_t *, void *); … … 219 220 poll_mode_change_handler, poll_request_handler); 220 221 221 /* Functions called in device_added */222 extern int nic_ready(nic_t *);223 224 222 /* General driver functions */ 225 223 extern ddf_dev_t *nic_get_ddf_dev(nic_t *); 226 224 extern ddf_fun_t *nic_get_ddf_fun(nic_t *); 225 extern void nic_set_ddf_fun(nic_t *, ddf_fun_t *); 227 226 extern nic_t *nic_get_from_ddf_dev(ddf_dev_t *); 228 227 extern nic_t *nic_get_from_ddf_fun(ddf_fun_t *); … … 233 232 extern int nic_report_poll_mode(nic_t *, nic_poll_mode_t, struct timeval *); 234 233 extern void nic_query_address(nic_t *, nic_address_t *); 235 extern void nic_received_packet(nic_t *, packet_t *); 236 extern void nic_received_noneth_packet(nic_t *, packet_t *); 234 extern void nic_received_noneth_frame(nic_t *, void *, size_t); 237 235 extern void nic_received_frame(nic_t *, nic_frame_t *); 238 236 extern void nic_received_frame_list(nic_t *, nic_frame_list_t *); … … 248 246 extern void nic_report_collisions(nic_t *, unsigned); 249 247 250 /* Packet / frame / frame list allocation and deallocation */ 251 extern packet_t *nic_alloc_packet(nic_t *, size_t); 252 extern void nic_release_packet(nic_t *, packet_t *); 248 /* Frame / frame list allocation and deallocation */ 253 249 extern nic_frame_t *nic_alloc_frame(nic_t *, size_t); 254 250 extern nic_frame_list_t *nic_alloc_frame_list(void); … … 275 271 extern void nic_sw_period_stop(nic_t *); 276 272 277 /* Packet DMA lock */278 extern int nic_dma_lock_packet(packet_t *, size_t, void **);279 extern int nic_dma_unlock_packet(packet_t *, size_t);280 281 273 #endif // __NIC_H__ 282 274 -
uspace/lib/nic/include/nic_driver.h
r199112e4 rcfb79747 44 44 45 45 #include <fibril_synch.h> 46 #include <n et/device.h>46 #include <nic/nic.h> 47 47 #include <async.h> 48 48 … … 50 50 #include "nic_rx_control.h" 51 51 #include "nic_wol_virtues.h" 52 53 #define DEVICE_CATEGORY_NIC "nic"54 52 55 53 struct sw_poll_info { … … 72 70 */ 73 71 ddf_fun_t *fun; 74 /** Identifier for higher network stack layers */75 nic_device_id_t device_id;76 72 /** Current state of the device */ 77 73 nic_device_state_t state; … … 82 78 /** Device's default MAC address (assigned the first time, used in STOP) */ 83 79 nic_address_t default_mac; 84 /** Session to SERVICE_NETWORKING */ 85 async_sess_t *net_session; 86 /** Session to SERVICE_ETHERNET or SERVICE_NILDUMMY */ 87 async_sess_t *nil_session; 80 /** Client callback session */ 81 async_sess_t *client_session; 88 82 /** Phone to APIC or i8259 */ 89 83 async_sess_t *irc_session; -
uspace/lib/nic/include/nic_impl.h
r199112e4 rcfb79747 40 40 41 41 #include <assert.h> 42 #include <n et/device.h>42 #include <nic/nic.h> 43 43 #include <ddf/driver.h> 44 #include <nil_remote.h>45 44 46 45 /* Inclusion of this file is not prohibited, because drivers could want to … … 49 48 extern int nic_get_address_impl(ddf_fun_t *dev_fun, nic_address_t *address); 50 49 extern int nic_send_frame_impl(ddf_fun_t *dev_fun, void *data, size_t size); 51 extern int nic_connect_to_nil_impl(ddf_fun_t *dev_fun, services_t nil_service, 52 int device_id); 50 extern int nic_callback_create_impl(ddf_fun_t *dev_fun); 53 51 extern int nic_get_state_impl(ddf_fun_t *dev_fun, nic_device_state_t *state); 54 52 extern int nic_set_state_impl(ddf_fun_t *dev_fun, nic_device_state_t state); -
uspace/lib/nic/include/nic_rx_control.h
r199112e4 rcfb79747 45 45 #include <adt/hash_table.h> 46 46 #include <fibril_synch.h> 47 #include <net/device.h> 48 #include <net/packet_header.h> 47 #include <nic/nic.h> 49 48 50 49 #include "nic_addr_db.h" … … 120 119 const nic_address_t *prev_addr, const nic_address_t *curr_addr); 121 120 extern int nic_rxc_check(const nic_rxc_t *rxc, 122 const packet_t *packet, nic_frame_type_t *frame_type);121 const void *data, size_t size, nic_frame_type_t *frame_type); 123 122 extern void nic_rxc_hw_filtering(nic_rxc_t *rxc, 124 123 int unicast_exact, int multicast_exact, int vlan_exact); -
uspace/lib/nic/include/nic_wol_virtues.h
r199112e4 rcfb79747 43 43 #endif 44 44 45 #include <n et/device.h>45 #include <nic/nic.h> 46 46 #include <adt/hash_table.h> 47 47 #include "nic.h" -
uspace/lib/nic/src/nic_driver.c
r199112e4 rcfb79747 49 49 #include <devman.h> 50 50 #include <ddf/interrupt.h> 51 #include <net_interface.h>52 51 #include <ops/nic.h> 53 #include <packet_client.h>54 #include <packet_remote.h>55 #include <net/packet_header.h>56 52 #include <errno.h> 57 53 58 54 #include "nic_driver.h" 55 #include "nic_ev.h" 59 56 #include "nic_impl.h" 60 57 … … 64 61 65 62 /** 66 * Initializes libraries required for NIC framework - logger , packet manager63 * Initializes libraries required for NIC framework - logger 67 64 * 68 65 * @param name Name of the device/driver (used in logging) … … 79 76 snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name); 80 77 81 /* Initialize packet manager */ 82 return pm_init(); 78 return EOK; 83 79 } 84 80 … … 93 89 nic_iface_t *iface) 94 90 { 95 if (driver_ops) {96 if (!driver_ops->device_added)97 driver_ops->device_added = nic_device_added_impl;98 }99 100 91 if (dev_ops) { 101 92 if (!dev_ops->open) … … 116 107 if (!iface->send_frame) 117 108 iface->send_frame = nic_send_frame_impl; 118 if (!iface->c onnect_to_nil)119 iface->c onnect_to_nil = nic_connect_to_nil_impl;109 if (!iface->callback_create) 110 iface->callback_create = nic_callback_create_impl; 120 111 if (!iface->get_address) 121 112 iface->get_address = nic_get_address_impl; … … 162 153 163 154 /** 164 * Setup write packethandler. This MUST be called in the add_device handler155 * Setup send frame handler. This MUST be called in the add_device handler 165 156 * if the nic_send_message_impl function is used for sending messages (filled 166 157 * as send_message member of the nic_iface_t structure). The function must not … … 270 261 } 271 262 272 /** 273 * Just a wrapper over the packet_get_1_remote function 274 */ 275 packet_t *nic_alloc_packet(nic_t *nic_data, size_t data_size) 276 { 277 return packet_get_1_remote(nic_data->net_session, data_size); 278 } 279 280 281 /** 282 * Just a wrapper over the pq_release_remote function 283 */ 284 void nic_release_packet(nic_t *nic_data, packet_t *packet) 285 { 286 pq_release_remote(nic_data->net_session, packet_get_id(packet)); 287 } 288 289 /** Allocate frame and packet 263 /** Allocate frame 290 264 * 291 265 * @param nic_data The NIC driver data 292 * @param packet_size Size of packet 293 * @param offload_size Size of packet offload 266 * @param size Frame size in bytes 294 267 * @return pointer to allocated frame if success, NULL otherwise 295 268 */ 296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)269 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size) 297 270 { 298 271 nic_frame_t *frame; … … 313 286 } 314 287 315 packet_t *packet = nic_alloc_packet(nic_data, packet_size);316 if ( !packet) {288 frame->data = malloc(size); 289 if (frame->data == NULL) { 317 290 free(frame); 318 291 return NULL; 319 292 } 320 293 321 frame-> packet = packet;294 frame->size = size; 322 295 return frame; 323 296 } … … 332 305 if (!frame) 333 306 return; 334 if (frame->packet != NULL) { 335 nic_release_packet(nic_data, frame->packet); 336 } 307 308 if (frame->data != NULL) { 309 free(frame->data); 310 frame->data = NULL; 311 frame->size = 0; 312 } 313 337 314 fibril_mutex_lock(&nic_globals.lock); 338 315 if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) { … … 447 424 448 425 /** 449 * Connect to the NET and IRQ services. This function should be called only from426 * Connect to IRC service. This function should be called only from 450 427 * the add_device handler, thus no locking is required. 451 428 * … … 454 431 * @return EOK If connection was successful. 455 432 * @return EINVAL If the IRC service cannot be determined. 456 * @return EREFUSED If NET orIRC service cannot be connected.433 * @return EREFUSED If IRC service cannot be connected. 457 434 */ 458 435 int nic_connect_to_services(nic_t *nic_data) 459 436 { 460 /* NET service */461 nic_data->net_session = service_connect_blocking(EXCHANGE_SERIALIZE,462 SERVICE_NETWORKING, 0, 0);463 if (nic_data->net_session == NULL)464 return errno;465 466 437 /* IRC service */ 467 438 sysarg_t apic; … … 480 451 481 452 return EOK; 482 }483 484 /** Notify the NET service that the device is ready485 *486 * @param nic NICF structure487 *488 * @return EOK on success489 *490 */491 int nic_ready(nic_t *nic)492 {493 fibril_rwlock_read_lock(&nic->main_lock);494 495 async_sess_t *session = nic->net_session;496 devman_handle_t handle = nic->dev->handle;497 498 fibril_rwlock_read_unlock(&nic->main_lock);499 500 if (session == NULL)501 return EINVAL;502 503 return net_driver_ready(session, handle);504 453 } 505 454 … … 546 495 547 496 /* Notify NIL layer (and uppper) if bound - not in add_device */ 548 if (nic_data-> nil_session != NULL) {549 int rc = ni l_addr_changed_msg(nic_data->nil_session,550 nic_data->device_id,address);497 if (nic_data->client_session != NULL) { 498 int rc = nic_ev_addr_changed(nic_data->client_session, 499 address); 551 500 if (rc != EOK) { 552 501 fibril_rwlock_write_unlock(&nic_data->main_lock); … … 604 553 605 554 /** 606 * The busy flag can be set to 1 only in the write_packethandler, to 0 it can555 * The busy flag can be set to 1 only in the send_frame handler, to 0 it can 607 556 * be set anywhere. 608 557 * … … 613 562 { 614 563 /* 615 * When the function is called in write_packethandler the main lock is564 * When the function is called in send_frame handler the main lock is 616 565 * locked so no race can happen. 617 566 * Otherwise, when it is unexpectedly set to 0 (even with main lock held … … 622 571 623 572 /** 624 * Provided for correct naming conventions.625 * The packetis checked by filters and then sent up to the NIL layer or626 * discarded , the frame is released.627 * 628 * @param nic_data 629 * @param frame The frame containing received packet573 * This is the function that the driver should call when it receives a frame. 574 * The frame is checked by filters and then sent up to the NIL layer or 575 * discarded. The frame is released. 576 * 577 * @param nic_data 578 * @param frame The received frame 630 579 */ 631 580 void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) 632 581 { 633 nic_received_packet(nic_data, frame->packet);634 frame->packet = NULL;635 nic_release_frame(nic_data, frame);636 }637 638 /**639 * This is the function that the driver should call when it receives a packet.640 * The packet is checked by filters and then sent up to the NIL layer or641 * discarded.642 *643 * @param nic_data644 * @param packet The received packet645 */646 void nic_received_packet(nic_t *nic_data, packet_t *packet)647 {648 582 /* Note: this function must not lock main lock, because loopback driver 649 * calls it inside write_packet handler (with locked main lock) */ 650 packet_id_t pid = packet_get_id(packet); 651 583 * calls it inside send_frame handler (with locked main lock) */ 652 584 fibril_rwlock_read_lock(&nic_data->rxc_lock); 653 585 nic_frame_type_t frame_type; 654 int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type); 586 int check = nic_rxc_check(&nic_data->rx_control, frame->data, 587 frame->size, &frame_type); 655 588 fibril_rwlock_read_unlock(&nic_data->rxc_lock); 656 589 /* Update statistics */ 657 590 fibril_rwlock_write_lock(&nic_data->stats_lock); 658 /* Both sending message up and releasing packet are atomic IPC calls */ 591 659 592 if (nic_data->state == NIC_STATE_ACTIVE && check) { 660 593 nic_data->stats.receive_packets++; 661 nic_data->stats.receive_bytes += packet_get_data_length(packet);594 nic_data->stats.receive_bytes += frame->size; 662 595 switch (frame_type) { 663 596 case NIC_FRAME_MULTICAST: … … 671 604 } 672 605 fibril_rwlock_write_unlock(&nic_data->stats_lock); 673 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid); 606 nic_ev_received(nic_data->client_session, frame->data, 607 frame->size); 674 608 } else { 675 609 switch (frame_type) { … … 685 619 } 686 620 fibril_rwlock_write_unlock(&nic_data->stats_lock); 687 nic_release_packet(nic_data, packet);688 }621 } 622 nic_release_frame(nic_data, frame); 689 623 } 690 624 691 625 /** 692 626 * This function is to be used only in the loopback driver. It's workaround 693 * for the situation when the packetdoes not contain ethernet address.627 * for the situation when the frame does not contain ethernet address. 694 628 * The filtering is therefore not applied here. 695 629 * 696 630 * @param nic_data 697 * @param packet 698 */ 699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet) 631 * @param data Frame data 632 * @param size Frame size in bytes 633 */ 634 void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size) 700 635 { 701 636 fibril_rwlock_write_lock(&nic_data->stats_lock); 702 637 nic_data->stats.receive_packets++; 703 nic_data->stats.receive_bytes += packet_get_data_length(packet);638 nic_data->stats.receive_bytes += size; 704 639 fibril_rwlock_write_unlock(&nic_data->stats_lock); 705 640 706 nil_received_msg(nic_data->nil_session, nic_data->device_id, 707 packet_get_id(packet)); 708 } 709 710 /** 711 * Some NICs can receive multiple packets during single interrupt. These can 641 nic_ev_received(nic_data->client_session, data, size); 642 } 643 644 /** 645 * Some NICs can receive multiple frames during single interrupt. These can 712 646 * send them in whole list of frames (actually nic_frame_t structures), then 713 * the list is deallocated and each packetis passed to the647 * the list is deallocated and each frame is passed to the 714 648 * nic_received_packet function. 715 649 * … … 726 660 727 661 list_remove(&frame->link); 728 nic_received_packet(nic_data, frame->packet); 729 frame->packet = NULL; 730 nic_release_frame(nic_data, frame); 662 nic_received_frame(nic_data, frame); 731 663 } 732 664 nic_driver_release_frame_list(frames); … … 758 690 nic_data->dev = NULL; 759 691 nic_data->fun = NULL; 760 nic_data->device_id = NIC_DEVICE_INVALID_ID;761 692 nic_data->state = NIC_STATE_STOPPED; 762 nic_data->net_session = NULL; 763 nic_data->nil_session = NULL; 693 nic_data->client_session = NULL; 764 694 nic_data->irc_session = NULL; 765 695 nic_data->poll_mode = NIC_POLL_IMMEDIATE; … … 815 745 */ 816 746 static void nic_destroy(nic_t *nic_data) { 817 if (nic_data->net_session != NULL) { 818 async_hangup(nic_data->net_session); 819 } 820 821 if (nic_data->nil_session != NULL) { 822 async_hangup(nic_data->nil_session); 747 if (nic_data->client_session != NULL) { 748 async_hangup(nic_data->client_session); 823 749 } 824 750 … … 846 772 847 773 /** 848 * Creates an exposed DDF function for the device, named "port0".849 * Device options are set as this function's options. The function is bound850 * (see ddf_fun_bind) and then registered to the DEVICE_CATEGORY_NIC class.851 * Note: this function should be called only from add_device handler, therefore852 * we don't need to use locks.853 *854 * @param nic_data The NIC structure855 * @param ops Device options for the DDF function.856 */857 int nic_register_as_ddf_fun(nic_t *nic_data, ddf_dev_ops_t *ops)858 {859 int rc;860 assert(nic_data);861 862 nic_data->fun = ddf_fun_create(nic_data->dev, fun_exposed, "port0");863 if (nic_data->fun == NULL)864 return ENOMEM;865 866 nic_data->fun->ops = ops;867 nic_data->fun->driver_data = nic_data;868 869 rc = ddf_fun_bind(nic_data->fun);870 if (rc != EOK) {871 ddf_fun_destroy(nic_data->fun);872 return rc;873 }874 875 rc = ddf_fun_add_to_category(nic_data->fun, DEVICE_CATEGORY_NIC);876 if (rc != EOK) {877 ddf_fun_destroy(nic_data->fun);878 return rc;879 }880 881 return EOK;882 }883 884 /**885 774 * Set information about current HW filtering. 886 775 * 1 ... Only those frames we want to receive are passed through HW … … 1097 986 { 1098 987 return nic_data->fun; 988 } 989 990 /** 991 * @param nic_data 992 * @param fun 993 */ 994 void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun) 995 { 996 nic_data->fun = fun; 1099 997 } 1100 998 … … 1329 1227 } 1330 1228 1331 /** Lock packet for DMA usage1332 *1333 * @param packet1334 * @return physical address of packet1335 */1336 int nic_dma_lock_packet(packet_t *packet, size_t size, void **phys)1337 {1338 return dmamem_map(packet, SIZE2PAGES(size), 0, 0, phys);1339 }1340 1341 /** Unlock packet after DMA usage1342 *1343 * @param packet1344 */1345 int nic_dma_unlock_packet(packet_t *packet, size_t size)1346 {1347 return dmamem_unmap(packet, size);1348 }1349 1350 1229 /** @} 1351 1230 */ -
uspace/lib/nic/src/nic_impl.c
r199112e4 rcfb79747 36 36 */ 37 37 38 #include <errno.h> 38 39 #include <str_error.h> 39 40 #include <ipc/services.h> 40 41 #include <ns.h> 41 42 #include "nic_driver.h" 43 #include "nic_ev.h" 42 44 #include "nic_impl.h" 43 45 … … 85 87 } 86 88 if (state == NIC_STATE_ACTIVE) { 87 if (nic_data->nil_session == NULL || nic_data->net_session == NULL 88 || nic_data->device_id < 0) { 89 if (nic_data->client_session == NULL) { 89 90 fibril_rwlock_write_unlock(&nic_data->main_lock); 90 91 return EINVAL; … … 116 117 if (state == NIC_STATE_STOPPED) { 117 118 /* Notify upper layers that we are reseting the MAC */ 118 int rc = ni l_addr_changed_msg(nic_data->nil_session,119 nic_data->device_id,&nic_data->default_mac);119 int rc = nic_ev_addr_changed(nic_data->client_session, 120 &nic_data->default_mac); 120 121 nic_data->poll_mode = nic_data->default_poll_mode; 121 122 memcpy(&nic_data->poll_period, &nic_data->default_poll_period, … … 149 150 nic_data->state = state; 150 151 151 ni l_device_state_msg(nic_data->nil_session, nic_data->device_id, state);152 nic_ev_device_state(nic_data->client_session, state); 152 153 153 154 fibril_rwlock_write_unlock(&nic_data->main_lock); … … 182 183 183 184 /** 184 * Default implementation of the connect_ to_nilmethod.185 * C onnects the driver to the NIL service.185 * Default implementation of the connect_client method. 186 * Creates callback connection to the client. 186 187 * 187 188 * @param fun 188 * @param nil_service ID of the server implementing the NIL service 189 * @param device_id ID of the device as used in higher layers 190 * 191 * @return EOK If the services were bound 192 * @return Negative error code from service_connect_blocking 193 */ 194 int nic_connect_to_nil_impl(ddf_fun_t *fun, services_t nil_service, 195 nic_device_id_t device_id) 196 { 197 nic_t *nic_data = (nic_t *) fun->driver_data; 198 fibril_rwlock_write_lock(&nic_data->main_lock); 189 * 190 * @return EOK On success, or negative error code. 191 */ 192 int nic_callback_create_impl(ddf_fun_t *fun) 193 { 194 nic_t *nic = (nic_t *) fun->driver_data; 195 fibril_rwlock_write_lock(&nic->main_lock); 199 196 200 nic_data->device_id = device_id; 197 nic->client_session = async_callback_receive(EXCHANGE_SERIALIZE); 198 if (nic->client_session == NULL) { 199 fibril_rwlock_write_unlock(&nic->main_lock); 200 return ENOMEM; 201 } 201 202 202 nic_data->nil_session = service_connect_blocking(EXCHANGE_SERIALIZE, 203 nil_service, 0, 0); 204 if (nic_data->nil_session != NULL) { 205 fibril_rwlock_write_unlock(&nic_data->main_lock); 206 return EOK; 207 } 208 209 fibril_rwlock_write_unlock(&nic_data->main_lock); 210 return EHANGUP; 203 fibril_rwlock_write_unlock(&nic->main_lock); 204 return EOK; 211 205 } 212 206 … … 805 799 } 806 800 807 /** Default implementation of the device_added method808 *809 * Just calls nic_ready.810 *811 * @param dev812 *813 */814 void nic_device_added_impl(ddf_dev_t *dev)815 {816 nic_ready((nic_t *) dev->driver_data);817 }818 819 801 /** 820 802 * Default handler for unknown methods (outside of the NIC interface). -
uspace/lib/nic/src/nic_rx_control.c
r199112e4 rcfb79747 40 40 #include <bool.h> 41 41 #include <errno.h> 42 #include <net/device.h> 43 #include <net_checksum.h> 44 #include <packet_client.h> 42 #include <mem.h> 43 #include <nic/nic.h> 45 44 #include "nic_rx_control.h" 46 45 … … 392 391 * 393 392 * @param rxc 394 * @param packetThe probed frame393 * @param frame The probed frame 395 394 * 396 395 * @return True if the frame passes, false if it does not 397 396 */ 398 int nic_rxc_check(const nic_rxc_t *rxc, const packet_t *packet,397 int nic_rxc_check(const nic_rxc_t *rxc, const void *data, size_t size, 399 398 nic_frame_type_t *frame_type) 400 399 { 401 400 assert(frame_type != NULL); 402 uint8_t *dest_addr = (uint8_t *) packet + packet->data_start;401 uint8_t *dest_addr = (uint8_t *) data; 403 402 uint8_t *src_addr = dest_addr + ETH_ADDR; 403 404 if (size < 2 * ETH_ADDR) 405 return false; 404 406 405 407 if (dest_addr[0] & 1) { … … 448 450 if (!rxc->vlan_exact && rxc->vlan_mask != NULL) { 449 451 vlan_header_t *vlan_header = (vlan_header_t *) 450 ((uint8_t *) packet + packet->data_start+ 2 * ETH_ADDR);452 ((uint8_t *) data + 2 * ETH_ADDR); 451 453 if (vlan_header->tpid_upper == VLAN_TPID_UPPER && 452 454 vlan_header->tpid_lower == VLAN_TPID_LOWER) { … … 484 486 rxc->vlan_exact = vlan_exact; 485 487 } 488 489 /** Polynomial used in multicast address hashing */ 490 #define CRC_MCAST_POLYNOMIAL 0x04c11db6 491 492 /** Compute the standard hash from MAC 493 * 494 * Hashing MAC into 64 possible values and using the value as index to 495 * 64bit number. 496 * 497 * The code is copied from qemu-0.13's implementation of ne2000 and rt8139 498 * drivers, but according to documentation there it originates in FreeBSD. 499 * 500 * @param[in] addr The 6-byte MAC address to be hashed 501 * 502 * @return 64-bit number with only single bit set to 1 503 * 504 */ 505 static uint64_t multicast_hash(const uint8_t addr[6]) 506 { 507 uint32_t crc; 508 int carry, i, j; 509 uint8_t b; 510 511 crc = 0xffffffff; 512 for (i = 0; i < 6; i++) { 513 b = addr[i]; 514 for (j = 0; j < 8; j++) { 515 carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); 516 crc <<= 1; 517 b >>= 1; 518 if (carry) 519 crc = ((crc ^ CRC_MCAST_POLYNOMIAL) | carry); 520 } 521 } 522 523 uint64_t one64 = 1; 524 return one64 << (crc >> 26); 525 } 526 486 527 487 528 /** -
uspace/lib/nic/src/nic_wol_virtues.c
r199112e4 rcfb79747 38 38 #include "nic_wol_virtues.h" 39 39 #include <assert.h> 40 #include <errno.h> 40 41 41 42 #define NIC_WV_HASH_COUNT 32 -
uspace/lib/posix/ctype.c
r199112e4 rcfb79747 112 112 * @return Non-zero if character match the definition, zero otherwise. 113 113 */ 114 externint posix_isascii(int c)114 int posix_isascii(int c) 115 115 { 116 116 return c >= 0 && c < 128; … … 123 123 * @return Coverted character. 124 124 */ 125 externint posix_toascii(int c)125 int posix_toascii(int c) 126 126 { 127 127 return c & 0x7F;
Note:
See TracChangeset
for help on using the changeset viewer.