2 * Copyright (c) 2011 Radim Vansa
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * @brief Default DDF NIC interface methods implementations
39 #include <str_error.h>
40 #include <ipc/services.h>
42 #include "nic_driver.h"
47 * Default implementation of the set_state method. Trivial.
54 errno_t
nic_get_state_impl(ddf_fun_t
*fun
, nic_device_state_t
*state
)
56 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
57 fibril_rwlock_read_lock(&nic_data
->main_lock
);
58 *state
= nic_data
->state
;
59 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
64 * Default implementation of the set_state method. Changes the internal
65 * driver's state, calls the appropriate callback and notifies the NIL service
69 * @param state The new device's state
71 * @return EOK If the state was changed
72 * @return EINVAL If the state cannot be changed
74 errno_t
nic_set_state_impl(ddf_fun_t
*fun
, nic_device_state_t state
)
76 if (state
>= NIC_STATE_MAX
) {
80 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
82 fibril_rwlock_write_lock(&nic_data
->main_lock
);
83 if (nic_data
->state
== state
) {
84 /* No change, nothing to do */
85 fibril_rwlock_write_unlock(&nic_data
->main_lock
);
88 if (state
== NIC_STATE_ACTIVE
) {
89 if (nic_data
->client_session
== NULL
) {
90 fibril_rwlock_write_unlock(&nic_data
->main_lock
);
95 state_change_handler event_handler
= NULL
;
97 case NIC_STATE_STOPPED
:
98 event_handler
= nic_data
->on_stopping
;
101 event_handler
= nic_data
->on_going_down
;
103 case NIC_STATE_ACTIVE
:
104 event_handler
= nic_data
->on_activating
;
109 if (event_handler
!= NULL
) {
110 errno_t rc
= event_handler(nic_data
);
112 fibril_rwlock_write_unlock(&nic_data
->main_lock
);
117 if (state
== NIC_STATE_STOPPED
) {
118 /* Notify upper layers that we are reseting the MAC */
119 errno_t rc
= nic_ev_addr_changed(nic_data
->client_session
,
120 &nic_data
->default_mac
);
121 nic_data
->poll_mode
= nic_data
->default_poll_mode
;
122 memcpy(&nic_data
->poll_period
, &nic_data
->default_poll_period
,
123 sizeof(struct timespec
));
126 * We have already ran the on stopped handler, even if we
127 * terminated the state change we would end up in undefined state.
128 * Therefore we just log the problem.
132 fibril_rwlock_write_lock(&nic_data
->stats_lock
);
133 memset(&nic_data
->stats
, 0, sizeof(nic_device_stats_t
));
134 fibril_rwlock_write_unlock(&nic_data
->stats_lock
);
136 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
137 nic_rxc_clear(&nic_data
->rx_control
);
138 /* Reinsert device's default MAC */
139 nic_rxc_set_addr(&nic_data
->rx_control
, NULL
,
140 &nic_data
->default_mac
);
141 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
142 memcpy(&nic_data
->mac
, &nic_data
->default_mac
, sizeof (nic_address_t
));
144 fibril_rwlock_write_lock(&nic_data
->wv_lock
);
145 nic_wol_virtues_clear(&nic_data
->wol_virtues
);
146 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
148 /* Ensure stopping period of NIC_POLL_SOFTWARE_PERIODIC */
149 nic_sw_period_stop(nic_data
);
152 nic_data
->state
= state
;
154 nic_ev_device_state(nic_data
->client_session
, state
);
156 fibril_rwlock_write_unlock(&nic_data
->main_lock
);
162 * Default implementation of the send_frame method.
163 * Send messages to the network.
166 * @param data Frame data
167 * @param size Frame size in bytes
169 * @return EOK If the message was sent
170 * @return EBUSY If the device is not in state when the frame can be sent.
172 errno_t
nic_send_frame_impl(ddf_fun_t
*fun
, void *data
, size_t size
)
174 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
176 fibril_rwlock_read_lock(&nic_data
->main_lock
);
177 if (nic_data
->state
!= NIC_STATE_ACTIVE
|| nic_data
->tx_busy
) {
178 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
182 nic_data
->send_frame(nic_data
, data
, size
);
183 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
188 * Default implementation of the connect_client method.
189 * Creates callback connection to the client.
193 * @return EOK On success, or an error code.
195 errno_t
nic_callback_create_impl(ddf_fun_t
*fun
)
197 nic_t
*nic
= nic_get_from_ddf_fun(fun
);
198 fibril_rwlock_write_lock(&nic
->main_lock
);
200 nic
->client_session
= async_callback_receive(EXCHANGE_SERIALIZE
);
201 if (nic
->client_session
== NULL
) {
202 fibril_rwlock_write_unlock(&nic
->main_lock
);
206 fibril_rwlock_write_unlock(&nic
->main_lock
);
211 * Default implementation of the get_address method.
212 * Retrieves the NIC's physical address.
215 * @param address Pointer to the structure where the address will be stored.
217 * @return EOK If the services were bound
218 * @return ELIMIT If the buffer is too short
220 errno_t
nic_get_address_impl(ddf_fun_t
*fun
, nic_address_t
*address
)
223 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
224 fibril_rwlock_read_lock(&nic_data
->main_lock
);
225 memcpy(address
, &nic_data
->mac
, sizeof (nic_address_t
));
226 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
231 * Default implementation of the get_stats method. Copies the statistics from
232 * the drivers data to supplied buffer.
235 * @param[out] stats The buffer for statistics
237 * @return EOK (cannot fail)
239 errno_t
nic_get_stats_impl(ddf_fun_t
*fun
, nic_device_stats_t
*stats
)
241 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
242 assert (stats
!= NULL
);
243 fibril_rwlock_read_lock(&nic_data
->stats_lock
);
244 memcpy(stats
, &nic_data
->stats
, sizeof (nic_device_stats_t
));
245 fibril_rwlock_read_unlock(&nic_data
->stats_lock
);
250 * Default implementation of unicast_get_mode method.
253 * @param[out] mode Current operation mode
254 * @param[in] max_count Max number of addresses that can be written into the
255 * buffer (addr_list).
256 * @param[out] addr_list Buffer for addresses
257 * @param[out] addr_count Number of addresses written into the list
261 errno_t
nic_unicast_get_mode_impl(ddf_fun_t
*fun
, nic_unicast_mode_t
*mode
,
262 size_t max_count
, nic_address_t
*addr_list
, size_t *addr_count
)
264 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
265 fibril_rwlock_read_lock(&nic_data
->rxc_lock
);
266 nic_rxc_unicast_get_mode(&nic_data
->rx_control
, mode
, max_count
,
267 addr_list
, addr_count
);
268 fibril_rwlock_read_unlock(&nic_data
->rxc_lock
);
273 * Default implementation of unicast_set_mode method.
276 * @param[in] mode New operation mode
277 * @param[in] addr_list List of unicast addresses
278 * @param[in] addr_count Number of addresses in the list
285 errno_t
nic_unicast_set_mode_impl(ddf_fun_t
*fun
,
286 nic_unicast_mode_t mode
, const nic_address_t
*addr_list
, size_t addr_count
)
288 assert((addr_count
== 0 && addr_list
== NULL
) ||
289 (addr_count
!= 0 && addr_list
!= NULL
));
291 for (i
= 0; i
< addr_count
; ++i
) {
292 if (addr_list
[i
].address
[0] & 1)
296 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
297 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
298 errno_t rc
= ENOTSUP
;
299 if (nic_data
->on_unicast_mode_change
) {
300 rc
= nic_data
->on_unicast_mode_change(nic_data
,
301 mode
, addr_list
, addr_count
);
304 rc
= nic_rxc_unicast_set_mode(&nic_data
->rx_control
, mode
,
305 addr_list
, addr_count
);
307 * After changing the mode the addr db gets cleared, therefore we have
308 * to reinsert also the physical address of NIC.
310 nic_rxc_set_addr(&nic_data
->rx_control
, NULL
, &nic_data
->mac
);
312 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
318 * Default implementation of multicast_get_mode method.
321 * @param[out] mode Current operation mode
322 * @param[in] max_count Max number of addresses that can be written into the
323 * buffer (addr_list).
324 * @param[out] addr_list Buffer for addresses
325 * @param[out] addr_count Number of addresses written into the list
329 errno_t
nic_multicast_get_mode_impl(ddf_fun_t
*fun
, nic_multicast_mode_t
*mode
,
330 size_t max_count
, nic_address_t
*addr_list
, size_t *addr_count
)
332 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
333 fibril_rwlock_read_lock(&nic_data
->rxc_lock
);
334 nic_rxc_multicast_get_mode(&nic_data
->rx_control
, mode
, max_count
,
335 addr_list
, addr_count
);
336 fibril_rwlock_read_unlock(&nic_data
->rxc_lock
);
341 * Default implementation of multicast_set_mode method.
344 * @param[in] mode New operation mode
345 * @param[in] addr_list List of multicast addresses
346 * @param[in] addr_count Number of addresses in the list
353 errno_t
nic_multicast_set_mode_impl(ddf_fun_t
*fun
, nic_multicast_mode_t mode
,
354 const nic_address_t
*addr_list
, size_t addr_count
)
356 assert((addr_count
== 0 && addr_list
== NULL
) ||
357 (addr_count
!= 0 && addr_list
!= NULL
));
359 for (i
= 0; i
< addr_count
; ++i
) {
360 if (!(addr_list
[i
].address
[0] & 1))
364 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
365 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
366 errno_t rc
= ENOTSUP
;
367 if (nic_data
->on_multicast_mode_change
) {
368 rc
= nic_data
->on_multicast_mode_change(nic_data
, mode
, addr_list
, addr_count
);
371 rc
= nic_rxc_multicast_set_mode(&nic_data
->rx_control
, mode
,
372 addr_list
, addr_count
);
374 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
379 * Default implementation of broadcast_get_mode method.
382 * @param[out] mode Current operation mode
386 errno_t
nic_broadcast_get_mode_impl(ddf_fun_t
*fun
, nic_broadcast_mode_t
*mode
)
388 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
389 fibril_rwlock_read_lock(&nic_data
->rxc_lock
);
390 nic_rxc_broadcast_get_mode(&nic_data
->rx_control
, mode
);
391 fibril_rwlock_read_unlock(&nic_data
->rxc_lock
);
396 * Default implementation of broadcast_set_mode method.
399 * @param[in] mode New operation mode
406 errno_t
nic_broadcast_set_mode_impl(ddf_fun_t
*fun
, nic_broadcast_mode_t mode
)
408 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
409 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
410 errno_t rc
= ENOTSUP
;
411 if (nic_data
->on_broadcast_mode_change
) {
412 rc
= nic_data
->on_broadcast_mode_change(nic_data
, mode
);
415 rc
= nic_rxc_broadcast_set_mode(&nic_data
->rx_control
, mode
);
417 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
422 * Default implementation of blocked_sources_get method.
425 * @param[in] max_count Max number of addresses that can be written into the
426 * buffer (addr_list).
427 * @param[out] addr_list Buffer for addresses
428 * @param[out] addr_count Number of addresses written into the list
432 errno_t
nic_blocked_sources_get_impl(ddf_fun_t
*fun
,
433 size_t max_count
, nic_address_t
*addr_list
, size_t *addr_count
)
435 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
436 fibril_rwlock_read_lock(&nic_data
->rxc_lock
);
437 nic_rxc_blocked_sources_get(&nic_data
->rx_control
,
438 max_count
, addr_list
, addr_count
);
439 fibril_rwlock_read_unlock(&nic_data
->rxc_lock
);
444 * Default implementation of blocked_sources_set method.
447 * @param[in] addr_list List of blocked addresses
448 * @param[in] addr_count Number of addresses in the list
455 errno_t
nic_blocked_sources_set_impl(ddf_fun_t
*fun
,
456 const nic_address_t
*addr_list
, size_t addr_count
)
458 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
459 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
460 if (nic_data
->on_blocked_sources_change
) {
461 nic_data
->on_blocked_sources_change(nic_data
, addr_list
, addr_count
);
463 errno_t rc
= nic_rxc_blocked_sources_set(&nic_data
->rx_control
,
464 addr_list
, addr_count
);
465 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
470 * Default implementation of vlan_get_mask method.
473 * @param[out] mask Current VLAN mask
476 * @return ENOENT If the mask is not set
478 errno_t
nic_vlan_get_mask_impl(ddf_fun_t
*fun
, nic_vlan_mask_t
*mask
)
480 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
481 fibril_rwlock_read_lock(&nic_data
->rxc_lock
);
482 errno_t rc
= nic_rxc_vlan_get_mask(&nic_data
->rx_control
, mask
);
483 fibril_rwlock_read_unlock(&nic_data
->rxc_lock
);
488 * Default implementation of vlan_set_mask method.
491 * @param[in] mask The new VLAN mask
496 errno_t
nic_vlan_set_mask_impl(ddf_fun_t
*fun
, const nic_vlan_mask_t
*mask
)
498 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
499 fibril_rwlock_write_lock(&nic_data
->rxc_lock
);
500 errno_t rc
= nic_rxc_vlan_set_mask(&nic_data
->rx_control
, mask
);
501 if (rc
== EOK
&& nic_data
->on_vlan_mask_change
) {
502 nic_data
->on_vlan_mask_change(nic_data
, mask
);
504 fibril_rwlock_write_unlock(&nic_data
->rxc_lock
);
509 * Default implementation of the wol_virtue_add method.
510 * Create a new WOL virtue.
513 * @param[in] type Type of the virtue
514 * @param[in] data Data required for this virtue (depends on type)
515 * @param[in] length Length of the data
516 * @param[out] filter Identifier of the new virtue
518 * @return EOK If the operation was successfully completed
519 * @return EINVAL If virtue type is not supported or the data are invalid
520 * @return ELIMIT If the driver does not allow to create more virtues
521 * @return ENOMEM If there was not enough memory to complete the operation
523 errno_t
nic_wol_virtue_add_impl(ddf_fun_t
*fun
, nic_wv_type_t type
,
524 const void *data
, size_t length
, nic_wv_id_t
*new_id
)
526 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
527 if (nic_data
->on_wol_virtue_add
== NULL
||
528 nic_data
->on_wol_virtue_remove
== NULL
) {
531 if (type
== NIC_WV_NONE
|| type
>= NIC_WV_MAX
) {
534 if (nic_wol_virtues_verify(type
, data
, length
) != EOK
) {
537 nic_wol_virtue_t
*virtue
= malloc(sizeof (nic_wol_virtue_t
));
538 if (virtue
== NULL
) {
541 memset(virtue
, 0, sizeof(nic_wol_virtue_t
));
543 virtue
->data
= malloc(length
);
544 if (virtue
->data
== NULL
) {
548 memcpy((void *) virtue
->data
, data
, length
);
551 virtue
->length
= length
;
553 fibril_rwlock_write_lock(&nic_data
->wv_lock
);
554 /* Check if we haven't reached the maximum */
555 if (nic_data
->wol_virtues
.caps_max
[type
] < 0) {
556 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
559 if ((int) nic_data
->wol_virtues
.lists_sizes
[type
] >=
560 nic_data
->wol_virtues
.caps_max
[type
]) {
561 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
564 /* Call the user-defined add callback */
565 errno_t rc
= nic_data
->on_wol_virtue_add(nic_data
, virtue
);
569 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
572 rc
= nic_wol_virtues_add(&nic_data
->wol_virtues
, virtue
);
574 /* If the adding fails, call user-defined remove callback */
575 nic_data
->on_wol_virtue_remove(nic_data
, virtue
);
576 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
581 *new_id
= virtue
->id
;
582 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
588 * Default implementation of the wol_virtue_remove method.
589 * Destroys the WOL virtue.
592 * @param[in] id WOL virtue identification
594 * @return EOK If the operation was successfully completed
595 * @return ENOTSUP If the function is not supported by the driver or device
596 * @return ENOENT If the virtue identifier is not valid.
598 errno_t
nic_wol_virtue_remove_impl(ddf_fun_t
*fun
, nic_wv_id_t id
)
600 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
601 if (nic_data
->on_wol_virtue_add
== NULL
||
602 nic_data
->on_wol_virtue_remove
== NULL
) {
605 fibril_rwlock_write_lock(&nic_data
->wv_lock
);
606 nic_wol_virtue_t
*virtue
=
607 nic_wol_virtues_remove(&nic_data
->wol_virtues
, id
);
608 if (virtue
== NULL
) {
609 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
612 /* The event handler is called after the filter was removed */
613 nic_data
->on_wol_virtue_remove(nic_data
, virtue
);
614 fibril_rwlock_write_unlock(&nic_data
->wv_lock
);
621 * Default implementation of the wol_virtue_probe method.
622 * Queries the type and data of the virtue.
625 * @param[in] id Virtue identifier
626 * @param[out] type Type of the virtue. Can be NULL.
627 * @param[out] data Data used when the virtue was created. Can be NULL.
628 * @param[out] length Length of the data. Can be NULL.
630 * @return EOK If the operation was successfully completed
631 * @return ENOENT If the virtue identifier is not valid.
632 * @return ENOMEM If there was not enough memory to complete the operation
634 errno_t
nic_wol_virtue_probe_impl(ddf_fun_t
*fun
, nic_wv_id_t id
,
635 nic_wv_type_t
*type
, size_t max_length
, void *data
, size_t *length
)
637 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
638 fibril_rwlock_read_lock(&nic_data
->wv_lock
);
639 const nic_wol_virtue_t
*virtue
=
640 nic_wol_virtues_find(&nic_data
->wol_virtues
, id
);
641 if (virtue
== NULL
) {
644 fibril_rwlock_read_unlock(&nic_data
->wv_lock
);
647 *type
= virtue
->type
;
648 if (max_length
> virtue
->length
) {
649 max_length
= virtue
->length
;
651 memcpy(data
, virtue
->data
, max_length
);
652 *length
= virtue
->length
;
653 fibril_rwlock_read_unlock(&nic_data
->wv_lock
);
659 * Default implementation of the wol_virtue_list method.
660 * List filters of the specified type. If NIC_WV_NONE is the type, it lists all
664 * @param[in] type Type of the virtues
665 * @param[out] virtues Vector of virtue ID's.
666 * @param[out] count Length of the data. Can be NULL.
668 * @return EOK If the operation was successfully completed
669 * @return ENOENT If the filter identification is not valid.
670 * @return ENOMEM If there was not enough memory to complete the operation
672 errno_t
nic_wol_virtue_list_impl(ddf_fun_t
*fun
, nic_wv_type_t type
,
673 size_t max_count
, nic_wv_id_t
*id_list
, size_t *id_count
)
675 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
676 fibril_rwlock_read_lock(&nic_data
->wv_lock
);
677 errno_t rc
= nic_wol_virtues_list(&nic_data
->wol_virtues
, type
,
678 max_count
, id_list
, id_count
);
679 fibril_rwlock_read_unlock(&nic_data
->wv_lock
);
684 * Default implementation of the wol_virtue_get_caps method.
685 * Queries for the current capabilities for some type of filter.
688 * @param[in] type Type of the virtues
689 * @param[out] count Number of virtues of this type that can be currently set
691 * @return EOK If the operation was successfully completed
693 errno_t
nic_wol_virtue_get_caps_impl(ddf_fun_t
*fun
, nic_wv_type_t type
, int *count
)
695 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
696 fibril_rwlock_read_lock(&nic_data
->wv_lock
);
697 *count
= nic_data
->wol_virtues
.caps_max
[type
] -
698 (int) nic_data
->wol_virtues
.lists_sizes
[type
];
699 fibril_rwlock_read_unlock(&nic_data
->wv_lock
);
704 * Default implementation of the poll_get_mode method.
705 * Queries the current interrupt/poll mode of the NIC
708 * @param[out] mode Current poll mode
709 * @param[out] period Period used in periodic polling. Can be NULL.
711 * @return EOK If the operation was successfully completed
712 * @return ENOTSUP This function is not supported.
713 * @return EPARTY Error in communication protocol
715 errno_t
nic_poll_get_mode_impl(ddf_fun_t
*fun
,
716 nic_poll_mode_t
*mode
, struct timespec
*period
)
718 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
719 fibril_rwlock_read_lock(&nic_data
->main_lock
);
720 *mode
= nic_data
->poll_mode
;
721 memcpy(period
, &nic_data
->poll_period
, sizeof(struct timespec
));
722 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
727 * Default implementation of the poll_set_mode_impl method.
728 * Sets the interrupt/poll mode of the NIC.
731 * @param[in] mode The new poll mode
732 * @param[in] period Period used in periodic polling. Can be NULL.
734 * @return EOK If the operation was successfully completed
735 * @return ENOTSUP This operation is not supported.
736 * @return EPARTY Error in communication protocol
738 errno_t
nic_poll_set_mode_impl(ddf_fun_t
*fun
,
739 nic_poll_mode_t mode
, const struct timespec
*period
)
741 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
743 * If the driver does not implement the poll mode change handler it cannot
744 * switch off interrupts and this is not supported.
746 if (nic_data
->on_poll_mode_change
== NULL
)
749 if ((mode
== NIC_POLL_ON_DEMAND
) && nic_data
->on_poll_request
== NULL
)
752 if (mode
== NIC_POLL_PERIODIC
|| mode
== NIC_POLL_SOFTWARE_PERIODIC
) {
755 if (period
->tv_sec
== 0 && period
->tv_nsec
== 0)
757 if (period
->tv_sec
< 0 || period
->tv_nsec
< 0)
760 fibril_rwlock_write_lock(&nic_data
->main_lock
);
761 errno_t rc
= nic_data
->on_poll_mode_change(nic_data
, mode
, period
);
762 assert(rc
== EOK
|| rc
== ENOTSUP
|| rc
== EINVAL
);
763 if (rc
== ENOTSUP
&& (nic_data
->on_poll_request
!= NULL
) &&
764 (mode
== NIC_POLL_PERIODIC
|| mode
== NIC_POLL_SOFTWARE_PERIODIC
)) {
766 rc
= nic_data
->on_poll_mode_change(nic_data
, NIC_POLL_ON_DEMAND
, NULL
);
767 assert(rc
== EOK
|| rc
== ENOTSUP
);
769 nic_sw_period_start(nic_data
);
772 nic_data
->poll_mode
= mode
;
774 nic_data
->poll_period
= *period
;
776 fibril_rwlock_write_unlock(&nic_data
->main_lock
);
781 * Default implementation of the poll_now method.
782 * Wrapper for the actual poll implementation.
786 * @return EOK If the NIC was polled
787 * @return ENOTSUP If the function is not supported
788 * @return EINVAL If the NIC is not in state where it allows on demand polling
790 errno_t
nic_poll_now_impl(ddf_fun_t
*fun
)
792 nic_t
*nic_data
= nic_get_from_ddf_fun(fun
);
793 fibril_rwlock_read_lock(&nic_data
->main_lock
);
794 if (nic_data
->poll_mode
!= NIC_POLL_ON_DEMAND
) {
795 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
798 if (nic_data
->on_poll_request
!= NULL
) {
799 nic_data
->on_poll_request(nic_data
);
800 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
803 fibril_rwlock_read_unlock(&nic_data
->main_lock
);
809 * Default handler for unknown methods (outside of the NIC interface).
810 * Logs a warning message and returns ENOTSUP to the caller.
812 * @param fun The DDF function where the method should be called.
813 * @param call IPC call data
816 void nic_default_handler_impl(ddf_fun_t
*fun
, ipc_call_t
*call
)
818 async_answer_0(call
, ENOTSUP
);
822 * Default (empty) OPEN function implementation.
824 * @param fun The DDF function
826 * @return EOK always.
828 errno_t
nic_open_impl(ddf_fun_t
*fun
)
834 * Default (empty) OPEN function implementation.
836 * @param fun The DDF function
838 void nic_close_impl(ddf_fun_t
*fun
)