Changes in uspace/lib/nic/src/nic_driver.c [49bd793b:9cd8165] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/nic/src/nic_driver.c
r49bd793b r9cd8165 46 46 #include <ipc/irc.h> 47 47 #include <sysinfo.h> 48 48 #include <as.h> 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) … … 114 105 if (!iface->set_state) 115 106 iface->set_state = nic_set_state_impl; 116 if (!iface->send_ message)117 iface->send_ message = nic_send_message_impl;118 if (!iface->c onnect_to_nil)119 iface->c onnect_to_nil = nic_connect_to_nil_impl;107 if (!iface->send_frame) 108 iface->send_frame = nic_send_frame_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 … … 168 159 * 169 160 * @param nic_data 170 * @param wpfunc Function handling the write_packetrequest171 */ 172 void nic_set_ write_packet_handler(nic_t *nic_data, write_packet_handler wpfunc)173 { 174 nic_data-> write_packet = wpfunc;161 * @param sffunc Function handling the send_frame request 162 */ 163 void nic_set_send_frame_handler(nic_t *nic_data, send_frame_handler sffunc) 164 { 165 nic_data->send_frame = sffunc; 175 166 } 176 167 … … 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; 766 696 nic_data->default_poll_mode = NIC_POLL_IMMEDIATE; 767 nic_data-> write_packet= NULL;697 nic_data->send_frame = NULL; 768 698 nic_data->on_activating = NULL; 769 699 nic_data->on_going_down = NULL; … … 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 // FIXME: Later1332 #if 01333 1334 /** Lock packet for DMA usage1335 *1336 * @param packet1337 * @return physical address of packet1338 */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 usage1352 *1353 * @param packet1354 */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 #endif1366 1367 1229 /** @} 1368 1230 */
Note:
See TracChangeset
for help on using the changeset viewer.