source: mainline/uspace/drv/nic/rtl8139/driver.c@ eadaeae8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since eadaeae8 was eadaeae8, checked in by Jakub Jermar <jakub@…>, 7 years ago

Make capability handles type-safe

Define distinct pointer types for the handles of the supported
capability types and use them instead of integer handles. This makes it
virtually impossible to pass a non-handle or a handle of different type
instead of the proper handle. Also turn cap_handle_t into an "untyped"
capability handle that can be assigned to and from the "typed" handles.

This commit also fixes a bug in msim-con driver, which wrongly used the
IRQ number instead of the IRQ capability handle to unregister the IRQ.

This commit also fixes the wrong use of the capability handle instead
of error code in libusbhost.

  • Property mode set to 100644
File size: 57.5 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Michalec
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29#include <assert.h>
30#include <async.h>
31#include <errno.h>
32#include <align.h>
33#include <byteorder.h>
34#include <libarch/barrier.h>
35#include <as.h>
36#include <ddf/log.h>
37#include <ddf/interrupt.h>
38#include <device/hw_res.h>
39#include <io/log.h>
40#include <nic.h>
41#include <pci_dev_iface.h>
42#include <stdio.h>
43#include <str.h>
44
45#include "defs.h"
46#include "driver.h"
47#include "general.h"
48
49/** Global mutex for work with shared irq structure */
50FIBRIL_MUTEX_INITIALIZE(irq_reg_lock);
51
52/** Lock interrupt structure mutex */
53#define RTL8139_IRQ_STRUCT_LOCK() \
54 fibril_mutex_lock(&irq_reg_lock)
55
56/** Unlock interrupt structure mutex */
57#define RTL8139_IRQ_STRUCT_UNLOCK() \
58 fibril_mutex_unlock(&irq_reg_lock)
59
60/** PCI clock frequency in kHz */
61#define RTL8139_PCI_FREQ_KHZ 33000
62
63#define RTL8139_AUTONEG_CAPS (ETH_AUTONEG_10BASE_T_HALF | \
64 ETH_AUTONEG_10BASE_T_FULL | ETH_AUTONEG_100BASE_TX_HALF | \
65 ETH_AUTONEG_100BASE_TX_FULL | ETH_AUTONEG_PAUSE_SYMETRIC)
66
67/** Lock transmitter and receiver data
68 *
69 * This function shall be called whenever
70 * both transmitter and receiver locking
71 * to force safe lock ordering (deadlock prevention)
72 *
73 * @param rtl8139 RTL8139 private data
74 *
75 */
76inline static void rtl8139_lock_all(rtl8139_t *rtl8139)
77{
78 assert(rtl8139);
79 fibril_mutex_lock(&rtl8139->tx_lock);
80 fibril_mutex_lock(&rtl8139->rx_lock);
81}
82
83/** Unlock transmitter and receiver data
84 *
85 * @param rtl8139 RTL8139 private data
86 *
87 */
88inline static void rtl8139_unlock_all(rtl8139_t *rtl8139)
89{
90 assert(rtl8139);
91 fibril_mutex_unlock(&rtl8139->rx_lock);
92 fibril_mutex_unlock(&rtl8139->tx_lock);
93}
94
95#ifndef RXBUF_SIZE_FLAGS
96 /** Flags for receiver buffer - 16kB default */
97 #define RXBUF_SIZE_FLAGS RTL8139_RXFLAGS_SIZE_16
98#endif
99
100#if (RXBUF_SIZE_FLAGS > RTL8139_RXFLAGS_SIZE_64) || (RXBUF_SIZE_FLAGS < 0)
101 #error Bad receiver buffer flags size flags
102#endif
103
104/** Size of the receiver buffer
105 *
106 * Incrementing flags by one twices the buffer size
107 * the lowest size is 8*1024 (flags = 0)
108 */
109#define RxBUF_SIZE RTL8139_RXSIZE(RXBUF_SIZE_FLAGS)
110
111/** Total size of the receiver buffer to allocate */
112#define RxBUF_TOT_LENGTH RTL8139_RXBUF_LENGTH(RXBUF_SIZE_FLAGS)
113
114
115/** Default interrupt mask */
116#define RTL_DEFAULT_INTERRUPTS UINT16_C(0xFFFF)
117
118/** Obtain the value of the register part
119 * The bit operations will be done
120 * The _SHIFT and _MASK for the register part must exists as macros
121 * or variables
122 */
123#define REG_GET_VAL(value, reg_part)\
124 (((value) >> reg_part##_SHIFT) & reg_part##_MASK)
125
126
127/** Set interrupts on controller
128 *
129 * @param rtl8139 The card private structure
130 */
131inline static void rtl8139_hw_int_set(rtl8139_t *rtl8139)
132{
133 pio_write_16(rtl8139->io_port + IMR, rtl8139->int_mask);
134}
135
136/** Check on the controller if the receiving buffer is empty
137 *
138 * @param rtl8139 The controller data
139 *
140 * @return Nonzero if empty, zero otherwise
141 */
142inline static int rtl8139_hw_buffer_empty(rtl8139_t *rtl8139)
143{
144 return pio_read_16(rtl8139->io_port + CR) & CR_BUFE;
145}
146
147/** Update the mask of accepted frames in the RCR register according to
148 * rcr_accept_mode value in rtl8139_t
149 *
150 * @param rtl8139 The rtl8139 private data
151 */
152static void rtl8139_hw_update_rcr(rtl8139_t *rtl8139)
153{
154 uint32_t rcr = rtl8139->rcr_data.rcr_base | rtl8139->rcr_data.ucast_mask
155 | rtl8139->rcr_data.mcast_mask | rtl8139->rcr_data.bcast_mask
156 | rtl8139->rcr_data.defect_mask |
157 (RXBUF_SIZE_FLAGS << RCR_RBLEN_SHIFT);
158
159 ddf_msg(LVL_DEBUG, "Rewriting rcr: %x -> %x", pio_read_32(rtl8139->io_port + RCR),
160 rcr);
161
162 pio_write_32(rtl8139->io_port + RCR, rcr);
163}
164
165/** Fill the mask of accepted multicast frames in the card registers
166 *
167 * @param rtl8139 The rtl8139 private data
168 * @param mask The mask to set
169 */
170inline static void rtl8139_hw_set_mcast_mask(rtl8139_t *rtl8139,
171 uint64_t mask)
172{
173 pio_write_32(rtl8139->io_port + MAR0, (uint32_t) mask);
174 pio_write_32(rtl8139->io_port + MAR0 + sizeof(uint32_t),
175 (uint32_t)(mask >> 32));
176 return;
177}
178
179/** Set PmEn (Power management enable) bit value
180 *
181 * @param rtl8139 rtl8139 card data
182 * @param bit_val If bit_val is zero pmen is set to 0, otherwise pmen is set to 1
183 */
184inline static void rtl8139_hw_pmen_set(rtl8139_t *rtl8139, uint8_t bit_val)
185{
186 uint8_t config1 = pio_read_8(rtl8139->io_port + CONFIG1);
187 uint8_t config1_new;
188 if (bit_val)
189 config1_new = config1 | CONFIG1_PMEn;
190 else
191 config1_new = config1 & ~(uint8_t)(CONFIG1_PMEn);
192
193 if (config1_new == config1)
194 return;
195
196 rtl8139_regs_unlock(rtl8139->io_port);
197 pio_write_8(rtl8139->io_port + CONFIG1, config1_new);
198 rtl8139_regs_lock(rtl8139->io_port);
199
200 async_sess_t *pci_sess =
201 ddf_dev_parent_sess_get(nic_get_ddf_dev(rtl8139->nic_data));
202
203 if (bit_val) {
204 uint8_t pmen;
205 pci_config_space_read_8(pci_sess, 0x55, &pmen);
206 pci_config_space_write_8(pci_sess, 0x55, pmen | 1 | (1 << 7));
207 } else {
208 uint8_t pmen;
209 pci_config_space_read_8(pci_sess, 0x55, &pmen);
210 pci_config_space_write_8(pci_sess, 0x55, pmen & ~(1 | (1 << 7)));
211 }
212}
213
214/** Get MAC address of the RTL8139 adapter
215 *
216 * @param rtl8139 The RTL8139 device
217 * @param address The place to store the address
218 *
219 * @return EOK if succeed, error code otherwise
220 */
221inline static void rtl8139_hw_get_addr(rtl8139_t *rtl8139,
222 nic_address_t *addr)
223{
224 assert(rtl8139);
225 assert(addr);
226
227 uint32_t *mac0_dest = (uint32_t *)addr->address;
228 uint16_t *mac4_dest = (uint16_t *)(addr->address + 4);
229
230 /* Read MAC address from the i/o (4byte + 2byte reads) */
231 *mac0_dest = pio_read_32(rtl8139->io_port + MAC0);
232 *mac4_dest = pio_read_16(rtl8139->io_port + MAC0 + 4);
233}
234
235/** Set MAC address to the device
236 *
237 * @param rtl8139 Controller private structure
238 * @param addr The address to set
239 */
240static void rtl8139_hw_set_addr(rtl8139_t *rtl8139, const nic_address_t *addr)
241{
242 assert(rtl8139);
243 assert(addr);
244
245 const uint32_t *val1 = (const uint32_t*)addr->address;
246 const uint16_t *val2 = (const uint16_t*)(addr->address + sizeof(uint32_t));
247
248 rtl8139_regs_unlock(rtl8139->io_port);
249 pio_write_32(rtl8139->io_port + MAC0, *val1);
250 pio_write_32(rtl8139->io_port + MAC0 + 4, *val2);
251 rtl8139_regs_lock(rtl8139->io_port);
252}
253
254/** Provide OR in the 8bit register (set selected bits to 1)
255 *
256 * @param rtl8139 The rtl8139 structure
257 * @param reg_offset Register offset in the device IO space
258 * @param bits_add The value to or
259 */
260inline static void rtl8139_hw_reg_add_8(rtl8139_t * rtl8139, size_t reg_offset,
261 uint8_t bits_add)
262{
263 uint8_t value = pio_read_8(rtl8139->io_port + reg_offset);
264 value |= bits_add;
265 pio_write_8(rtl8139->io_port + reg_offset, value);
266}
267
268/** Unset selected bits in 8bit register
269 *
270 * @param rtl8139 The rtl8139 structure
271 * @param reg_offset Register offset in the device IO space
272 * @param bits_add The mask of bits to remove
273 */
274inline static void rtl8139_hw_reg_rem_8(rtl8139_t * rtl8139, size_t reg_offset,
275 uint8_t bits_add)
276{
277 uint8_t value = pio_read_8(rtl8139->io_port + reg_offset);
278 value &= ~bits_add;
279 pio_write_8(rtl8139->io_port + reg_offset, value);
280}
281
282static errno_t rtl8139_set_addr(ddf_fun_t *fun, const nic_address_t *);
283static errno_t rtl8139_get_device_info(ddf_fun_t *fun, nic_device_info_t *info);
284static errno_t rtl8139_get_cable_state(ddf_fun_t *fun, nic_cable_state_t *state);
285static errno_t rtl8139_get_operation_mode(ddf_fun_t *fun, int *speed,
286 nic_channel_mode_t *duplex, nic_role_t *role);
287static errno_t rtl8139_set_operation_mode(ddf_fun_t *fun, int speed,
288 nic_channel_mode_t duplex, nic_role_t);
289
290static errno_t rtl8139_pause_get(ddf_fun_t*, nic_result_t*, nic_result_t*,
291 uint16_t *);
292static errno_t rtl8139_pause_set(ddf_fun_t*, int, int, uint16_t);
293
294static errno_t rtl8139_autoneg_enable(ddf_fun_t *fun, uint32_t advertisement);
295static errno_t rtl8139_autoneg_disable(ddf_fun_t *fun);
296static errno_t rtl8139_autoneg_probe(ddf_fun_t *fun, uint32_t *our_advertisement,
297 uint32_t *their_advertisement, nic_result_t *result,
298 nic_result_t *their_result);
299static errno_t rtl8139_autoneg_restart(ddf_fun_t *fun);
300
301static errno_t rtl8139_defective_get_mode(ddf_fun_t *fun, uint32_t *mode);
302static errno_t rtl8139_defective_set_mode(ddf_fun_t *fun, uint32_t mode);
303
304static errno_t rtl8139_wol_virtue_add(nic_t *nic_data,
305 const nic_wol_virtue_t *virtue);
306static void rtl8139_wol_virtue_rem(nic_t *nic_data,
307 const nic_wol_virtue_t *virtue);
308
309static errno_t rtl8139_poll_mode_change(nic_t *nic_data, nic_poll_mode_t mode,
310 const struct timeval *period);
311static void rtl8139_poll(nic_t *nic_data);
312
313/** Network interface options for RTL8139 card driver */
314static nic_iface_t rtl8139_nic_iface = {
315 .set_address = &rtl8139_set_addr,
316 .get_device_info = &rtl8139_get_device_info,
317 .get_cable_state = &rtl8139_get_cable_state,
318 .get_operation_mode = &rtl8139_get_operation_mode,
319 .set_operation_mode = &rtl8139_set_operation_mode,
320
321 .get_pause = &rtl8139_pause_get,
322 .set_pause = &rtl8139_pause_set,
323
324 .autoneg_enable = &rtl8139_autoneg_enable,
325 .autoneg_disable = &rtl8139_autoneg_disable,
326 .autoneg_probe = &rtl8139_autoneg_probe,
327 .autoneg_restart = &rtl8139_autoneg_restart,
328
329 .defective_get_mode = &rtl8139_defective_get_mode,
330 .defective_set_mode = &rtl8139_defective_set_mode,
331};
332
333/** Basic device operations for RTL8139 driver */
334static ddf_dev_ops_t rtl8139_dev_ops;
335
336static errno_t rtl8139_dev_add(ddf_dev_t *dev);
337
338/** Basic driver operations for RTL8139 driver */
339static driver_ops_t rtl8139_driver_ops = {
340 .dev_add = &rtl8139_dev_add,
341};
342
343/** Driver structure for RTL8139 driver */
344static driver_t rtl8139_driver = {
345 .name = NAME,
346 .driver_ops = &rtl8139_driver_ops
347};
348
349/* The default implementation callbacks */
350static errno_t rtl8139_on_activated(nic_t *nic_data);
351static errno_t rtl8139_on_stopped(nic_t *nic_data);
352static void rtl8139_send_frame(nic_t *nic_data, void *data, size_t size);
353
354/** Check if the transmit buffer is busy */
355#define rtl8139_tbuf_busy(tsd) ((pio_read_32(tsd) & TSD_OWN) == 0)
356
357/** Send frame with the hardware
358 *
359 * note: the main_lock is locked when framework calls this function
360 *
361 * @param nic_data The nic driver data structure
362 * @param data Frame data
363 * @param size Frame size in bytes
364 *
365 * @return EOK if succeed, error code in the case of error
366 */
367static void rtl8139_send_frame(nic_t *nic_data, void *data, size_t size)
368{
369 assert(nic_data);
370
371 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
372 assert(rtl8139);
373 ddf_msg(LVL_DEBUG, "Sending frame");
374
375 if (size > RTL8139_FRAME_MAX_LENGTH) {
376 ddf_msg(LVL_ERROR, "Send frame: frame too long, %zu bytes",
377 size);
378 nic_report_send_error(rtl8139->nic_data, NIC_SEC_OTHER, 1);
379 goto err_size;
380 }
381
382 assert((size & TSD_SIZE_MASK) == size);
383
384 /* Lock transmitter structure for obtaining next buffer */
385 fibril_mutex_lock(&rtl8139->tx_lock);
386
387 /* Check if there is free buffer */
388 if (rtl8139->tx_next - TX_BUFF_COUNT == rtl8139->tx_used) {
389 nic_set_tx_busy(nic_data, 1);
390 fibril_mutex_unlock(&rtl8139->tx_lock);
391 nic_report_send_error(nic_data, NIC_SEC_BUFFER_FULL, 1);
392 goto err_busy_no_inc;
393 }
394
395 /* Get buffer id to use and set next buffer to use */
396 size_t tx_curr = rtl8139->tx_next++ % TX_BUFF_COUNT;
397
398 fibril_mutex_unlock(&rtl8139->tx_lock);
399
400 /* Get address of the buffer descriptor and frame data */
401 void *tsd = rtl8139->io_port + TSD0 + tx_curr * 4;
402 void *buf_addr = rtl8139->tx_buff[tx_curr];
403
404 /* Wait until the buffer is free */
405 assert(!rtl8139_tbuf_busy(tsd));
406
407 /* Write frame data to the buffer, set the size to TSD and clear OWN bit */
408 memcpy(buf_addr, data, size);
409
410 /* Set size of the data to send */
411 uint32_t tsd_value = pio_read_32(tsd);
412 tsd_value = rtl8139_tsd_set_size(tsd_value, size);
413 pio_write_32(tsd, tsd_value);
414
415 /* barrier for HW to really see the current buffer data */
416 write_barrier();
417
418 tsd_value &= ~(uint32_t)TSD_OWN;
419 pio_write_32(tsd, tsd_value);
420 return;
421
422err_busy_no_inc:
423err_size:
424 return;
425}
426
427
428/** Reset the controller
429 *
430 * @param io_base The address of the i/o port mapping start
431 */
432inline static void rtl8139_hw_soft_reset(void *io_base)
433{
434 pio_write_8(io_base + CR, CR_RST);
435 memory_barrier();
436 while(pio_read_8(io_base + CR) & CR_RST) {
437 async_usleep(1);
438 read_barrier();
439 }
440}
441
442/** Provide soft reset of the controller
443 *
444 * The caller must lock tx_lock and rx_lock before calling this function
445 *
446 */
447static void rtl8139_soft_reset(rtl8139_t *rtl8139)
448{
449 assert(rtl8139);
450
451 rtl8139_hw_soft_reset(rtl8139->io_port);
452 nic_t *nic_data = rtl8139->nic_data;
453
454 /* Write MAC address to the card */
455 nic_address_t addr;
456 nic_query_address(nic_data, &addr);
457 rtl8139_hw_set_addr(rtl8139, &addr);
458
459 /* Recover accept modes back */
460 rtl8139_hw_set_mcast_mask(rtl8139, nic_query_mcast_hash(nic_data));
461 rtl8139_hw_update_rcr(rtl8139);
462
463 rtl8139->tx_used = 0;
464 rtl8139->tx_next = 0;
465 nic_set_tx_busy(rtl8139->nic_data, 0);
466}
467
468/** Create frame structure from the buffer data
469 *
470 * @param nic_data NIC driver data
471 * @param rx_buffer The receiver buffer
472 * @param rx_size The buffer size
473 * @param frame_start The offset where packet data start
474 * @param frame_size The size of the frame data
475 *
476 * @return The frame list node (not connected)
477 *
478 */
479static nic_frame_t *rtl8139_read_frame(nic_t *nic_data,
480 void *rx_buffer, size_t rx_size, size_t frame_start, size_t frame_size)
481{
482 nic_frame_t *frame = nic_alloc_frame(nic_data, frame_size);
483 if (! frame) {
484 ddf_msg(LVL_ERROR, "Can not allocate frame for received frame.");
485 return NULL;
486 }
487
488 void *ret = rtl8139_memcpy_wrapped(frame->data, rx_buffer, frame_start,
489 RxBUF_SIZE, frame_size);
490 if (ret == NULL) {
491 nic_release_frame(nic_data, frame);
492 return NULL;
493 }
494 return frame;
495}
496
497/* Reset receiver
498 *
499 * Use in the case of receiver error (lost in the rx_buff)
500 *
501 * @param rtl8139 controller private data
502 */
503static void rtl8139_rx_reset(rtl8139_t *rtl8139)
504{
505 /* Disable receiver, update offset and enable receiver again */
506 uint8_t cr = pio_read_8(rtl8139->io_port + CR);
507 rtl8139_regs_unlock(rtl8139);
508
509 pio_write_8(rtl8139->io_port + CR, cr & ~(uint8_t)CR_RE);
510
511 write_barrier();
512 pio_write_32(rtl8139->io_port + CAPR, 0);
513 pio_write_32(rtl8139->io_port + RBSTART,
514 PTR2U32(rtl8139->rx_buff_phys));
515
516 write_barrier();
517
518 rtl8139_hw_update_rcr(rtl8139);
519 pio_write_8(rtl8139->io_port + CR, cr);
520 rtl8139_regs_lock(rtl8139);
521
522 nic_report_receive_error(rtl8139->nic_data, NIC_REC_OTHER, 1);
523}
524
525/** Receive all frames in queue
526 *
527 * @param nic_data The controller data
528 * @return The linked list of nic_frame_list_t nodes, each containing one frame
529 */
530static nic_frame_list_t *rtl8139_frame_receive(nic_t *nic_data)
531{
532 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
533 if (rtl8139_hw_buffer_empty(rtl8139))
534 return NULL;
535
536 nic_frame_list_t *frames = nic_alloc_frame_list();
537 if (!frames)
538 ddf_msg(LVL_ERROR, "Can not allocate frame list for received frames.");
539
540 void *rx_buffer = rtl8139->rx_buff_virt;
541
542 /* where to start reading */
543 uint16_t rx_offset = pio_read_16(rtl8139->io_port + CAPR) + 16;
544 /* unread bytes count */
545 uint16_t bytes_received = pio_read_16(rtl8139->io_port + CBA);
546 uint16_t max_read;
547 uint16_t cur_read = 0;
548
549 /* get values to the <0, buffer size) */
550 bytes_received %= RxBUF_SIZE;
551 rx_offset %= RxBUF_SIZE;
552
553 /* count how many bytes to read maximaly */
554 if (bytes_received < rx_offset)
555 max_read = bytes_received + (RxBUF_SIZE - rx_offset);
556 else
557 max_read = bytes_received - rx_offset;
558
559 memory_barrier();
560 while (!rtl8139_hw_buffer_empty(rtl8139)) {
561 void *rx_ptr = rx_buffer + rx_offset % RxBUF_SIZE;
562 uint32_t frame_header = uint32_t_le2host( *((uint32_t*)rx_ptr) );
563 uint16_t size = frame_header >> 16;
564 uint16_t frame_size = size - RTL8139_CRC_SIZE;
565 /* received frame flags in frame header */
566 uint16_t rcs = (uint16_t) frame_header;
567
568 if (size == RTL8139_EARLY_SIZE) {
569 /* The frame copying is still in progress, break receiving */
570 ddf_msg(LVL_DEBUG, "Early threshold reached, not completely coppied");
571 break;
572 }
573
574 /* Check if the header is valid, otherwise we are lost in the buffer */
575 if (size == 0 || size > RTL8139_FRAME_MAX_LENGTH) {
576 ddf_msg(LVL_ERROR, "Receiver error -> receiver reset (size: %4" PRIu16 ", "
577 "header 0x%4" PRIx32 ". Offset: %" PRIu16 ")", size, frame_header,
578 rx_offset);
579 goto rx_err;
580 }
581 if (size < RTL8139_RUNT_MAX_SIZE && !(rcs & RSR_RUNT)) {
582 ddf_msg(LVL_ERROR, "Receiver error -> receiver reset (%"PRIx16")", size);
583 goto rx_err;
584 }
585
586 cur_read += size + RTL_FRAME_HEADER_SIZE;
587 if (cur_read > max_read)
588 break;
589
590 if (frames) {
591 nic_frame_t *frame = rtl8139_read_frame(nic_data, rx_buffer,
592 RxBUF_SIZE, rx_offset + RTL_FRAME_HEADER_SIZE, frame_size);
593
594 if (frame)
595 nic_frame_list_append(frames, frame);
596 }
597
598 /* Update offset */
599 rx_offset = ALIGN_UP(rx_offset + size + RTL_FRAME_HEADER_SIZE, 4);
600
601 /* Write lesser value to prevent overflow into unread frame
602 * (the recomendation from the RealTech rtl8139 programming guide)
603 */
604 uint16_t capr_val = rx_offset - 16;
605 pio_write_16(rtl8139->io_port + CAPR, capr_val);
606
607 /* Ensure no CR read optimalization during next empty buffer test */
608 memory_barrier();
609 }
610 return frames;
611rx_err:
612 rtl8139_rx_reset(rtl8139);
613 return frames;
614}
615
616
617irq_pio_range_t rtl8139_irq_pio_ranges[] = {
618 {
619 .base = 0,
620 .size = RTL8139_IO_SIZE
621 }
622};
623
624/** Commands to deal with interrupt
625 *
626 * Read ISR, check if tere is any interrupt pending.
627 * If so, reset it and accept the interrupt.
628 * The .addr of the first and third command must
629 * be filled to the ISR port address
630 */
631irq_cmd_t rtl8139_irq_commands[] = {
632 {
633 /* Get the interrupt status */
634 .cmd = CMD_PIO_READ_16,
635 .addr = NULL,
636 .dstarg = 2
637 },
638 {
639 .cmd = CMD_PREDICATE,
640 .value = 3,
641 .srcarg = 2
642 },
643 {
644 /* Mark interrupts as solved */
645 .cmd = CMD_PIO_WRITE_16,
646 .addr = NULL,
647 .value = 0xFFFF
648 },
649 {
650 /* Disable interrupts until interrupt routine is finished */
651 .cmd = CMD_PIO_WRITE_16,
652 .addr = NULL,
653 .value = 0x0000
654 },
655 {
656 .cmd = CMD_ACCEPT
657 }
658};
659
660/** Interrupt code definition */
661irq_code_t rtl8139_irq_code = {
662 .rangecount = sizeof(rtl8139_irq_pio_ranges) / sizeof(irq_pio_range_t),
663 .ranges = rtl8139_irq_pio_ranges,
664 .cmdcount = sizeof(rtl8139_irq_commands) / sizeof(irq_cmd_t),
665 .cmds = rtl8139_irq_commands
666};
667
668/** Deal with transmitter interrupt
669 *
670 * @param nic_data Nic driver data
671 */
672static void rtl8139_tx_interrupt(nic_t *nic_data)
673{
674 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
675
676 fibril_mutex_lock(&rtl8139->tx_lock);
677
678 size_t tx_next = rtl8139->tx_next;
679 size_t tx_used = rtl8139->tx_used;
680 while (tx_used != tx_next) {
681 size_t desc_to_check = tx_used % TX_BUFF_COUNT;
682 void * tsd_to_check = rtl8139->io_port + TSD0
683 + desc_to_check * sizeof(uint32_t);
684 uint32_t tsd_value = pio_read_32(tsd_to_check);
685
686 /* If sending is still in the progress */
687 if ((tsd_value & TSD_OWN) == 0)
688 break;
689
690 tx_used++;
691
692 /* If the frame was sent */
693 if (tsd_value & TSD_TOK) {
694 size_t size = REG_GET_VAL(tsd_value, TSD_SIZE);
695 nic_report_send_ok(nic_data, 1, size);
696 } else if (tsd_value & TSD_CRS) {
697 nic_report_send_error(nic_data, NIC_SEC_CARRIER_LOST, 1);
698 } else if (tsd_value & TSD_OWC) {
699 nic_report_send_error(nic_data, NIC_SEC_WINDOW_ERROR, 1);
700 } else if (tsd_value & TSD_TABT) {
701 nic_report_send_error(nic_data, NIC_SEC_ABORTED, 1);
702 } else if (tsd_value & TSD_CDH) {
703 nic_report_send_error(nic_data, NIC_SEC_HEARTBEAT, 1);
704 }
705
706 unsigned collisions = REG_GET_VAL(tsd_value, TSD_NCC);
707 if (collisions > 0) {
708 nic_report_collisions(nic_data, collisions);
709 }
710
711 if (tsd_value & TSD_TUN) {
712 nic_report_send_error(nic_data, NIC_SEC_FIFO_OVERRUN, 1);
713 }
714 }
715 if (rtl8139->tx_used != tx_used) {
716 rtl8139->tx_used = tx_used;
717 nic_set_tx_busy(nic_data, 0);
718 }
719 fibril_mutex_unlock(&rtl8139->tx_lock);
720}
721
722/** Receive all frames from the buffer
723 *
724 * @param rtl8139 driver private data
725 */
726static void rtl8139_receive_frames(nic_t *nic_data)
727{
728 assert(nic_data);
729
730 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
731 assert(rtl8139);
732
733 fibril_mutex_lock(&rtl8139->rx_lock);
734 nic_frame_list_t *frames = rtl8139_frame_receive(nic_data);
735 fibril_mutex_unlock(&rtl8139->rx_lock);
736
737 if (frames)
738 nic_received_frame_list(nic_data, frames);
739}
740
741
742/** Deal with poll interrupt
743 *
744 * @param nic_data Nic driver data
745 */
746static int rtl8139_poll_interrupt(nic_t *nic_data)
747{
748 assert(nic_data);
749
750 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
751 assert(rtl8139);
752
753 uint32_t timer_val;
754 int receive = rtl8139_timer_act_step(&rtl8139->poll_timer, &timer_val);
755
756 assert(timer_val);
757 pio_write_32(rtl8139->io_port + TIMERINT, timer_val);
758 pio_write_32(rtl8139->io_port + TCTR, 0x0);
759 ddf_msg(LVL_DEBUG, "rtl8139 timer: %"PRIu32"\treceive: %d", timer_val, receive);
760 return receive;
761}
762
763
764/** Poll device according to isr status
765 *
766 * The isr value must be obtained and cleared by the caller. The reason
767 * of this function separate is to allow polling from both interrupt
768 * (which clears controller ISR before the handler runs) and the polling
769 * callbacks.
770 *
771 * @param nic_data Driver data
772 * @param isr Interrupt status register value
773 */
774static void rtl8139_interrupt_impl(nic_t *nic_data, uint16_t isr)
775{
776 assert(nic_data);
777
778 nic_poll_mode_t poll_mode = nic_query_poll_mode(nic_data, 0);
779
780 /* Process only when should in the polling mode */
781 if (poll_mode == NIC_POLL_PERIODIC) {
782 int receive = 0;
783 if (isr & INT_TIME_OUT) {
784 receive = rtl8139_poll_interrupt(nic_data);
785 }
786 if (! receive)
787 return;
788 }
789
790 /* Check transmittion interrupts first to allow transmit next frames
791 * sooner
792 */
793 if (isr & (INT_TOK | INT_TER)) {
794 rtl8139_tx_interrupt(nic_data);
795 }
796 if (isr & INT_ROK) {
797 rtl8139_receive_frames(nic_data);
798 }
799 if (isr & (INT_RER | INT_RXOVW | INT_FIFOOVW)) {
800 if (isr & INT_RER) {
801 //TODO: is this only the general error, or any particular?
802 }
803 if (isr & (INT_FIFOOVW)) {
804 nic_report_receive_error(nic_data, NIC_REC_FIFO_OVERRUN, 1);
805 } else if (isr & (INT_RXOVW)) {
806 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
807 assert(rtl8139);
808
809 uint32_t miss = pio_read_32(rtl8139->io_port + MPC) & MPC_VMASK;
810 pio_write_32(rtl8139->io_port + MPC, 0);
811 nic_report_receive_error(nic_data, NIC_REC_BUFFER_OVERFLOW, miss);
812 }
813 }
814}
815
816/** Handle device interrupt
817 *
818 * @param icall The IPC call structure
819 * @param dev The rtl8139 device
820 *
821 */
822static void rtl8139_interrupt_handler(ipc_call_t *icall, ddf_dev_t *dev)
823{
824 assert(dev);
825 assert(icall);
826
827 uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall);
828 nic_t *nic_data = nic_get_from_ddf_dev(dev);
829 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
830
831 rtl8139_interrupt_impl(nic_data, isr);
832
833 /* Turn the interrupts on again */
834 rtl8139_hw_int_set(rtl8139);
835}
836
837/** Register interrupt handler for the card in the system
838 *
839 * Note: the global irq_reg_mutex is locked because of work with global
840 * structure.
841 *
842 * @param nic_data The driver data
843 *
844 * @param[out] handle IRQ capability handle if the handler was registered.
845 *
846 * @return An error code otherwise.
847 */
848inline static errno_t rtl8139_register_int_handler(nic_t *nic_data,
849 cap_irq_handle_t *handle)
850{
851 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
852
853 /* Lock the mutex in whole driver while working with global structure */
854 RTL8139_IRQ_STRUCT_LOCK();
855
856 rtl8139_irq_code.ranges[0].base = (uintptr_t) rtl8139->io_addr;
857 rtl8139_irq_code.cmds[0].addr = rtl8139->io_addr + ISR;
858 rtl8139_irq_code.cmds[2].addr = rtl8139->io_addr + ISR;
859 rtl8139_irq_code.cmds[3].addr = rtl8139->io_addr + IMR;
860 errno_t rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
861 rtl8139->irq, rtl8139_interrupt_handler, &rtl8139_irq_code, handle);
862
863 RTL8139_IRQ_STRUCT_UNLOCK();
864
865 return rc;
866}
867
868/** Start the controller
869 *
870 * The caller must lock tx_lock and rx_lock before calling this function
871 *
872 * @param rtl8139 The card private data
873 */
874inline static void rtl8139_card_up(rtl8139_t *rtl8139)
875{
876 void *io_base = rtl8139->io_port;
877 size_t i;
878
879 /* Wake up the device */
880 pio_write_8(io_base + CONFIG1, 0x00);
881 /* Reset the device */
882 rtl8139_soft_reset(rtl8139);
883
884 /* Write transmittion buffer addresses */
885 for(i = 0; i < TX_BUFF_COUNT; ++i) {
886 uint32_t addr = PTR2U32(rtl8139->tx_buff_phys + i*TX_BUFF_SIZE);
887 pio_write_32(io_base + TSAD0 + 4*i, addr);
888 }
889 rtl8139->tx_next = 0;
890 rtl8139->tx_used = 0;
891 nic_set_tx_busy(rtl8139->nic_data, 0);
892
893 pio_write_32(io_base + RBSTART, PTR2U32(rtl8139->rx_buff_phys));
894
895 /* Enable transmitter and receiver */
896 uint8_t cr_value = pio_read_8(io_base + CR);
897 pio_write_8(io_base + CR, cr_value | CR_TE | CR_RE);
898 rtl8139_hw_update_rcr(rtl8139);
899}
900
901/** Activate the device to receive and transmit frames
902 *
903 * @param nic_data The nic driver data
904 *
905 * @return EOK if activated successfully, error code otherwise
906 */
907static errno_t rtl8139_on_activated(nic_t *nic_data)
908{
909 assert(nic_data);
910 ddf_msg(LVL_NOTE, "Activating device");
911
912 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
913 assert(rtl8139);
914
915 rtl8139_lock_all(rtl8139);
916 rtl8139_card_up(rtl8139);
917 rtl8139_unlock_all(rtl8139);
918
919 rtl8139->int_mask = RTL_DEFAULT_INTERRUPTS;
920 rtl8139_hw_int_set(rtl8139);
921
922 errno_t rc = hw_res_enable_interrupt(rtl8139->parent_sess, rtl8139->irq);
923 if (rc != EOK) {
924 rtl8139_on_stopped(nic_data);
925 return rc;
926 }
927
928 ddf_msg(LVL_DEBUG, "Device activated, interrupt %d registered", rtl8139->irq);
929 return EOK;
930}
931
932/** Callback for NIC_STATE_STOPPED change
933 *
934 * @param nic_data The nic driver data
935 *
936 * @return EOK if succeed, error code otherwise
937 */
938static errno_t rtl8139_on_stopped(nic_t *nic_data)
939{
940 assert(nic_data);
941
942 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
943 assert(rtl8139);
944
945 rtl8139->rcr_data.ucast_mask = RTL8139_RCR_UCAST_DEFAULT;
946 rtl8139->rcr_data.mcast_mask = RTL8139_RCR_MCAST_DEFAULT;
947 rtl8139->rcr_data.bcast_mask = RTL8139_RCR_BCAST_DEFAULT;
948 rtl8139->rcr_data.defect_mask = RTL8139_RCR_DEFECT_DEFAULT;
949
950 /* Reset the card to the initial state (interrupts, Tx and Rx disabled) */
951 rtl8139_lock_all(rtl8139);
952 rtl8139_soft_reset(rtl8139);
953 rtl8139_unlock_all(rtl8139);
954 return EOK;
955}
956
957
958static errno_t rtl8139_unicast_set(nic_t *nic_data, nic_unicast_mode_t mode,
959 const nic_address_t *, size_t);
960static errno_t rtl8139_multicast_set(nic_t *nic_data, nic_multicast_mode_t mode,
961 const nic_address_t *addr, size_t addr_count);
962static errno_t rtl8139_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode);
963
964
965/** Create driver data structure
966 *
967 * @return Intialized device data structure or NULL
968 */
969static rtl8139_t *rtl8139_create_dev_data(ddf_dev_t *dev)
970{
971 assert(dev);
972 assert(!nic_get_from_ddf_dev(dev));
973
974 nic_t *nic_data = nic_create_and_bind(dev);
975 if (!nic_data)
976 return NULL;
977
978 rtl8139_t *rtl8139 = calloc(1, sizeof(rtl8139_t));
979 if (!rtl8139) {
980 nic_unbind_and_destroy(dev);
981 return NULL;
982 }
983
984 rtl8139->dev = dev;
985
986 rtl8139->nic_data = nic_data;
987 nic_set_specific(nic_data, rtl8139);
988 nic_set_send_frame_handler(nic_data, rtl8139_send_frame);
989 nic_set_state_change_handlers(nic_data,
990 rtl8139_on_activated, NULL, rtl8139_on_stopped);
991 nic_set_filtering_change_handlers(nic_data,
992 rtl8139_unicast_set, rtl8139_multicast_set, rtl8139_broadcast_set,
993 NULL, NULL);
994 nic_set_wol_virtue_change_handlers(nic_data,
995 rtl8139_wol_virtue_add, rtl8139_wol_virtue_rem);
996 nic_set_poll_handlers(nic_data, rtl8139_poll_mode_change, rtl8139_poll);
997
998
999 fibril_mutex_initialize(&rtl8139->rx_lock);
1000 fibril_mutex_initialize(&rtl8139->tx_lock);
1001
1002 nic_set_wol_max_caps(nic_data, NIC_WV_BROADCAST, 1);
1003 nic_set_wol_max_caps(nic_data, NIC_WV_LINK_CHANGE, 1);
1004 nic_set_wol_max_caps(nic_data, NIC_WV_MAGIC_PACKET, 1);
1005
1006 return rtl8139;
1007}
1008
1009/** Clean up the rtl8139 device structure.
1010 *
1011 * @param dev The device structure.
1012 */
1013static void rtl8139_dev_cleanup(ddf_dev_t *dev)
1014{
1015 assert(dev);
1016
1017 if (ddf_dev_data_get(dev))
1018 nic_unbind_and_destroy(dev);
1019}
1020
1021/** Fill the irq and io_addr part of device data structure
1022 *
1023 * The hw_resources must be obtained before calling this function
1024 *
1025 * @param dev The device structure
1026 * @param hw_resources Devices hardware resources
1027 *
1028 * @return EOK if succeed, error code otherwise
1029 */
1030static errno_t rtl8139_fill_resource_info(ddf_dev_t *dev, const hw_res_list_parsed_t
1031 *hw_resources)
1032{
1033 assert(dev);
1034 assert(hw_resources);
1035
1036 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_dev(dev));
1037 assert(rtl8139);
1038
1039 if (hw_resources->irqs.count != 1) {
1040 ddf_msg(LVL_ERROR, "%s device: unexpected irq count", ddf_dev_get_name(dev));
1041 return EINVAL;
1042 }
1043 if (hw_resources->io_ranges.count != 1) {
1044 ddf_msg(LVL_ERROR, "%s device: unexpected io ranges count", ddf_dev_get_name(dev));
1045 return EINVAL;
1046 }
1047
1048 rtl8139->irq = hw_resources->irqs.irqs[0];
1049 ddf_msg(LVL_DEBUG, "%s device: irq 0x%x assigned", ddf_dev_get_name(dev), rtl8139->irq);
1050
1051 rtl8139->io_addr = IOADDR_TO_PTR(RNGABS(hw_resources->io_ranges.ranges[0]));
1052 if (hw_resources->io_ranges.ranges[0].size < RTL8139_IO_SIZE) {
1053 ddf_msg(LVL_ERROR, "i/o range assigned to the device "
1054 "%s is too small.", ddf_dev_get_name(dev));
1055 return EINVAL;
1056 }
1057 ddf_msg(LVL_DEBUG, "%s device: i/o addr %p assigned.", ddf_dev_get_name(dev), rtl8139->io_addr);
1058
1059 return EOK;
1060}
1061
1062/** Obtain information about hardware resources of the device
1063 *
1064 * The device must be connected to the parent
1065 *
1066 * @param dev The device structure
1067 *
1068 * @return EOK if succeed, error code otherwise
1069 */
1070static errno_t rtl8139_get_resource_info(ddf_dev_t *dev)
1071{
1072 assert(dev);
1073
1074 nic_t *nic_data = nic_get_from_ddf_dev(dev);
1075 assert(nic_data);
1076
1077 hw_res_list_parsed_t hw_res_parsed;
1078 hw_res_list_parsed_init(&hw_res_parsed);
1079
1080 /* Get hw resources form parent driver */
1081 errno_t rc = nic_get_resources(nic_data, &hw_res_parsed);
1082 if (rc != EOK)
1083 return rc;
1084
1085 /* Fill resources information to the device */
1086 errno_t ret = rtl8139_fill_resource_info(dev, &hw_res_parsed);
1087 hw_res_list_parsed_clean(&hw_res_parsed);
1088
1089 return ret;
1090}
1091
1092
1093/** Allocate buffers using DMA framework
1094 *
1095 * The buffers structures in the device specific data is filled
1096 *
1097 * @param data The device specific structure to fill
1098 *
1099 * @return EOK in the case of success, error code otherwise
1100 */
1101static errno_t rtl8139_buffers_create(rtl8139_t *rtl8139)
1102{
1103 size_t i = 0;
1104 errno_t rc;
1105
1106 ddf_msg(LVL_DEBUG, "Creating buffers");
1107
1108 rtl8139->tx_buff_virt = AS_AREA_ANY;
1109 rc = dmamem_map_anonymous(TX_PAGES * PAGE_SIZE, DMAMEM_4GiB,
1110 AS_AREA_WRITE, 0, &rtl8139->tx_buff_phys, &rtl8139->tx_buff_virt);
1111 if (rc != EOK) {
1112 ddf_msg(LVL_ERROR, "Can not allocate transmitter buffers.");
1113 goto err_tx_alloc;
1114 }
1115
1116 for (i = 0; i < TX_BUFF_COUNT; ++i)
1117 rtl8139->tx_buff[i] = rtl8139->tx_buff_virt + i * TX_BUFF_SIZE;
1118
1119 ddf_msg(LVL_DEBUG, "The transmittion buffers allocated");
1120
1121 /* Use the first buffer for next transmittion */
1122 rtl8139->tx_next = 0;
1123 rtl8139->tx_used = 0;
1124
1125 /* Allocate buffer for receiver */
1126 ddf_msg(LVL_DEBUG, "Allocating receiver buffer of the size %d bytes",
1127 RxBUF_TOT_LENGTH);
1128
1129 rtl8139->rx_buff_virt = AS_AREA_ANY;
1130 rc = dmamem_map_anonymous(RxBUF_TOT_LENGTH, DMAMEM_4GiB,
1131 AS_AREA_READ, 0, &rtl8139->rx_buff_phys, &rtl8139->rx_buff_virt);
1132 if (rc != EOK) {
1133 ddf_msg(LVL_ERROR, "Can not allocate receive buffer.");
1134 goto err_rx_alloc;
1135 }
1136 ddf_msg(LVL_DEBUG, "The buffers created");
1137
1138 return EOK;
1139
1140err_rx_alloc:
1141 dmamem_unmap_anonymous(&rtl8139->tx_buff_virt);
1142err_tx_alloc:
1143 return rc;
1144}
1145
1146/** Initialize the rtl8139 device structure
1147 *
1148 * @param dev The device information
1149 *
1150 * @return EOK if succeed, error code otherwise
1151 */
1152static errno_t rtl8139_device_initialize(ddf_dev_t *dev)
1153{
1154 ddf_msg(LVL_DEBUG, "rtl8139_dev_initialize %s", ddf_dev_get_name(dev));
1155
1156 errno_t ret = EOK;
1157
1158 ddf_msg(LVL_DEBUG, "rtl8139: creating device data");
1159
1160 /* Allocate driver data for the device. */
1161 rtl8139_t *rtl8139 = rtl8139_create_dev_data(dev);
1162 if (rtl8139 == NULL) {
1163 ddf_msg(LVL_ERROR, "Not enough memory for initializing %s.", ddf_dev_get_name(dev));
1164 return ENOMEM;
1165 }
1166
1167 ddf_msg(LVL_DEBUG, "rtl8139: dev_data created");
1168 rtl8139->parent_sess = ddf_dev_parent_sess_get(dev);
1169 if (rtl8139->parent_sess == NULL) {
1170 ddf_msg(LVL_ERROR, "Error connecting parent device.");
1171 return EIO;
1172 }
1173
1174 /* Obtain and fill hardware resources info and connect to parent */
1175 ret = rtl8139_get_resource_info(dev);
1176 if (ret != EOK) {
1177 ddf_msg(LVL_ERROR, "Can not obatin hw resources information");
1178 goto failed;
1179 }
1180
1181 ddf_msg(LVL_DEBUG, "rtl8139: resource_info obtained");
1182
1183 /* Allocate DMA buffers */
1184 ret = rtl8139_buffers_create(rtl8139);
1185 if (ret != EOK)
1186 goto failed;
1187
1188 /* Set default frame acceptance */
1189 rtl8139->rcr_data.ucast_mask = RTL8139_RCR_UCAST_DEFAULT;
1190 rtl8139->rcr_data.mcast_mask = RTL8139_RCR_MCAST_DEFAULT;
1191 rtl8139->rcr_data.bcast_mask = RTL8139_RCR_BCAST_DEFAULT;
1192 rtl8139->rcr_data.defect_mask = RTL8139_RCR_DEFECT_DEFAULT;
1193 /* Set receiver early treshold to 8/16 of frame length */
1194 rtl8139->rcr_data.rcr_base = (0x8 << RCR_ERTH_SHIFT);
1195
1196 ddf_msg(LVL_DEBUG, "The device is initialized");
1197 return ret;
1198
1199failed:
1200 ddf_msg(LVL_ERROR, "The device initialization failed");
1201 rtl8139_dev_cleanup(dev);
1202 return ret;
1203}
1204
1205/** Enable the i/o ports of the device.
1206 *
1207 * @param dev The RTL8139 device.
1208 *
1209 * @return EOK if successed, error code otherwise
1210 */
1211static errno_t rtl8139_pio_enable(ddf_dev_t *dev)
1212{
1213 ddf_msg(LVL_DEBUG, NAME ": rtl8139_pio_enable %s", ddf_dev_get_name(dev));
1214
1215 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_dev(dev));
1216
1217 /* Gain control over port's registers. */
1218 if (pio_enable(rtl8139->io_addr, RTL8139_IO_SIZE, &rtl8139->io_port)) {
1219 ddf_msg(LVL_ERROR, "Cannot gain the port %p for device %s.", rtl8139->io_addr,
1220 ddf_dev_get_name(dev));
1221 return EADDRNOTAVAIL;
1222 }
1223
1224 return EOK;
1225}
1226
1227/** Initialize the driver private data according to the
1228 * device registers
1229 *
1230 * @param rtl8139 rtl8139 private data
1231 */
1232static void rtl8139_data_init(rtl8139_t *rtl8139)
1233{
1234 assert(rtl8139);
1235
1236 /* Check the version id */
1237 uint32_t tcr = pio_read_32(rtl8139->io_port + TCR);
1238 uint32_t hwverid = RTL8139_HWVERID(tcr);
1239 size_t i = 0;
1240 rtl8139->hw_version = RTL8139_VER_COUNT;
1241 for (i = 0; i < RTL8139_VER_COUNT; ++i) {
1242 if (rtl8139_versions[i].hwverid == 0)
1243 break;
1244
1245 if (rtl8139_versions[i].hwverid == hwverid) {
1246 rtl8139->hw_version = rtl8139_versions[i].ver_id;
1247 ddf_msg(LVL_NOTE, "HW version found: index %zu, ver_id %d (%s)", i,
1248 rtl8139_versions[i].ver_id, model_names[rtl8139->hw_version]);
1249 }
1250 }
1251}
1252
1253/** The add_device callback of RTL8139 callback
1254 *
1255 * Probe and initialize the newly added device.
1256 *
1257 * @param dev The RTL8139 device.
1258 *
1259 * @return EOK if added successfully, error code otherwise
1260 */
1261errno_t rtl8139_dev_add(ddf_dev_t *dev)
1262{
1263 ddf_fun_t *fun;
1264
1265 ddf_msg(LVL_NOTE, "RTL8139_dev_add %s (handle = %zu)",
1266 ddf_dev_get_name(dev), ddf_dev_get_handle(dev));
1267
1268 /* Init device structure for rtl8139 */
1269 errno_t rc = rtl8139_device_initialize(dev);
1270 if (rc != EOK)
1271 return rc;
1272
1273 /* Map I/O ports */
1274 rc = rtl8139_pio_enable(dev);
1275 if (rc != EOK)
1276 goto err_destroy;
1277
1278 nic_t *nic_data = nic_get_from_ddf_dev(dev);
1279 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1280
1281 nic_address_t addr;
1282 rtl8139_hw_get_addr(rtl8139, &addr);
1283 rc = nic_report_address(nic_data, &addr);
1284 if (rc != EOK)
1285 goto err_pio;
1286
1287 /* Initialize the driver private structure */
1288 rtl8139_data_init(rtl8139);
1289
1290 /* Register interrupt handler */
1291 cap_irq_handle_t irq_handle;
1292 rc = rtl8139_register_int_handler(nic_data, &irq_handle);
1293 if (rc != EOK) {
1294 goto err_pio;
1295 }
1296
1297 fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
1298 if (fun == NULL) {
1299 ddf_msg(LVL_ERROR, "Failed creating device function");
1300 goto err_srv;
1301 }
1302
1303 nic_set_ddf_fun(nic_data, fun);
1304 ddf_fun_set_ops(fun, &rtl8139_dev_ops);
1305
1306 rc = ddf_fun_bind(fun);
1307 if (rc != EOK) {
1308 ddf_msg(LVL_ERROR, "Failed binding device function");
1309 goto err_fun_create;
1310 }
1311 rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
1312 if (rc != EOK) {
1313 ddf_msg(LVL_ERROR, "Failed adding function to category");
1314 goto err_fun_bind;
1315 }
1316
1317 ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.",
1318 ddf_dev_get_name(dev));
1319
1320 return EOK;
1321
1322err_fun_bind:
1323 ddf_fun_unbind(fun);
1324err_fun_create:
1325 ddf_fun_destroy(fun);
1326err_srv:
1327 unregister_interrupt_handler(dev, irq_handle);
1328err_pio:
1329 // rtl8139_pio_disable(dev);
1330 /* TODO: find out if the pio_disable is needed */
1331err_destroy:
1332 rtl8139_dev_cleanup(dev);
1333 return rc;
1334}
1335
1336/** Set card MAC address
1337 *
1338 * @param device The RTL8139 device
1339 * @param address The place to store the address
1340 * @param max_len Maximal addresss length to store
1341 *
1342 * @return EOK if succeed, error code otherwise
1343 */
1344static errno_t rtl8139_set_addr(ddf_fun_t *fun, const nic_address_t *addr)
1345{
1346 assert(fun);
1347 assert(addr);
1348
1349 nic_t *nic_data =nic_get_from_ddf_fun((fun));
1350 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1351 assert(rtl8139);
1352
1353 rtl8139_lock_all(rtl8139);
1354
1355 errno_t rc = nic_report_address(nic_data, addr);
1356 if ( rc != EOK) {
1357 rtl8139_unlock_all(rtl8139);
1358 return rc;
1359 }
1360
1361 rtl8139_hw_set_addr(rtl8139, addr);
1362
1363 rtl8139_unlock_all(rtl8139);
1364 return EOK;
1365}
1366
1367/** Get the device information
1368 *
1369 * @param dev The NIC device
1370 * @param info The information to fill
1371 *
1372 * @return EOK
1373 */
1374static errno_t rtl8139_get_device_info(ddf_fun_t *fun, nic_device_info_t *info)
1375{
1376 assert(fun);
1377 assert(info);
1378
1379 nic_t *nic_data = nic_get_from_ddf_fun(fun);
1380 assert(nic_data);
1381 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1382 assert(rtl8139);
1383
1384 /* TODO: fill the information more completely */
1385 info->vendor_id = 0x10ec;
1386 str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Realtek");
1387
1388 if (rtl8139->hw_version < RTL8139_VER_COUNT) {
1389 str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH,
1390 model_names[rtl8139->hw_version]);
1391 } else {
1392 str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8139");
1393 }
1394
1395 info->ethernet_support[ETH_10M] = ETH_10BASE_T;
1396 info->ethernet_support[ETH_100M] = ETH_100BASE_TX;
1397
1398 info->autoneg_support = RTL8139_AUTONEG_CAPS;
1399 return EOK;
1400}
1401
1402/** Check the cable state
1403 *
1404 * @param[in] dev The device
1405 * @param[out] state The state to fill
1406 *
1407 * @return EOK
1408 */
1409static errno_t rtl8139_get_cable_state(ddf_fun_t *fun, nic_cable_state_t *state)
1410{
1411 assert(fun);
1412 assert(state);
1413
1414 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1415 assert(rtl8139);
1416
1417 if (pio_read_16(rtl8139->io_port + CSCR) & CS_CON_STATUS) {
1418 *state = NIC_CS_PLUGGED;
1419 } else {
1420 *state = NIC_CS_UNPLUGGED;
1421 }
1422
1423 return EOK;
1424}
1425
1426/** Get operation mode of the device
1427 */
1428static errno_t rtl8139_get_operation_mode(ddf_fun_t *fun, int *speed,
1429 nic_channel_mode_t *duplex, nic_role_t *role)
1430{
1431 assert(fun);
1432 assert(speed);
1433 assert(duplex);
1434 assert(role);
1435
1436 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1437 assert(rtl8139);
1438
1439 uint16_t bmcr_val = pio_read_16(rtl8139->io_port + BMCR);
1440 uint8_t msr_val = pio_read_8(rtl8139->io_port + MSR);
1441
1442 if (bmcr_val & BMCR_DUPLEX) {
1443 *duplex = NIC_CM_FULL_DUPLEX;
1444 } else {
1445 *duplex = NIC_CM_HALF_DUPLEX;
1446 }
1447
1448 if (msr_val & MSR_SPEED10) {
1449 *speed = 10;
1450 } else {
1451 *speed = 100;
1452 }
1453
1454 *role = NIC_ROLE_UNKNOWN;
1455 return EOK;
1456}
1457
1458/** Value validity */
1459enum access_mode {
1460 /** Value is invalid now */
1461 VALUE_INVALID = 0,
1462 /** Read-only */
1463 VALUE_RO,
1464 /** Read-write */
1465 VALUE_RW
1466};
1467
1468/** Check if pause frame operations are valid in current situation
1469 *
1470 * @param rtl8139 RTL8139 private structure
1471 *
1472 * @return VALUE_INVALID if the value has no sense in current moment
1473 * @return VALUE_RO if the state is read-only in current moment
1474 * @return VALUE_RW if the state can be modified
1475 */
1476static int rtl8139_pause_is_valid(rtl8139_t *rtl8139)
1477{
1478 assert(rtl8139);
1479
1480 uint16_t bmcr = pio_read_16(rtl8139->io_port + BMCR);
1481 if ((bmcr & (BMCR_AN_ENABLE | BMCR_DUPLEX)) == 0)
1482 return VALUE_INVALID;
1483
1484 if (bmcr & BMCR_AN_ENABLE) {
1485 uint16_t anar_lp = pio_read_16(rtl8139->io_port + ANLPAR);
1486 if (anar_lp & ANAR_PAUSE)
1487 return VALUE_RO;
1488 }
1489
1490 return VALUE_RW;
1491}
1492
1493/** Get current pause frame configuration
1494 *
1495 * Values are filled with NIC_RESULT_NOT_AVAILABLE if the value has no sense in
1496 * the moment (half-duplex).
1497 *
1498 * @param[in] fun The DDF structure of the RTL8139
1499 * @param[out] we_send Sign if local constroller sends pause frame
1500 * @param[out] we_receive Sign if local constroller receives pause frame
1501 * @param[out] time Time filled in pause frames. 0xFFFF in rtl8139
1502 *
1503 * @return EOK if succeed
1504 */
1505static errno_t rtl8139_pause_get(ddf_fun_t *fun, nic_result_t *we_send,
1506 nic_result_t *we_receive, uint16_t *time)
1507{
1508 assert(fun);
1509 assert(we_send);
1510 assert(we_receive);
1511
1512 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1513 assert(rtl8139);
1514
1515 if (rtl8139_pause_is_valid(rtl8139) == VALUE_INVALID) {
1516 *we_send = NIC_RESULT_NOT_AVAILABLE;
1517 *we_receive = NIC_RESULT_NOT_AVAILABLE;
1518 *time = 0;
1519 return EOK;
1520 }
1521
1522 uint8_t msr = pio_read_8(rtl8139->io_port + MSR);
1523
1524 *we_send = (msr & MSR_TXFCE) ? NIC_RESULT_ENABLED : NIC_RESULT_DISABLED;
1525 *we_receive = (msr & MSR_RXFCE) ? NIC_RESULT_ENABLED : NIC_RESULT_DISABLED;
1526 *time = RTL8139_PAUSE_VAL;
1527
1528 return EOK;
1529}
1530
1531/** Set current pause frame configuration
1532 *
1533 * @param fun The DDF structure of the RTL8139
1534 * @param allow_send Sign if local constroller sends pause frame
1535 * @param allow_receive Sign if local constroller receives pause frames
1536 * @param time Time to use, ignored (not supported by device)
1537 *
1538 * @return EOK if succeed, INVAL if the pause frame has no sence
1539 */
1540static errno_t rtl8139_pause_set(ddf_fun_t *fun, int allow_send, int allow_receive,
1541 uint16_t time)
1542{
1543 assert(fun);
1544
1545 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1546 assert(rtl8139);
1547
1548 if (rtl8139_pause_is_valid(rtl8139) != VALUE_RW)
1549 return EINVAL;
1550
1551 uint8_t msr = pio_read_8(rtl8139->io_port + MSR);
1552 msr &= ~(uint8_t)(MSR_TXFCE | MSR_RXFCE);
1553
1554 if (allow_receive)
1555 msr |= MSR_RXFCE;
1556 if (allow_send)
1557 msr |= MSR_TXFCE;
1558
1559 pio_write_8(rtl8139->io_port + MSR, msr);
1560
1561 if (allow_send && time > 0) {
1562 ddf_msg(LVL_WARN, "Time setting is not supported in set_pause method.");
1563 }
1564 return EOK;
1565}
1566
1567/** Set operation mode of the device
1568 *
1569 */
1570static errno_t rtl8139_set_operation_mode(ddf_fun_t *fun, int speed,
1571 nic_channel_mode_t duplex, nic_role_t role)
1572{
1573 assert(fun);
1574
1575 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1576 assert(rtl8139);
1577
1578 if (speed != 10 && speed != 100)
1579 return EINVAL;
1580 if (duplex != NIC_CM_HALF_DUPLEX && duplex != NIC_CM_FULL_DUPLEX)
1581 return EINVAL;
1582
1583 uint16_t bmcr_val = pio_read_16(rtl8139->io_port + BMCR);
1584
1585 /* Set autonegotion disabled */
1586 bmcr_val &= ~(uint16_t)BMCR_AN_ENABLE;
1587
1588 if (duplex == NIC_CM_FULL_DUPLEX) {
1589 bmcr_val |= BMCR_DUPLEX;
1590 } else {
1591 bmcr_val &= ~((uint16_t)BMCR_DUPLEX);
1592 }
1593
1594 if (speed == 100) {
1595 bmcr_val |= BMCR_Spd_100;
1596 } else {
1597 bmcr_val &= ~((uint16_t)BMCR_Spd_100);
1598 }
1599
1600 rtl8139_regs_unlock(rtl8139->io_port);
1601 pio_write_16(rtl8139->io_port + BMCR, bmcr_val);
1602 rtl8139_regs_lock(rtl8139->io_port);
1603 return EOK;
1604}
1605
1606/** Enable autonegoation with specific advertisement
1607 *
1608 * @param dev The device to update
1609 * @param advertisement The advertisement to set
1610 *
1611 * @returns EINVAL if the advertisement mode is not supproted
1612 * @returns EOK if advertisement mode set successfully
1613 */
1614static errno_t rtl8139_autoneg_enable(ddf_fun_t *fun, uint32_t advertisement)
1615{
1616 assert(fun);
1617
1618 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1619 assert(rtl8139);
1620
1621 if (advertisement == 0) {
1622 advertisement = RTL8139_AUTONEG_CAPS;
1623 }
1624
1625 if ((advertisement | RTL8139_AUTONEG_CAPS) != RTL8139_AUTONEG_CAPS)
1626 return EINVAL; /* some unsuported mode is requested */
1627
1628 assert(advertisement != 0);
1629
1630 /* Set the autonegotiation advertisement */
1631 uint16_t anar = ANAR_SELECTOR; /* default selector */
1632 if (advertisement & ETH_AUTONEG_10BASE_T_FULL)
1633 anar |= ANAR_10_FD;
1634 if (advertisement & ETH_AUTONEG_10BASE_T_HALF)
1635 anar |= ANAR_10_HD;
1636 if (advertisement & ETH_AUTONEG_100BASE_TX_FULL)
1637 anar |= ANAR_100TX_FD;
1638 if (advertisement & ETH_AUTONEG_100BASE_TX_HALF)
1639 anar |= ANAR_100TX_HD;
1640 if (advertisement & ETH_AUTONEG_PAUSE_SYMETRIC)
1641 anar |= ANAR_PAUSE;
1642
1643 uint16_t bmcr_val = pio_read_16(rtl8139->io_port + BMCR);
1644 bmcr_val |= BMCR_AN_ENABLE;
1645
1646 pio_write_16(rtl8139->io_port + ANAR, anar);
1647
1648 rtl8139_regs_unlock(rtl8139->io_port);
1649 pio_write_16(rtl8139->io_port + BMCR, bmcr_val);
1650 rtl8139_regs_lock(rtl8139->io_port);
1651 return EOK;
1652}
1653
1654/** Disable advertisement functionality
1655 *
1656 * @param dev The device to update
1657 *
1658 * @returns EOK
1659 */
1660static errno_t rtl8139_autoneg_disable(ddf_fun_t *fun)
1661{
1662 assert(fun);
1663
1664 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1665 assert(rtl8139);
1666
1667 uint16_t bmcr_val = pio_read_16(rtl8139->io_port + BMCR);
1668
1669 bmcr_val &= ~((uint16_t)BMCR_AN_ENABLE);
1670
1671 rtl8139_regs_unlock(rtl8139->io_port);
1672 pio_write_16(rtl8139->io_port + BMCR, bmcr_val);
1673 rtl8139_regs_lock(rtl8139->io_port);
1674
1675 return EOK;
1676}
1677
1678/** Obtain the advertisement NIC framework value from the ANAR/ANLPAR register
1679 * value
1680 *
1681 * @param[in] anar The ANAR register value
1682 * @param[out] advertisement The advertisement result
1683 */
1684static void rtl8139_get_anar_state(uint16_t anar, uint32_t *advertisement)
1685{
1686 *advertisement = 0;
1687 if (anar & ANAR_10_HD)
1688 *advertisement |= ETH_AUTONEG_10BASE_T_HALF;
1689 if (anar & ANAR_10_FD)
1690 *advertisement |= ETH_AUTONEG_10BASE_T_FULL;
1691 if (anar & ANAR_100TX_HD)
1692 *advertisement |= ETH_AUTONEG_100BASE_TX_HALF;
1693 if (anar & ANAR_100TX_FD)
1694 *advertisement |= ETH_AUTONEG_100BASE_TX_FULL;
1695 if (anar & ANAR_100T4)
1696 *advertisement |= ETH_AUTONEG_100BASE_T4_HALF;
1697 if (anar & ANAR_PAUSE)
1698 *advertisement |= ETH_AUTONEG_PAUSE_SYMETRIC;
1699}
1700
1701/** Check the autonegotion state
1702 *
1703 * @param[in] dev The device to check
1704 * @param[out] advertisement The device advertisement
1705 * @param[out] their_adv The partners advertisement
1706 * @param[out] result The autonegotion state
1707 * @param[out] their_result The link partner autonegotion status
1708 *
1709 * @returns EOK
1710 */
1711static errno_t rtl8139_autoneg_probe(ddf_fun_t *fun, uint32_t *advertisement,
1712 uint32_t *their_adv, nic_result_t *result, nic_result_t *their_result)
1713{
1714 assert(fun);
1715
1716 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1717 assert(rtl8139);
1718
1719 uint16_t bmcr = pio_read_16(rtl8139->io_port + BMCR);
1720 uint16_t anar = pio_read_16(rtl8139->io_port + ANAR);
1721 uint16_t anar_lp = pio_read_16(rtl8139->io_port + ANLPAR);
1722 uint16_t aner = pio_read_16(rtl8139->io_port + ANER);
1723
1724 if (bmcr & BMCR_AN_ENABLE) {
1725 *result = NIC_RESULT_ENABLED;
1726 } else {
1727 *result = NIC_RESULT_DISABLED;
1728 }
1729
1730 if (aner & ANER_LP_NW_ABLE) {
1731 *their_result = NIC_RESULT_ENABLED;
1732 } else {
1733 *their_result = NIC_RESULT_DISABLED;
1734 }
1735
1736 rtl8139_get_anar_state(anar, advertisement);
1737 rtl8139_get_anar_state(anar_lp, their_adv);
1738
1739 return EOK;
1740}
1741
1742/** Restart autonegotiation process
1743 *
1744 * @param dev The device to update
1745 *
1746 * @returns EOK
1747 */
1748static errno_t rtl8139_autoneg_restart(ddf_fun_t *fun)
1749{
1750 assert(fun);
1751
1752 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1753 assert(rtl8139);
1754
1755 uint16_t bmcr = pio_read_16(rtl8139->io_port + BMCR);
1756 bmcr |= BMCR_AN_RESTART;
1757 bmcr |= BMCR_AN_ENABLE;
1758
1759 rtl8139_regs_unlock(rtl8139);
1760 pio_write_16(rtl8139->io_port + BMCR, bmcr);
1761 rtl8139_regs_lock(rtl8139);
1762
1763 return EOK;
1764}
1765
1766/** Notify NIC framework about HW filtering state when promisc mode was disabled
1767 *
1768 * @param nic_data The NIC data
1769 * @param mcast_mode Current multicast mode
1770 * @param was_promisc Sign if the promiscuous mode was active before disabling
1771 */
1772inline static void rtl8139_rcx_promics_rem(nic_t *nic_data,
1773 nic_multicast_mode_t mcast_mode, uint8_t was_promisc)
1774{
1775 assert(nic_data);
1776
1777 if (was_promisc != 0) {
1778 if (mcast_mode == NIC_MULTICAST_LIST)
1779 nic_report_hw_filtering(nic_data, 1, 0, -1);
1780 else
1781 nic_report_hw_filtering(nic_data, 1, 1, -1);
1782 } else {
1783 nic_report_hw_filtering(nic_data, 1, -1, -1);
1784 }
1785}
1786
1787/** Set unicast frames acceptance mode
1788 *
1789 * @param nic_data The nic device to update
1790 * @param mode The mode to set
1791 * @param addr Ignored, no HW support, just use unicast promisc
1792 * @param addr_cnt Ignored, no HW support
1793 *
1794 * @returns EOK
1795 */
1796static errno_t rtl8139_unicast_set(nic_t *nic_data, nic_unicast_mode_t mode,
1797 const nic_address_t *addr, size_t addr_cnt)
1798{
1799 assert(nic_data);
1800
1801 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1802 assert(rtl8139);
1803
1804 uint8_t was_promisc = rtl8139->rcr_data.ucast_mask & RCR_ACCEPT_ALL_PHYS;
1805
1806 nic_multicast_mode_t mcast_mode;
1807 nic_query_multicast(nic_data, &mcast_mode, 0, NULL, NULL);
1808
1809 switch (mode) {
1810 case NIC_UNICAST_BLOCKED:
1811 rtl8139->rcr_data.ucast_mask = 0;
1812 rtl8139_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
1813 break;
1814 case NIC_UNICAST_DEFAULT:
1815 rtl8139->rcr_data.ucast_mask = RCR_ACCEPT_PHYS_MATCH;
1816 rtl8139_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
1817 break;
1818 case NIC_UNICAST_LIST:
1819 rtl8139->rcr_data.ucast_mask = RCR_ACCEPT_PHYS_MATCH
1820 | RCR_ACCEPT_ALL_PHYS;
1821
1822 if (mcast_mode == NIC_MULTICAST_PROMISC)
1823 nic_report_hw_filtering(nic_data, 0, 1, -1);
1824 else
1825 nic_report_hw_filtering(nic_data, 0, 0, -1);
1826 break;
1827 case NIC_UNICAST_PROMISC:
1828 rtl8139->rcr_data.ucast_mask = RCR_ACCEPT_PHYS_MATCH
1829 | RCR_ACCEPT_ALL_PHYS;
1830
1831 if (mcast_mode == NIC_MULTICAST_PROMISC)
1832 nic_report_hw_filtering(nic_data, 1, 1, -1);
1833 else
1834 nic_report_hw_filtering(nic_data, 1, 0, -1);
1835 break;
1836 default:
1837 return ENOTSUP;
1838 }
1839 fibril_mutex_lock(&rtl8139->rx_lock);
1840 rtl8139_hw_update_rcr(rtl8139);
1841 fibril_mutex_unlock(&rtl8139->rx_lock);
1842 return EOK;
1843}
1844
1845/** Set multicast frames acceptance mode
1846 *
1847 * @param nic_data The nic device to update
1848 * @param mode The mode to set
1849 * @param addr Addresses to accept
1850 * @param addr_cnt Addresses count
1851 *
1852 * @returns EOK
1853 */
1854static errno_t rtl8139_multicast_set(nic_t *nic_data, nic_multicast_mode_t mode,
1855 const nic_address_t *addr, size_t addr_count)
1856{
1857 assert(nic_data);
1858 assert(addr_count == 0 || addr);
1859
1860 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1861 assert(rtl8139);
1862
1863 switch (mode) {
1864 case NIC_MULTICAST_BLOCKED:
1865 rtl8139->rcr_data.mcast_mask = 0;
1866 if ((rtl8139->rcr_data.ucast_mask & RCR_ACCEPT_ALL_PHYS) != 0)
1867 nic_report_hw_filtering(nic_data, -1, 0, -1);
1868 else
1869 nic_report_hw_filtering(nic_data, -1, 1, -1);
1870 break;
1871 case NIC_MULTICAST_LIST:
1872 rtl8139_hw_set_mcast_mask(rtl8139, nic_mcast_hash(addr, addr_count));
1873 rtl8139->rcr_data.mcast_mask = RCR_ACCEPT_MULTICAST;
1874 nic_report_hw_filtering(nic_data, -1, 0, -1);
1875 break;
1876 case NIC_MULTICAST_PROMISC:
1877 rtl8139_hw_set_mcast_mask(rtl8139, RTL8139_MCAST_MASK_PROMISC);
1878 rtl8139->rcr_data.mcast_mask = RCR_ACCEPT_MULTICAST;
1879 nic_report_hw_filtering(nic_data, -1, 1, -1);
1880 break;
1881 default:
1882 return ENOTSUP;
1883 }
1884 fibril_mutex_lock(&rtl8139->rx_lock);
1885 rtl8139_hw_update_rcr(rtl8139);
1886 fibril_mutex_unlock(&rtl8139->rx_lock);
1887 return EOK;
1888}
1889
1890/** Set broadcast frames acceptance mode
1891 *
1892 * @param nic_data The nic device to update
1893 * @param mode The mode to set
1894 *
1895 * @returns EOK
1896 */
1897static errno_t rtl8139_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode)
1898{
1899 assert(nic_data);
1900
1901 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1902 assert(rtl8139);
1903
1904 switch (mode) {
1905 case NIC_BROADCAST_BLOCKED:
1906 rtl8139->rcr_data.bcast_mask = 0;
1907 break;
1908 case NIC_BROADCAST_ACCEPTED:
1909 rtl8139->rcr_data.bcast_mask = RCR_ACCEPT_BROADCAST;
1910 break;
1911 default:
1912 return ENOTSUP;
1913 }
1914 fibril_mutex_lock(&rtl8139->rx_lock);
1915 rtl8139_hw_update_rcr(rtl8139);
1916 fibril_mutex_unlock(&rtl8139->rx_lock);
1917 return EOK;
1918}
1919
1920/** Get state of acceptance of weird frames
1921 *
1922 * @param[in] device The device to check
1923 * @param[out] mode The current mode
1924 */
1925static errno_t rtl8139_defective_get_mode(ddf_fun_t *fun, uint32_t *mode)
1926{
1927 assert(fun);
1928 assert(mode);
1929
1930 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1931 assert(rtl8139);
1932
1933 *mode = 0;
1934 if (rtl8139->rcr_data.defect_mask & RCR_ACCEPT_ERROR)
1935 *mode |= NIC_DEFECTIVE_BAD_CRC;
1936 if (rtl8139->rcr_data.defect_mask & RCR_ACCEPT_RUNT)
1937 *mode |= NIC_DEFECTIVE_SHORT;
1938
1939 return EOK;
1940}
1941
1942/** Set acceptance of weird frames
1943 *
1944 * @param device The device to update
1945 * @param mode The mode to set
1946 *
1947 * @returns ENOTSUP if the mode is not supported
1948 * @returns EOK of mode was set
1949 */
1950static errno_t rtl8139_defective_set_mode(ddf_fun_t *fun, uint32_t mode)
1951{
1952 assert(fun);
1953
1954 rtl8139_t *rtl8139 = nic_get_specific(nic_get_from_ddf_fun(fun));
1955 assert(rtl8139);
1956
1957 if ((mode & (NIC_DEFECTIVE_SHORT | NIC_DEFECTIVE_BAD_CRC)) != mode)
1958 return ENOTSUP;
1959
1960 rtl8139->rcr_data.defect_mask = 0;
1961 if (mode & NIC_DEFECTIVE_SHORT)
1962 rtl8139->rcr_data.defect_mask |= RCR_ACCEPT_RUNT;
1963 if (mode & NIC_DEFECTIVE_BAD_CRC)
1964 rtl8139->rcr_data.defect_mask |= RCR_ACCEPT_ERROR;
1965
1966 fibril_mutex_lock(&rtl8139->rx_lock);
1967 rtl8139_hw_update_rcr(rtl8139);
1968 fibril_mutex_unlock(&rtl8139->rx_lock);
1969 return EOK;
1970}
1971
1972
1973/** Turn Wakeup On Lan method on
1974 *
1975 * @param nic_data The NIC to update
1976 * @param virtue The method to turn on
1977 *
1978 * @returns EINVAL if the method is not supported
1979 * @returns EOK if succeed
1980 * @returns ELIMIT if no more methods of this kind can be enabled
1981 */
1982static errno_t rtl8139_wol_virtue_add(nic_t *nic_data,
1983 const nic_wol_virtue_t *virtue)
1984{
1985 assert(nic_data);
1986 assert(virtue);
1987
1988 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
1989 assert(rtl8139);
1990
1991 switch(virtue->type) {
1992 case NIC_WV_BROADCAST:
1993 rtl8139_hw_reg_add_8(rtl8139, CONFIG5, CONFIG5_BROADCAST_WAKEUP);
1994 break;
1995 case NIC_WV_LINK_CHANGE:
1996 rtl8139_regs_unlock(rtl8139->io_port);
1997 rtl8139_hw_reg_add_8(rtl8139, CONFIG3, CONFIG3_LINK_UP);
1998 rtl8139_regs_lock(rtl8139->io_port);
1999 break;
2000 case NIC_WV_MAGIC_PACKET:
2001 if (virtue->data)
2002 return EINVAL;
2003 rtl8139_regs_unlock(rtl8139->io_port);
2004 rtl8139_hw_reg_add_8(rtl8139, CONFIG3, CONFIG3_MAGIC);
2005 rtl8139_regs_lock(rtl8139->io_port);
2006 break;
2007 default:
2008 return EINVAL;
2009 }
2010 if(rtl8139->pm.active++ == 0)
2011 rtl8139_hw_pmen_set(rtl8139, 1);
2012 return EOK;
2013}
2014
2015/** Turn Wakeup On Lan method off
2016 *
2017 * @param nic_data The NIC to update
2018 * @param virtue The method to turn off
2019 */
2020static void rtl8139_wol_virtue_rem(nic_t *nic_data,
2021 const nic_wol_virtue_t *virtue)
2022{
2023 assert(nic_data);
2024 assert(virtue);
2025
2026 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
2027 assert(rtl8139);
2028
2029 switch(virtue->type) {
2030 case NIC_WV_BROADCAST:
2031 rtl8139_hw_reg_rem_8(rtl8139, CONFIG5, CONFIG5_BROADCAST_WAKEUP);
2032 break;
2033 case NIC_WV_LINK_CHANGE:
2034 rtl8139_regs_unlock(rtl8139->io_port);
2035 rtl8139_hw_reg_rem_8(rtl8139, CONFIG3, CONFIG3_LINK_UP);
2036 rtl8139_regs_lock(rtl8139->io_port);
2037 break;
2038 case NIC_WV_MAGIC_PACKET:
2039 rtl8139_regs_unlock(rtl8139->io_port);
2040 rtl8139_hw_reg_rem_8(rtl8139, CONFIG3, CONFIG3_MAGIC);
2041 rtl8139_regs_lock(rtl8139->io_port);
2042 break;
2043 default:
2044 return;
2045 }
2046 rtl8139->pm.active--;
2047 if (rtl8139->pm.active == 0)
2048 rtl8139_hw_pmen_set(rtl8139, 0);
2049}
2050
2051
2052/** Set polling mode
2053 *
2054 * @param device The device to set
2055 * @param mode The mode to set
2056 * @param period The period for NIC_POLL_PERIODIC
2057 *
2058 * @returns EOK if succeed
2059 * @returns ENOTSUP if the mode is not supported
2060 */
2061static errno_t rtl8139_poll_mode_change(nic_t *nic_data, nic_poll_mode_t mode,
2062 const struct timeval *period)
2063{
2064 assert(nic_data);
2065 errno_t rc = EOK;
2066
2067 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
2068 assert(rtl8139);
2069
2070 fibril_mutex_lock(&rtl8139->rx_lock);
2071
2072 switch(mode) {
2073 case NIC_POLL_IMMEDIATE:
2074 rtl8139->int_mask = RTL_DEFAULT_INTERRUPTS;
2075 break;
2076 case NIC_POLL_ON_DEMAND:
2077 rtl8139->int_mask = 0;
2078 break;
2079 case NIC_POLL_PERIODIC:
2080 assert(period);
2081
2082 rtl8139_timer_act_t new_timer;
2083 rc = rtl8139_timer_act_init(&new_timer, RTL8139_PCI_FREQ_KHZ, period);
2084 if (rc != EOK)
2085 break;
2086
2087 /* Disable timer interrupts while working with timer-related data */
2088 rtl8139->int_mask = 0;
2089 rtl8139_hw_int_set(rtl8139);
2090
2091 rtl8139->poll_timer = new_timer;
2092 rtl8139->int_mask = INT_TIME_OUT;
2093
2094 /* Force timer interrupt start be writing nonzero value to timer
2095 * interrutp register (should be small to prevent big delay)
2096 * Read TCTR to reset timer counter
2097 * Change values to simulate the last interrupt from the period.
2098 */
2099 pio_write_32(rtl8139->io_port + TIMERINT, 10);
2100 pio_write_32(rtl8139->io_port + TCTR, 0);
2101
2102 ddf_msg(LVL_DEBUG, "Periodic mode. Interrupt mask %" PRIx16 ", "
2103 "poll.full_skips %zu, last timer %" PRIu32,
2104 rtl8139->int_mask, rtl8139->poll_timer.full_skips,
2105 rtl8139->poll_timer.last_val);
2106 break;
2107 default:
2108 rc = ENOTSUP;
2109 break;
2110 }
2111
2112 rtl8139_hw_int_set(rtl8139);
2113
2114 fibril_mutex_unlock(&rtl8139->rx_lock);
2115
2116 return rc;
2117}
2118
2119/** Force receiving all frames in the receive buffer
2120 *
2121 * @param device The device to receive
2122 */
2123static void rtl8139_poll(nic_t *nic_data)
2124{
2125 assert(nic_data);
2126
2127 rtl8139_t *rtl8139 = nic_get_specific(nic_data);
2128 assert(rtl8139);
2129
2130 uint16_t isr = pio_read_16(rtl8139->io_port + ISR);
2131 pio_write_16(rtl8139->io_port + ISR, 0);
2132
2133 rtl8139_interrupt_impl(nic_data, isr);
2134}
2135
2136
2137/** Main function of RTL8139 driver
2138 *
2139 * Just initialize the driver structures and
2140 * put it into the device drivers interface
2141 */
2142int main(void)
2143{
2144 printf("%s: HelenOS RTL8139 network adapter driver\n", NAME);
2145
2146 errno_t rc = nic_driver_init(NAME);
2147 if (rc != EOK)
2148 return rc;
2149
2150 nic_driver_implement(&rtl8139_driver_ops, &rtl8139_dev_ops,
2151 &rtl8139_nic_iface);
2152
2153 ddf_log_init(NAME);
2154 return ddf_driver_main(&rtl8139_driver);
2155}
Note: See TracBrowser for help on using the repository browser.