Changes in uspace/lib/nic/src/nic_driver.c [ea788701:6d8455d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/nic/src/nic_driver.c
rea788701 r6d8455d 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> 53 56 #include <errno.h> 54 57 … … 61 64 62 65 /** 63 * Initializes libraries required for NIC framework - logger 66 * Initializes libraries required for NIC framework - logger, packet manager 64 67 * 65 68 * @param name Name of the device/driver (used in logging) … … 76 79 snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name); 77 80 78 return EOK; 81 /* Initialize packet manager */ 82 return pm_init(); 79 83 } 80 84 … … 158 162 159 163 /** 160 * Setup send framehandler. This MUST be called in the add_device handler164 * Setup write packet handler. This MUST be called in the add_device handler 161 165 * if the nic_send_message_impl function is used for sending messages (filled 162 166 * as send_message member of the nic_iface_t structure). The function must not … … 266 270 } 267 271 268 /** Allocate frame 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 269 290 * 270 291 * @param nic_data The NIC driver data 271 * @param size Frame size in bytes 292 * @param packet_size Size of packet 293 * @param offload_size Size of packet offload 272 294 * @return pointer to allocated frame if success, NULL otherwise 273 295 */ 274 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size) 275 297 { 276 298 nic_frame_t *frame; … … 291 313 } 292 314 293 frame->data = malloc(size);294 if ( frame->data == NULL) {315 packet_t *packet = nic_alloc_packet(nic_data, packet_size); 316 if (!packet) { 295 317 free(frame); 296 318 return NULL; 297 319 } 298 320 299 frame-> size = size;321 frame->packet = packet; 300 322 return frame; 301 323 } … … 310 332 if (!frame) 311 333 return; 312 313 if (frame->data != NULL) { 314 free(frame->data); 315 frame->data = NULL; 316 frame->size = 0; 317 } 318 334 if (frame->packet != NULL) { 335 nic_release_packet(nic_data, frame->packet); 336 } 319 337 fibril_mutex_lock(&nic_globals.lock); 320 338 if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) { … … 586 604 587 605 /** 588 * The busy flag can be set to 1 only in the send_framehandler, to 0 it can606 * The busy flag can be set to 1 only in the write_packet handler, to 0 it can 589 607 * be set anywhere. 590 608 * … … 595 613 { 596 614 /* 597 * When the function is called in send_framehandler the main lock is615 * When the function is called in write_packet handler the main lock is 598 616 * locked so no race can happen. 599 617 * Otherwise, when it is unexpectedly set to 0 (even with main lock held … … 604 622 605 623 /** 606 * This is the function that the driver should call when it receives a frame.607 * The frameis checked by filters and then sent up to the NIL layer or608 * discarded . The frame is released.609 * 610 * @param nic_data 611 * @param frame The received frame624 * Provided for correct naming conventions. 625 * The packet is checked by filters and then sent up to the NIL layer or 626 * discarded, the frame is released. 627 * 628 * @param nic_data 629 * @param frame The frame containing received packet 612 630 */ 613 631 void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) 614 632 { 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 or 641 * discarded. 642 * 643 * @param nic_data 644 * @param packet The received packet 645 */ 646 void nic_received_packet(nic_t *nic_data, packet_t *packet) 647 { 615 648 /* Note: this function must not lock main lock, because loopback driver 616 * calls it inside send_frame handler (with locked main lock) */ 649 * calls it inside write_packet handler (with locked main lock) */ 650 packet_id_t pid = packet_get_id(packet); 651 617 652 fibril_rwlock_read_lock(&nic_data->rxc_lock); 618 653 nic_frame_type_t frame_type; 619 int check = nic_rxc_check(&nic_data->rx_control, frame->data, 620 frame->size, &frame_type); 654 int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type); 621 655 fibril_rwlock_read_unlock(&nic_data->rxc_lock); 622 656 /* Update statistics */ 623 657 fibril_rwlock_write_lock(&nic_data->stats_lock); 624 658 /* Both sending message up and releasing packet are atomic IPC calls */ 625 659 if (nic_data->state == NIC_STATE_ACTIVE && check) { 626 660 nic_data->stats.receive_packets++; 627 nic_data->stats.receive_bytes += frame->size;661 nic_data->stats.receive_bytes += packet_get_data_length(packet); 628 662 switch (frame_type) { 629 663 case NIC_FRAME_MULTICAST: … … 637 671 } 638 672 fibril_rwlock_write_unlock(&nic_data->stats_lock); 639 nil_received_msg(nic_data->nil_session, nic_data->device_id, 640 frame->data, frame->size); 673 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid); 641 674 } else { 642 675 switch (frame_type) { … … 652 685 } 653 686 fibril_rwlock_write_unlock(&nic_data->stats_lock); 654 }655 nic_release_frame(nic_data, frame);687 nic_release_packet(nic_data, packet); 688 } 656 689 } 657 690 658 691 /** 659 692 * This function is to be used only in the loopback driver. It's workaround 660 * for the situation when the framedoes not contain ethernet address.693 * for the situation when the packet does not contain ethernet address. 661 694 * The filtering is therefore not applied here. 662 695 * 663 696 * @param nic_data 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) 697 * @param packet 698 */ 699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet) 668 700 { 669 701 fibril_rwlock_write_lock(&nic_data->stats_lock); 670 702 nic_data->stats.receive_packets++; 671 nic_data->stats.receive_bytes += size;703 nic_data->stats.receive_bytes += packet_get_data_length(packet); 672 704 fibril_rwlock_write_unlock(&nic_data->stats_lock); 673 705 674 706 nil_received_msg(nic_data->nil_session, nic_data->device_id, 675 data, size);676 } 677 678 /** 679 * Some NICs can receive multiple frames during single interrupt. These can707 packet_get_id(packet)); 708 } 709 710 /** 711 * Some NICs can receive multiple packets during single interrupt. These can 680 712 * send them in whole list of frames (actually nic_frame_t structures), then 681 * the list is deallocated and each frameis passed to the713 * the list is deallocated and each packet is passed to the 682 714 * nic_received_packet function. 683 715 * … … 694 726 695 727 list_remove(&frame->link); 696 nic_received_frame(nic_data, frame); 728 nic_received_packet(nic_data, frame->packet); 729 frame->packet = NULL; 730 nic_release_frame(nic_data, frame); 697 731 } 698 732 nic_driver_release_frame_list(frames); … … 1295 1329 } 1296 1330 1331 /** Lock packet for DMA usage 1332 * 1333 * @param packet 1334 * @return physical address of packet 1335 */ 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 usage 1342 * 1343 * @param packet 1344 */ 1345 int nic_dma_unlock_packet(packet_t *packet, size_t size) 1346 { 1347 return dmamem_unmap(packet, size); 1348 } 1349 1297 1350 /** @} 1298 1351 */
Note:
See TracChangeset
for help on using the changeset viewer.