Changes in uspace/lib/nic/src/nic_driver.c [9cd8165:49bd793b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/nic/src/nic_driver.c
r9cd8165 r49bd793b 46 46 #include <ipc/irc.h> 47 47 #include <sysinfo.h> 48 #include <as.h> 48 49 49 #include <devman.h> 50 50 #include <ddf/interrupt.h> 51 #include <net_interface.h> 51 52 #include <ops/nic.h> 53 #include <packet_client.h> 54 #include <packet_remote.h> 55 #include <net/packet_header.h> 52 56 #include <errno.h> 53 57 54 58 #include "nic_driver.h" 55 #include "nic_ev.h"56 59 #include "nic_impl.h" 57 60 … … 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 … … 89 93 nic_iface_t *iface) 90 94 { 95 if (driver_ops) { 96 if (!driver_ops->device_added) 97 driver_ops->device_added = nic_device_added_impl; 98 } 99 91 100 if (dev_ops) { 92 101 if (!dev_ops->open) … … 105 114 if (!iface->set_state) 106 115 iface->set_state = nic_set_state_impl; 107 if (!iface->send_ frame)108 iface->send_ frame = nic_send_frame_impl;109 if (!iface->c allback_create)110 iface->c allback_create = nic_callback_create_impl;116 if (!iface->send_message) 117 iface->send_message = nic_send_message_impl; 118 if (!iface->connect_to_nil) 119 iface->connect_to_nil = nic_connect_to_nil_impl; 111 120 if (!iface->get_address) 112 121 iface->get_address = nic_get_address_impl; … … 153 162 154 163 /** 155 * 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 156 165 * if the nic_send_message_impl function is used for sending messages (filled 157 166 * as send_message member of the nic_iface_t structure). The function must not … … 159 168 * 160 169 * @param nic_data 161 * @param sffunc Function handling the send_framerequest162 */ 163 void nic_set_ send_frame_handler(nic_t *nic_data, send_frame_handler sffunc)164 { 165 nic_data-> send_frame = sffunc;170 * @param wpfunc Function handling the write_packet request 171 */ 172 void nic_set_write_packet_handler(nic_t *nic_data, write_packet_handler wpfunc) 173 { 174 nic_data->write_packet = wpfunc; 166 175 } 167 176 … … 261 270 } 262 271 263 /** 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 264 290 * 265 291 * @param nic_data The NIC driver data 266 * @param size Frame size in bytes 292 * @param packet_size Size of packet 293 * @param offload_size Size of packet offload 267 294 * @return pointer to allocated frame if success, NULL otherwise 268 295 */ 269 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) 270 297 { 271 298 nic_frame_t *frame; … … 286 313 } 287 314 288 frame->data = malloc(size);289 if ( frame->data == NULL) {315 packet_t *packet = nic_alloc_packet(nic_data, packet_size); 316 if (!packet) { 290 317 free(frame); 291 318 return NULL; 292 319 } 293 320 294 frame-> size = size;321 frame->packet = packet; 295 322 return frame; 296 323 } … … 305 332 if (!frame) 306 333 return; 307 308 if (frame->data != NULL) { 309 free(frame->data); 310 frame->data = NULL; 311 frame->size = 0; 312 } 313 334 if (frame->packet != NULL) { 335 nic_release_packet(nic_data, frame->packet); 336 } 314 337 fibril_mutex_lock(&nic_globals.lock); 315 338 if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) { … … 424 447 425 448 /** 426 * Connect to IRC service. This function should be called only from449 * Connect to the NET and IRQ services. This function should be called only from 427 450 * the add_device handler, thus no locking is required. 428 451 * … … 431 454 * @return EOK If connection was successful. 432 455 * @return EINVAL If the IRC service cannot be determined. 433 * @return EREFUSED If IRC service cannot be connected.456 * @return EREFUSED If NET or IRC service cannot be connected. 434 457 */ 435 458 int nic_connect_to_services(nic_t *nic_data) 436 459 { 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 437 466 /* IRC service */ 438 467 sysarg_t apic; … … 451 480 452 481 return EOK; 482 } 483 484 /** Notify the NET service that the device is ready 485 * 486 * @param nic NICF structure 487 * 488 * @return EOK on success 489 * 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); 453 504 } 454 505 … … 495 546 496 547 /* Notify NIL layer (and uppper) if bound - not in add_device */ 497 if (nic_data-> client_session != NULL) {498 int rc = ni c_ev_addr_changed(nic_data->client_session,499 address);548 if (nic_data->nil_session != NULL) { 549 int rc = nil_addr_changed_msg(nic_data->nil_session, 550 nic_data->device_id, address); 500 551 if (rc != EOK) { 501 552 fibril_rwlock_write_unlock(&nic_data->main_lock); … … 553 604 554 605 /** 555 * 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 556 607 * be set anywhere. 557 608 * … … 562 613 { 563 614 /* 564 * 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 565 616 * locked so no race can happen. 566 617 * Otherwise, when it is unexpectedly set to 0 (even with main lock held … … 571 622 572 623 /** 573 * This is the function that the driver should call when it receives a frame.574 * The frameis checked by filters and then sent up to the NIL layer or575 * discarded . The frame is released.576 * 577 * @param nic_data 578 * @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 579 630 */ 580 631 void nic_received_frame(nic_t *nic_data, nic_frame_t *frame) 581 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 { 582 648 /* Note: this function must not lock main lock, because loopback driver 583 * 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 584 652 fibril_rwlock_read_lock(&nic_data->rxc_lock); 585 653 nic_frame_type_t frame_type; 586 int check = nic_rxc_check(&nic_data->rx_control, frame->data, 587 frame->size, &frame_type); 654 int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type); 588 655 fibril_rwlock_read_unlock(&nic_data->rxc_lock); 589 656 /* Update statistics */ 590 657 fibril_rwlock_write_lock(&nic_data->stats_lock); 591 658 /* Both sending message up and releasing packet are atomic IPC calls */ 592 659 if (nic_data->state == NIC_STATE_ACTIVE && check) { 593 660 nic_data->stats.receive_packets++; 594 nic_data->stats.receive_bytes += frame->size;661 nic_data->stats.receive_bytes += packet_get_data_length(packet); 595 662 switch (frame_type) { 596 663 case NIC_FRAME_MULTICAST: … … 604 671 } 605 672 fibril_rwlock_write_unlock(&nic_data->stats_lock); 606 nic_ev_received(nic_data->client_session, frame->data, 607 frame->size); 673 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid); 608 674 } else { 609 675 switch (frame_type) { … … 619 685 } 620 686 fibril_rwlock_write_unlock(&nic_data->stats_lock); 621 }622 nic_release_frame(nic_data, frame);687 nic_release_packet(nic_data, packet); 688 } 623 689 } 624 690 625 691 /** 626 692 * This function is to be used only in the loopback driver. It's workaround 627 * for the situation when the framedoes not contain ethernet address.693 * for the situation when the packet does not contain ethernet address. 628 694 * The filtering is therefore not applied here. 629 695 * 630 696 * @param nic_data 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) 697 * @param packet 698 */ 699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet) 635 700 { 636 701 fibril_rwlock_write_lock(&nic_data->stats_lock); 637 702 nic_data->stats.receive_packets++; 638 nic_data->stats.receive_bytes += size;703 nic_data->stats.receive_bytes += packet_get_data_length(packet); 639 704 fibril_rwlock_write_unlock(&nic_data->stats_lock); 640 705 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 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 646 712 * send them in whole list of frames (actually nic_frame_t structures), then 647 * the list is deallocated and each frameis passed to the713 * the list is deallocated and each packet is passed to the 648 714 * nic_received_packet function. 649 715 * … … 660 726 661 727 list_remove(&frame->link); 662 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); 663 731 } 664 732 nic_driver_release_frame_list(frames); … … 690 758 nic_data->dev = NULL; 691 759 nic_data->fun = NULL; 760 nic_data->device_id = NIC_DEVICE_INVALID_ID; 692 761 nic_data->state = NIC_STATE_STOPPED; 693 nic_data->client_session = NULL; 762 nic_data->net_session = NULL; 763 nic_data->nil_session = NULL; 694 764 nic_data->irc_session = NULL; 695 765 nic_data->poll_mode = NIC_POLL_IMMEDIATE; 696 766 nic_data->default_poll_mode = NIC_POLL_IMMEDIATE; 697 nic_data-> send_frame= NULL;767 nic_data->write_packet = NULL; 698 768 nic_data->on_activating = NULL; 699 769 nic_data->on_going_down = NULL; … … 745 815 */ 746 816 static void nic_destroy(nic_t *nic_data) { 747 if (nic_data->client_session != NULL) { 748 async_hangup(nic_data->client_session); 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); 749 823 } 750 824 … … 772 846 773 847 /** 848 * Creates an exposed DDF function for the device, named "port0". 849 * Device options are set as this function's options. The function is bound 850 * (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, therefore 852 * we don't need to use locks. 853 * 854 * @param nic_data The NIC structure 855 * @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 /** 774 885 * Set information about current HW filtering. 775 886 * 1 ... Only those frames we want to receive are passed through HW … … 986 1097 { 987 1098 return nic_data->fun; 988 }989 990 /**991 * @param nic_data992 * @param fun993 */994 void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun)995 {996 nic_data->fun = fun;997 1099 } 998 1100 … … 1227 1329 } 1228 1330 1331 // FIXME: Later 1332 #if 0 1333 1334 /** Lock packet for DMA usage 1335 * 1336 * @param packet 1337 * @return physical address of packet 1338 */ 1339 void *nic_dma_lock_packet(packet_t *packet) 1340 { 1341 void *phys_addr; 1342 size_t locked; 1343 int rc = dma_lock(packet, &phys_addr, 1, &locked); 1344 if (rc != EOK) 1345 return NULL; 1346 1347 assert(locked == 1); 1348 return phys_addr; 1349 } 1350 1351 /** Unlock packet after DMA usage 1352 * 1353 * @param packet 1354 */ 1355 void nic_dma_unlock_packet(packet_t *packet) 1356 { 1357 size_t unlocked; 1358 int rc = dma_unlock(packet, 1, &unlocked); 1359 if (rc != EOK) 1360 return; 1361 1362 assert(unlocked == 1); 1363 } 1364 1365 #endif 1366 1229 1367 /** @} 1230 1368 */
Note:
See TracChangeset
for help on using the changeset viewer.