Changeset 86c71de in mainline for uspace/lib
- Timestamp:
- 2012-01-21T12:57:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- eaa0c3f
- Parents:
- 47a89fe (diff), e86b8f0 (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:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/include/nil_remote.h
r47a89fe r86c71de 39 39 #include <generic.h> 40 40 #include <async.h> 41 #include <sys/types.h> 41 42 42 43 #define nil_bind_service(service, device_id, me, receiver) \ … … 61 62 size_t); 62 63 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_received_msg(async_sess_t *, nic_device_id_t, void *, size_t); 64 65 extern int nil_addr_changed_msg(async_sess_t *, nic_device_id_t, 65 66 const nic_address_t *); -
uspace/lib/net/nil/nil_remote.c
r47a89fe r86c71de 77 77 */ 78 78 int nil_received_msg(async_sess_t *sess, nic_device_id_t device_id, 79 packet_id_t packet_id)79 void *data, size_t size) 80 80 { 81 return generic_received_msg_remote(sess, NET_NIL_RECEIVED, 82 device_id, packet_id, 0, 0); 81 async_exch_t *exch = async_exchange_begin(sess); 82 83 ipc_call_t answer; 84 aid_t req = async_send_1(exch, NET_NIL_RECEIVED, (sysarg_t) device_id, 85 &answer); 86 sysarg_t retval = async_data_write_start(exch, data, size); 87 88 async_exchange_end(exch); 89 90 if (retval != EOK) { 91 async_wait_for(req, NULL); 92 return retval; 93 } 94 95 async_wait_for(req, &retval); 96 return retval; 83 97 } 84 98 -
uspace/lib/nic/include/nic.h
r47a89fe r86c71de 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 *); … … 225 226 extern ddf_dev_t *nic_get_ddf_dev(nic_t *); 226 227 extern ddf_fun_t *nic_get_ddf_fun(nic_t *); 228 extern void nic_set_ddf_fun(nic_t *, ddf_fun_t *); 227 229 extern nic_t *nic_get_from_ddf_dev(ddf_dev_t *); 228 230 extern nic_t *nic_get_from_ddf_fun(ddf_fun_t *); … … 233 235 extern int nic_report_poll_mode(nic_t *, nic_poll_mode_t, struct timeval *); 234 236 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 *); 237 extern void nic_received_noneth_frame(nic_t *, void *, size_t); 237 238 extern void nic_received_frame(nic_t *, nic_frame_t *); 238 239 extern void nic_received_frame_list(nic_t *, nic_frame_list_t *); … … 248 249 extern void nic_report_collisions(nic_t *, unsigned); 249 250 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 *); 251 /* Frame / frame list allocation and deallocation */ 253 252 extern nic_frame_t *nic_alloc_frame(nic_t *, size_t); 254 253 extern nic_frame_list_t *nic_alloc_frame_list(void); … … 275 274 extern void nic_sw_period_stop(nic_t *); 276 275 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 276 #endif // __NIC_H__ 282 277 -
uspace/lib/nic/include/nic_driver.h
r47a89fe r86c71de 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 { -
uspace/lib/nic/include/nic_rx_control.h
r47a89fe r86c71de 46 46 #include <fibril_synch.h> 47 47 #include <net/device.h> 48 #include <net/packet_header.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/src/nic_driver.c
r47a89fe r86c71de 51 51 #include <net_interface.h> 52 52 #include <ops/nic.h> 53 #include <packet_client.h>54 #include <packet_remote.h>55 #include <net/packet_header.h>56 53 #include <errno.h> 57 54 … … 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 … … 162 158 163 159 /** 164 * Setup write packethandler. This MUST be called in the add_device handler160 * Setup send frame handler. This MUST be called in the add_device handler 165 161 * if the nic_send_message_impl function is used for sending messages (filled 166 162 * as send_message member of the nic_iface_t structure). The function must not … … 270 266 } 271 267 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 268 /** Allocate frame 290 269 * 291 270 * @param nic_data The NIC driver data 292 * @param packet_size Size of packet 293 * @param offload_size Size of packet offload 271 * @param size Frame size in bytes 294 272 * @return pointer to allocated frame if success, NULL otherwise 295 273 */ 296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)274 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size) 297 275 { 298 276 nic_frame_t *frame; … … 313 291 } 314 292 315 packet_t *packet = nic_alloc_packet(nic_data, packet_size);316 if ( !packet) {293 frame->data = malloc(size); 294 if (frame->data == NULL) { 317 295 free(frame); 318 296 return NULL; 319 297 } 320 298 321 frame-> packet = packet;299 frame->size = size; 322 300 return frame; 323 301 } … … 332 310 if (!frame) 333 311 return; 334 if (frame->packet != NULL) { 335 nic_release_packet(nic_data, frame->packet); 336 } 312 313 if (frame->data != NULL) { 314 free(frame->data); 315 frame->data = NULL; 316 frame->size = 0; 317 } 318 337 319 fibril_mutex_lock(&nic_globals.lock); 338 320 if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) { … … 604 586 605 587 /** 606 * The busy flag can be set to 1 only in the write_packethandler, to 0 it can588 * The busy flag can be set to 1 only in the send_frame handler, to 0 it can 607 589 * be set anywhere. 608 590 * … … 613 595 { 614 596 /* 615 * When the function is called in write_packethandler the main lock is597 * When the function is called in send_frame handler the main lock is 616 598 * locked so no race can happen. 617 599 * Otherwise, when it is unexpectedly set to 0 (even with main lock held … … 622 604 623 605 /** 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 packet606 * This is the function that the driver should call when it receives a frame. 607 * The frame is checked by filters and then sent up to the NIL layer or 608 * discarded. The frame is released. 609 * 610 * @param nic_data 611 * @param frame The received frame 630 612 */ 631 613 void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) 632 614 { 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 615 /* 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 616 * calls it inside send_frame handler (with locked main lock) */ 652 617 fibril_rwlock_read_lock(&nic_data->rxc_lock); 653 618 nic_frame_type_t frame_type; 654 int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type); 619 int check = nic_rxc_check(&nic_data->rx_control, frame->data, 620 frame->size, &frame_type); 655 621 fibril_rwlock_read_unlock(&nic_data->rxc_lock); 656 622 /* Update statistics */ 657 623 fibril_rwlock_write_lock(&nic_data->stats_lock); 658 /* Both sending message up and releasing packet are atomic IPC calls */ 624 659 625 if (nic_data->state == NIC_STATE_ACTIVE && check) { 660 626 nic_data->stats.receive_packets++; 661 nic_data->stats.receive_bytes += packet_get_data_length(packet);627 nic_data->stats.receive_bytes += frame->size; 662 628 switch (frame_type) { 663 629 case NIC_FRAME_MULTICAST: … … 671 637 } 672 638 fibril_rwlock_write_unlock(&nic_data->stats_lock); 673 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid); 639 nil_received_msg(nic_data->nil_session, nic_data->device_id, 640 frame->data, frame->size); 674 641 } else { 675 642 switch (frame_type) { … … 685 652 } 686 653 fibril_rwlock_write_unlock(&nic_data->stats_lock); 687 nic_release_packet(nic_data, packet);688 }654 } 655 nic_release_frame(nic_data, frame); 689 656 } 690 657 691 658 /** 692 659 * 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.660 * for the situation when the frame does not contain ethernet address. 694 661 * The filtering is therefore not applied here. 695 662 * 696 663 * @param nic_data 697 * @param packet 698 */ 699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet) 664 * @param data Frame data 665 * @param size Frame size in bytes 666 */ 667 void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size) 700 668 { 701 669 fibril_rwlock_write_lock(&nic_data->stats_lock); 702 670 nic_data->stats.receive_packets++; 703 nic_data->stats.receive_bytes += packet_get_data_length(packet);671 nic_data->stats.receive_bytes += size; 704 672 fibril_rwlock_write_unlock(&nic_data->stats_lock); 705 673 706 674 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 can675 data, size); 676 } 677 678 /** 679 * Some NICs can receive multiple frames during single interrupt. These can 712 680 * send them in whole list of frames (actually nic_frame_t structures), then 713 * the list is deallocated and each packetis passed to the681 * the list is deallocated and each frame is passed to the 714 682 * nic_received_packet function. 715 683 * … … 726 694 727 695 list_remove(&frame->link); 728 nic_received_packet(nic_data, frame->packet); 729 frame->packet = NULL; 730 nic_release_frame(nic_data, frame); 696 nic_received_frame(nic_data, frame); 731 697 } 732 698 nic_driver_release_frame_list(frames); … … 846 812 847 813 /** 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 814 * Set information about current HW filtering. 886 815 * 1 ... Only those frames we want to receive are passed through HW … … 1097 1026 { 1098 1027 return nic_data->fun; 1028 } 1029 1030 /** 1031 * @param nic_data 1032 * @param fun 1033 */ 1034 void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun) 1035 { 1036 nic_data->fun = fun; 1099 1037 } 1100 1038 … … 1329 1267 } 1330 1268 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 1269 /** @} 1351 1270 */ -
uspace/lib/nic/src/nic_rx_control.c
r47a89fe r86c71de 392 392 * 393 393 * @param rxc 394 * @param packetThe probed frame394 * @param frame The probed frame 395 395 * 396 396 * @return True if the frame passes, false if it does not 397 397 */ 398 int nic_rxc_check(const nic_rxc_t *rxc, const packet_t *packet,398 int nic_rxc_check(const nic_rxc_t *rxc, const void *data, size_t size, 399 399 nic_frame_type_t *frame_type) 400 400 { 401 401 assert(frame_type != NULL); 402 uint8_t *dest_addr = (uint8_t *) packet + packet->data_start;402 uint8_t *dest_addr = (uint8_t *) data; 403 403 uint8_t *src_addr = dest_addr + ETH_ADDR; 404 405 if (size < 2 * ETH_ADDR) 406 return false; 404 407 405 408 if (dest_addr[0] & 1) { … … 448 451 if (!rxc->vlan_exact && rxc->vlan_mask != NULL) { 449 452 vlan_header_t *vlan_header = (vlan_header_t *) 450 ((uint8_t *) packet + packet->data_start+ 2 * ETH_ADDR);453 ((uint8_t *) data + 2 * ETH_ADDR); 451 454 if (vlan_header->tpid_upper == VLAN_TPID_UPPER && 452 455 vlan_header->tpid_lower == VLAN_TPID_LOWER) {
Note:
See TracChangeset
for help on using the changeset viewer.