1 #include <minix/drivers.h>
2 #include <minix/netdriver.h>
3 #include <net/gen/ether.h>
4 #include <net/gen/eth_io.h>
5 #include <minix/sysutil.h>
6 #include <minix/board.h>
9 #include "lan8710a_reg.h"
12 static void lan8710a_readv_s(message
*m
, int from_int
);
13 static void lan8710a_writev_s(message
*m
, int from_int
);
14 static void lan8710a_conf(message
*m
);
15 static void lan8710a_getstat(message
*m
);
17 static void lan8710a_init(void);
18 static void lan8710a_enable_interrupt(int interrupt
);
19 static void lan8710a_interrupt(message
*m
);
20 static void lan8710a_map_regs(void);
21 static void lan8710a_stop(void);
22 static void lan8710a_dma_config_tx(u8_t desc_idx
);
23 static void lan8710a_dma_reset_init(void);
24 static void lan8710a_init_addr(void);
25 static void lan8710a_init_desc(void);
26 static void lan8710a_init_mdio(void);
27 static int lan8710a_init_hw(void);
28 static void lan8710a_reset_hw();
30 static void lan8710a_phy_write(u32_t reg
, u32_t value
);
31 static u32_t
lan8710a_phy_read(u32_t reg
);
33 static u32_t
lan8710a_reg_read(volatile u32_t
*reg
);
34 static void lan8710a_reg_write(volatile u32_t
*reg
, u32_t value
);
35 static void lan8710a_reg_set(volatile u32_t
*reg
, u32_t value
);
36 static void lan8710a_reg_unset(volatile u32_t
*reg
, u32_t value
);
38 static void mess_reply(message
*req
, message
*reply
);
39 static void reply(lan8710a_t
*e
);
42 static lan8710a_t lan8710a_state
;
44 /* SEF functions and variables. */
45 static void sef_local_startup(void);
46 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
47 static void sef_cb_signal_handler(int signal
);
49 /*============================================================================*
51 *============================================================================*/
53 main(int argc
, char *argv
[])
60 struct machine machine
;
62 sys_getmachine(&machine
);
63 if ( BOARD_IS_BB(machine
.board_id
)) {
65 /* SEF local startup */
66 env_setargs(argc
, argv
);
69 /* Main driver loop */
71 r
= netdriver_receive(ANY
, &m
, &ipc_status
);
73 panic("netdriver_receive failed: %d", r
);
76 if (is_ipc_notify(ipc_status
)) {
77 switch (_ENDPOINT_P(m
.m_source
)) {
79 lan8710a_interrupt(&m
);
85 lan8710a_writev_s(&m
, FALSE
);
88 lan8710a_readv_s(&m
, FALSE
);
97 panic("Illegal message: %d", m
.m_type
);
105 /*============================================================================*
106 * sef_local_startup *
107 *============================================================================*/
111 /* Register init callbacks. */
112 sef_setcb_init_fresh(sef_cb_init_fresh
);
113 sef_setcb_init_lu(sef_cb_init_fresh
);
114 sef_setcb_init_restart(sef_cb_init_fresh
);
116 /* Register live update callbacks. */
117 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
118 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree
);
120 /* Register signal callbacks. */
121 sef_setcb_signal_handler(sef_cb_signal_handler
);
123 /* Let SEF perform startup. */
127 /*============================================================================*
128 * sef_cb_init_fresh *
129 *============================================================================*/
131 sef_cb_init_fresh(int UNUSED( type
), sef_init_info_t
*UNUSED( info
))
133 /* Initialize the ethernet driver. */
137 memset(&lan8710a_state
, 0, sizeof(lan8710a_state
));
139 /* Initialize driver. */
142 /* Get instance of ethernet device */
143 env_parse("instance", "d", 0, &v
, 0, 255);
144 lan8710a_state
.instance
= (int) v
;
146 /* Announce we are up! */
147 netdriver_announce();
152 /*============================================================================*
153 * sef_cb_signal_handler *
154 *============================================================================*/
156 sef_cb_signal_handler(int signal
)
158 /* Only check for termination signal, ignore anything else. */
159 if (signal
!= SIGTERM
)
165 /*============================================================================*
166 * lan8710a_enable_interrupt *
167 *============================================================================*/
169 lan8710a_enable_interrupt(interrupt
)
174 if (interrupt
& RX_INT
) {
175 if ((r
= sys_irqenable(&lan8710a_state
.irq_rx_hook
)) != OK
) {
176 panic("sys_irqenable failed: %d", r
);
179 if (interrupt
& TX_INT
) {
180 if ((r
= sys_irqenable(&lan8710a_state
.irq_tx_hook
)) != OK
) {
181 panic("sys_irqenable failed: %d", r
);
185 /*============================================================================*
186 * lan8710a_interrupt *
187 *============================================================================*/
189 lan8710a_interrupt(m
)
192 lan8710a_t
*e
= &lan8710a_state
;
195 /* Check the card for interrupt reason(s). */
196 u32_t rx_stat
= lan8710a_reg_read(CPSW_WR_C0_RX_STAT
);
197 u32_t tx_stat
= lan8710a_reg_read(CPSW_WR_C0_TX_STAT
);
200 /* Handle interrupts. */
202 cp
= lan8710a_reg_read(CPDMA_STRAM_RX_CP(0));
204 lan8710a_readv_s(&(e
->rx_message
), TRUE
);
206 lan8710a_reg_write(CPDMA_STRAM_RX_CP(0), cp
);
207 lan8710a_reg_write(CPDMA_EOI_VECTOR
, RX_INT
);
210 cp
= lan8710a_reg_read(CPDMA_STRAM_TX_CP(0));
212 /* Disabling channels, where Tx interrupt occurred */
213 lan8710a_reg_set(CPDMA_TX_INTMASK_CLEAR
, tx_stat
);
215 lan8710a_writev_s(&(e
->tx_message
), TRUE
);
217 lan8710a_reg_write(CPDMA_STRAM_TX_CP(0), cp
);
218 lan8710a_reg_write(CPDMA_EOI_VECTOR
, TX_INT
);
221 dma_status
= lan8710a_reg_read(CPDMA_STATUS
);
223 if (dma_status
& CPDMA_ERROR
) {
224 LAN8710A_DEBUG_PRINT(("CPDMA error: 0x%X, reset", dma_status
));
225 lan8710a_dma_reset_init();
228 /* Re-enable Rx interrupt. */
229 if(m
->m_notify
.interrupts
& (1 << RX_INT
))
230 lan8710a_enable_interrupt(RX_INT
);
232 /* Re-enable Tx interrupt. */
233 if(m
->m_notify
.interrupts
& (1 << TX_INT
))
234 lan8710a_enable_interrupt(TX_INT
);
237 /*============================================================================*
239 *============================================================================*/
246 if (!(lan8710a_state
.status
& LAN8710A_ENABLED
) &&
247 !(lan8710a_init_hw())) {
248 reply
.m_type
= DL_CONF_REPLY
;
249 reply
.DL_STAT
= ENXIO
;
250 mess_reply(m
, &reply
);
253 /* Reply back to INET. */
254 reply
.m_type
= DL_CONF_REPLY
;
256 *(ether_addr_t
*) reply
.DL_HWADDR
= lan8710a_state
.address
;
257 mess_reply(m
, &reply
);
260 /*============================================================================*
262 *============================================================================*/
267 strlcpy(lan8710a_state
.name
, "lan8710a#0", LAN8710A_NAME_LEN
);
268 lan8710a_state
.name
[9] += lan8710a_state
.instance
;
269 lan8710a_state
.status
|= LAN8710A_DETECTED
;
271 if (!(lan8710a_state
.status
& LAN8710A_ENABLED
) &&
272 !(lan8710a_init_hw())) {
277 /*============================================================================*
278 * lan8710a_init_addr *
279 *============================================================================*/
281 lan8710a_init_addr(void)
283 static char eakey
[]= LAN8710A_ENVVAR
"#_EA";
284 static char eafmt
[]= "x:x:x:x:x:x";
289 * Do we have a user defined ethernet address?
291 eakey
[sizeof(LAN8710A_ENVVAR
)-1] = '0' + lan8710a_state
.instance
;
293 for (i
= 0; i
< 6; i
++) {
294 if (env_parse(eakey
, eafmt
, i
, &v
, 0x00L
, 0xFFL
) != EP_SET
)
297 lan8710a_state
.address
.ea_addr
[i
] = v
;
300 lan8710a_state
.address
.ea_addr
[0] =
301 (lan8710a_reg_read(CTRL_MAC_ID0_HI
) & 0xFF);
302 lan8710a_state
.address
.ea_addr
[1] =
303 ((lan8710a_reg_read(CTRL_MAC_ID0_HI
) & 0xFF00) >> 8);
304 lan8710a_state
.address
.ea_addr
[2] =
305 ((lan8710a_reg_read(CTRL_MAC_ID0_HI
) & 0xFF0000) >> 16);
306 lan8710a_state
.address
.ea_addr
[3] =
307 ((lan8710a_reg_read(CTRL_MAC_ID0_HI
) & 0xFF000000) >> 24);
308 lan8710a_state
.address
.ea_addr
[4] =
309 (lan8710a_reg_read(CTRL_MAC_ID0_LO
) & 0xFF);
310 lan8710a_state
.address
.ea_addr
[5] =
311 ((lan8710a_reg_read(CTRL_MAC_ID0_LO
) & 0xFF00) >> 8);
315 /*============================================================================*
316 * lan8710a_map_regs *
317 *============================================================================*/
319 lan8710a_map_regs(void)
321 struct minix_mem_range mr
;
322 mr
.mr_base
= CM_PER_BASE_ADR
;
323 mr
.mr_limit
= CM_PER_BASE_ADR
+ MEMORY_LIMIT
;
325 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != 0) {
326 panic("Unable to request permission to map memory");
328 lan8710a_state
.regs_cp_per
=
329 (vir_bytes
)vm_map_phys(SELF
, (void *)CM_PER_BASE_ADR
, 512);
330 if ((void *)lan8710a_state
.regs_cp_per
== MAP_FAILED
) {
331 panic("lan8710a_state.regs_cp_per: vm_map_phys failed");
333 lan8710a_state
.regs_cpdma_stram
=
334 (vir_bytes
)vm_map_phys(SELF
, (void *)CPDMA_STRAM_BASE_ADR
, 512);
335 if ((void *)lan8710a_state
.regs_cpdma_stram
== MAP_FAILED
) {
336 panic("lan8710a_state.regs_cpdma_stram: vm_map_phys failed");
338 lan8710a_state
.regs_cpsw_cpdma
=
339 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_CPDMA_BASE_ADR
, 512);
340 if ((void *)lan8710a_state
.regs_cpsw_cpdma
== MAP_FAILED
) {
341 panic("lan8710a_state.regs_cpsw_cpdma: vm_map_phys failed");
343 lan8710a_state
.regs_cpsw_ale
=
344 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_ALE_BASE_ADR
, 256);
345 if ((void *)lan8710a_state
.regs_cpsw_ale
== MAP_FAILED
) {
346 panic("lan8710a_state.regs_cpsw_ale: vm_map_phys failed");
348 lan8710a_state
.regs_cpsw_sl
=
349 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_SL_BASE_ADR
, 512);
350 if ((void *)lan8710a_state
.regs_cpsw_sl
== MAP_FAILED
) {
351 panic("lan8710a_state.regs_cpsw_sl: vm_map_phys failed");
353 lan8710a_state
.regs_cpsw_ss
=
354 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_SS_BASE_ADR
, 512);
355 if ((void *)lan8710a_state
.regs_cpsw_ss
== MAP_FAILED
) {
356 panic("lan8710a_state.regs_cpsw_ss: vm_map_phys failed");
358 lan8710a_state
.regs_cpsw_wr
=
359 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_WR_BASE_ADR
, 512);
360 if ((void *)lan8710a_state
.regs_cpsw_wr
== MAP_FAILED
) {
361 panic("lan8710a_state.regs_cpsw_wr: vm_map_phys failed");
363 lan8710a_state
.regs_ctrl_mod
=
364 (vir_bytes
)vm_map_phys(SELF
, (void *)CTRL_MOD_BASE_ADR
, 2560);
365 if ((void *)lan8710a_state
.regs_ctrl_mod
== MAP_FAILED
) {
366 panic("lan8710a_state.regs_ctrl_mod: vm_map_phys failed");
368 lan8710a_state
.regs_intc
=
369 (vir_bytes
)vm_map_phys(SELF
, (void *)INTC_BASE_ADR
, 512);
370 if ((void *)lan8710a_state
.regs_intc
== MAP_FAILED
) {
371 panic("lan8710a_state.regs_intc: vm_map_phys failed");
373 lan8710a_state
.regs_mdio
=
374 (vir_bytes
)vm_map_phys(SELF
, (void *)MDIO_BASE_ADDR
, 512);
375 if ((void *)lan8710a_state
.regs_mdio
== MAP_FAILED
) {
376 panic("lan8710a_state.regs_mdio: vm_map_phys failed");
379 mr
.mr_base
= BEGINNING_DESC_MEM
;
380 mr
.mr_limit
= BEGINNING_DESC_MEM
+ DESC_MEMORY_LIMIT
;
382 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != 0) {
383 panic("Unable to request permission to map memory");
385 lan8710a_state
.rx_desc_phy
= BEGINNING_RX_DESC_MEM
;
386 lan8710a_state
.tx_desc_phy
= BEGINNING_TX_DESC_MEM
;
387 lan8710a_state
.rx_desc
= (lan8710a_desc_t
*)vm_map_phys(SELF
,
388 (void *)lan8710a_state
.rx_desc_phy
, 1024);
389 if ((void *)lan8710a_state
.rx_desc
== MAP_FAILED
) {
390 panic("lan8710a_state.rx_desc: vm_map_phys failed");
392 lan8710a_state
.tx_desc
= (lan8710a_desc_t
*)vm_map_phys(SELF
,
393 (void *)lan8710a_state
.tx_desc_phy
, 1024);
394 if ((void *)lan8710a_state
.tx_desc
== MAP_FAILED
) {
395 panic("lan8710a_state.tx_desc: vm_map_phys failed");
398 mr
.mr_base
= CPSW_STATS_BASE_ADR
;
399 mr
.mr_limit
= CPSW_STATS_BASE_ADR
+ CPSW_STATS_MEM_LIMIT
;
401 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != 0) {
402 panic("Unable to request permission to map memory");
404 lan8710a_state
.regs_cpsw_stats
=
405 (vir_bytes
)vm_map_phys(SELF
, (void *)CPSW_STATS_BASE_ADR
, 256);
406 if ((void *)lan8710a_state
.regs_cpsw_stats
== MAP_FAILED
) {
407 panic("lan8710a_state.regs_cpsw_stats: vm_map_phys failed");
411 /*============================================================================*
413 *============================================================================*/
421 stats
.ets_recvErr
= lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR
)
422 + lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR
)
423 + lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE
);
424 stats
.ets_sendErr
= 0;
426 stats
.ets_CRCerr
= lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR
);
427 stats
.ets_frameAll
= lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR
);
428 stats
.ets_missedP
= 0;
429 stats
.ets_packetR
= lan8710a_reg_read(CPSW_STAT_RX_GOOD
);
430 stats
.ets_packetT
= lan8710a_reg_read(CPSW_STAT_TX_GOOD
);
431 stats
.ets_collision
= lan8710a_reg_read(CPSW_STAT_COLLISIONS
);
432 stats
.ets_transAb
= 0;
433 stats
.ets_carrSense
= lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR
);
434 stats
.ets_fifoUnder
= lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN
);
435 stats
.ets_fifoOver
= lan8710a_reg_read(CPSW_STAT_RX_OVERRUN
);
436 stats
.ets_CDheartbeat
= 0;
439 sys_safecopyto(mp
->m_source
, mp
->DL_GRANT
, 0, (vir_bytes
)&stats
,
441 mp
->m_type
= DL_STAT_REPLY
;
443 if ((r
=ipc_send(mp
->m_source
, mp
)) != OK
) {
444 panic("lan8710a_getstat: ipc_send() failed: %d", r
);
448 /*============================================================================*
450 *============================================================================*/
454 /* Reset hardware. */
461 /*============================================================================*
462 * lan8710a_dma_config_tx *
463 *============================================================================*/
465 lan8710a_dma_config_tx(desc_idx
)
468 phys_bytes phys_addr
;
470 for (i
= 0; i
< TX_DMA_CHANNELS
; ++i
) {
471 if (!lan8710a_reg_read(CPDMA_STRAM_TX_HDP(i
))) break;
473 if (i
== TX_DMA_CHANNELS
) {
474 panic("There are no free TX DMA channels.");
477 /* Enabling only one channel Tx interrupt */
478 lan8710a_reg_write(CPDMA_TX_INTMASK_SET
, 1 << i
);
479 /* Routing only one channel Tx int to TX_PULSE signal */
480 lan8710a_reg_write(CPSW_WR_C0_TX_EN
, 1 << i
);
483 phys_addr
= lan8710a_state
.tx_desc_phy
+
484 (desc_idx
* sizeof(lan8710a_desc_t
));
485 lan8710a_reg_write(CPDMA_STRAM_TX_HDP(i
), (u32_t
)phys_addr
);
488 /*============================================================================*
489 * lan8710a_dma_reset_init *
490 *============================================================================*/
492 lan8710a_dma_reset_init(void)
495 lan8710a_reg_write(CPDMA_SOFT_RESET
, SOFT_RESET
);
496 while ((lan8710a_reg_read(CPDMA_SOFT_RESET
) & SOFT_RESET
));
499 * Initialize the HDPs (Header Description Pointers) and
500 * CPs (Completion Pointers) to NULL.
502 for (i
= 0; i
< DMA_MAX_CHANNELS
; ++i
) {
503 lan8710a_reg_write(CPDMA_STRAM_TX_HDP(i
), 0);
504 lan8710a_reg_write(CPDMA_STRAM_RX_HDP(i
), 0);
505 lan8710a_reg_write(CPDMA_STRAM_TX_CP(i
), 0);
506 lan8710a_reg_write(CPDMA_STRAM_RX_CP(i
), 0);
509 lan8710a_reg_write(CPDMA_RX_INTMASK_CLEAR
, 0xFFFFFFFF);
510 lan8710a_reg_write(CPDMA_TX_INTMASK_CLEAR
, 0xFFFFFFFF);
512 /* Configure the CPDMA controller. */
513 lan8710a_reg_set(CPDMA_RX_CONTROL
, CPDMA_RX_EN
); /* RX Enabled */
514 lan8710a_reg_set(CPDMA_TX_CONTROL
, CPDMA_TX_EN
); /* TX Enabled */
516 /* Enabling first channel Rx interrupt */
517 lan8710a_reg_set(CPDMA_RX_INTMASK_SET
, CPDMA_FIRST_CHAN_INT
);
520 * Writing the address of the first buffer descriptor in the queue
521 * (nonzero value)to the channel’s head descriptor pointer in the
522 * channel’s Rx DMA state.
524 lan8710a_reg_write(CPDMA_STRAM_RX_HDP(0),
525 (u32_t
)lan8710a_state
.rx_desc_phy
);
527 lan8710a_state
.rx_desc_idx
= 0;
528 lan8710a_state
.tx_desc_idx
= 0;
531 /*============================================================================*
532 * lan8710a_init_desc *
533 *============================================================================*/
535 lan8710a_init_desc(void)
537 lan8710a_desc_t
*p_rx_desc
;
538 lan8710a_desc_t
*p_tx_desc
;
539 phys_bytes buf_phys_addr
;
543 /* Attempt to allocate. */
544 if ((lan8710a_state
.p_rx_buf
= alloc_contig((LAN8710A_NUM_RX_DESC
545 * LAN8710A_IOBUF_SIZE
), AC_ALIGN4K
,
546 &buf_phys_addr
)) == NULL
) {
547 panic("failed to allocate RX buffers.");
549 p_buf
= lan8710a_state
.p_rx_buf
;
550 for (i
= 0; i
< LAN8710A_NUM_RX_DESC
; i
++) {
551 p_rx_desc
= &(lan8710a_state
.rx_desc
[i
]);
552 memset(p_rx_desc
, 0x0, sizeof(lan8710a_desc_t
));
553 p_rx_desc
->pkt_len_flags
= LAN8710A_DESC_FLAG_OWN
;
554 p_rx_desc
->buffer_length_off
= LAN8710A_IOBUF_SIZE
;
555 p_rx_desc
->buffer_pointer
= (u32_t
)(buf_phys_addr
+
556 (i
* LAN8710A_IOBUF_SIZE
));
558 p_rx_desc
->next_pointer
=
559 (u32_t
)((i
== (LAN8710A_NUM_RX_DESC
- 1)) ?
560 (lan8710a_state
.rx_desc_phy
) :
561 (lan8710a_state
.rx_desc_phy
+
562 ((i
+ 1) * sizeof(lan8710a_desc_t
))));
565 /* Attempt to allocate. */
566 if ((lan8710a_state
.p_tx_buf
= alloc_contig((LAN8710A_NUM_TX_DESC
567 * LAN8710A_IOBUF_SIZE
), AC_ALIGN4K
,
568 &buf_phys_addr
)) == NULL
) {
569 panic("failed to allocate TX buffers");
571 p_buf
= lan8710a_state
.p_tx_buf
;
572 for (i
= 0; i
< LAN8710A_NUM_TX_DESC
; i
++) {
573 p_tx_desc
= &(lan8710a_state
.tx_desc
[i
]);
574 memset(p_tx_desc
, 0x0, sizeof(lan8710a_desc_t
));
575 p_tx_desc
->buffer_pointer
= (u32_t
)(buf_phys_addr
+
576 (i
* LAN8710A_IOBUF_SIZE
));
578 lan8710a_state
.rx_desc_idx
= 0;
579 lan8710a_state
.tx_desc_idx
= 0;
582 /*============================================================================*
584 *============================================================================*/
586 lan8710a_init_hw(void)
590 lan8710a_state
.status
|= LAN8710A_ENABLED
;
593 * Set the interrupt handler and policy. Do not automatically
594 * re-enable interrupts. Return the IRQ line number on interrupts.
596 lan8710a_state
.irq_rx_hook
= RX_INT
;
597 if ((r
= sys_irqsetpolicy(LAN8710A_RX_INTR
, 0,
598 &lan8710a_state
.irq_rx_hook
)) != OK
) {
599 panic("sys_irqsetpolicy failed: %d", r
);
601 lan8710a_state
.irq_tx_hook
= TX_INT
;
602 if ((r
= sys_irqsetpolicy(LAN8710A_TX_INTR
, 0,
603 &lan8710a_state
.irq_tx_hook
)) != OK
) {
604 panic("sys_irqsetpolicy failed: %d", r
);
607 /* Reset hardware. */
611 * Select the Interface (GMII/RGMII/MII) Mode in the Control Module.
612 * Port1 GMII/MII Mode, Port2 not used.
614 lan8710a_reg_write(GMII_SEL
, (GMII2_SEL_BIT1
| GMII2_SEL_BIT0
));
617 * Configure pads (PIN muxing) as per the Interface Selected using the
618 * appropriate pin muxing conf_xxx registers in the Control Module.
620 * CONF_MOD_SLEW_CTRL when 0 - Fast Mode, when 1 - Slow Mode
621 * CONF_MOD_RX_ACTIVE when 0 - Only output, when 1 - Also input
622 * CONF_MOD_PU_TYPESEL when 0 - Pull-down, when 1 - Pull-up
623 * CONF_MOD_PUDEN when 0 Pull* enabled, when 1 Pull* disabled
624 * CONF_MOD_MMODE_MII selects pin to work for MII interface
626 lan8710a_reg_unset(CONF_MII1_COL
, CONF_MOD_SLEW_CTRL
);
627 lan8710a_reg_set(CONF_MII1_COL
, CONF_MOD_RX_ACTIVE
);
628 lan8710a_reg_set(CONF_MII1_COL
, CONF_MOD_PU_TYPESEL
);
629 lan8710a_reg_unset(CONF_MII1_COL
, CONF_MOD_PUDEN
);
630 lan8710a_reg_unset(CONF_MII1_COL
, CONF_MOD_MMODE_MII
);
632 lan8710a_reg_unset(CONF_MII1_CRS
, CONF_MOD_SLEW_CTRL
);
633 lan8710a_reg_set(CONF_MII1_CRS
, CONF_MOD_RX_ACTIVE
);
634 lan8710a_reg_set(CONF_MII1_CRS
, CONF_MOD_PU_TYPESEL
);
635 lan8710a_reg_unset(CONF_MII1_CRS
, CONF_MOD_PUDEN
);
636 lan8710a_reg_unset(CONF_MII1_CRS
, CONF_MOD_MMODE_MII
);
638 lan8710a_reg_unset(CONF_MII1_RX_ER
, CONF_MOD_SLEW_CTRL
);
639 lan8710a_reg_set(CONF_MII1_RX_ER
, CONF_MOD_RX_ACTIVE
);
640 lan8710a_reg_set(CONF_MII1_RX_ER
, CONF_MOD_PU_TYPESEL
);
641 lan8710a_reg_unset(CONF_MII1_RX_ER
, CONF_MOD_PUDEN
);
642 lan8710a_reg_unset(CONF_MII1_RX_ER
, CONF_MOD_MMODE_MII
);
644 lan8710a_reg_unset(CONF_MII1_TX_EN
, CONF_MOD_SLEW_CTRL
);
645 lan8710a_reg_unset(CONF_MII1_TX_EN
, CONF_MOD_RX_ACTIVE
);
646 lan8710a_reg_set(CONF_MII1_TX_EN
, CONF_MOD_PUDEN
);
647 lan8710a_reg_unset(CONF_MII1_TX_EN
, CONF_MOD_MMODE_MII
);
649 lan8710a_reg_unset(CONF_MII1_RX_DV
, CONF_MOD_SLEW_CTRL
);
650 lan8710a_reg_set(CONF_MII1_RX_DV
, CONF_MOD_RX_ACTIVE
);
651 lan8710a_reg_set(CONF_MII1_RX_DV
, CONF_MOD_PU_TYPESEL
);
652 lan8710a_reg_unset(CONF_MII1_RX_DV
, CONF_MOD_PUDEN
);
653 lan8710a_reg_unset(CONF_MII1_RX_DV
, CONF_MOD_MMODE_MII
);
655 lan8710a_reg_unset(CONF_MII1_TXD3
, CONF_MOD_SLEW_CTRL
);
656 lan8710a_reg_unset(CONF_MII1_TXD3
, CONF_MOD_RX_ACTIVE
);
657 lan8710a_reg_set(CONF_MII1_TXD3
, CONF_MOD_PUDEN
);
658 lan8710a_reg_unset(CONF_MII1_TXD3
, CONF_MOD_MMODE_MII
);
660 lan8710a_reg_unset(CONF_MII1_TXD2
, CONF_MOD_SLEW_CTRL
);
661 lan8710a_reg_unset(CONF_MII1_TXD2
, CONF_MOD_RX_ACTIVE
);
662 lan8710a_reg_set(CONF_MII1_TXD2
, CONF_MOD_PUDEN
);
663 lan8710a_reg_unset(CONF_MII1_TXD2
, CONF_MOD_MMODE_MII
);
665 lan8710a_reg_unset(CONF_MII1_TXD1
, CONF_MOD_SLEW_CTRL
);
666 lan8710a_reg_unset(CONF_MII1_TXD1
, CONF_MOD_RX_ACTIVE
);
667 lan8710a_reg_set(CONF_MII1_TXD1
, CONF_MOD_PUDEN
);
668 lan8710a_reg_unset(CONF_MII1_TXD1
, CONF_MOD_MMODE_MII
);
670 lan8710a_reg_unset(CONF_MII1_TXD0
, CONF_MOD_SLEW_CTRL
);
671 lan8710a_reg_unset(CONF_MII1_TXD0
, CONF_MOD_RX_ACTIVE
);
672 lan8710a_reg_set(CONF_MII1_TXD0
, CONF_MOD_PUDEN
);
673 lan8710a_reg_unset(CONF_MII1_TXD0
, CONF_MOD_MMODE_MII
);
675 lan8710a_reg_unset(CONF_MII1_TX_CLK
, CONF_MOD_SLEW_CTRL
);
676 lan8710a_reg_set(CONF_MII1_TX_CLK
, CONF_MOD_RX_ACTIVE
);
677 lan8710a_reg_set(CONF_MII1_TX_CLK
, CONF_MOD_PUDEN
);
678 lan8710a_reg_unset(CONF_MII1_TX_CLK
, CONF_MOD_MMODE_MII
);
680 lan8710a_reg_unset(CONF_MII1_RX_CLK
, CONF_MOD_SLEW_CTRL
);
681 lan8710a_reg_set(CONF_MII1_RX_CLK
, CONF_MOD_RX_ACTIVE
);
682 lan8710a_reg_set(CONF_MII1_RX_CLK
, CONF_MOD_PUDEN
);
683 lan8710a_reg_unset(CONF_MII1_RX_CLK
, CONF_MOD_MMODE_MII
);
685 lan8710a_reg_unset(CONF_MII1_RXD3
, CONF_MOD_SLEW_CTRL
);
686 lan8710a_reg_set(CONF_MII1_RXD3
, CONF_MOD_RX_ACTIVE
);
687 lan8710a_reg_set(CONF_MII1_RXD3
, CONF_MOD_PU_TYPESEL
);
688 lan8710a_reg_unset(CONF_MII1_RXD3
, CONF_MOD_PUDEN
);
689 lan8710a_reg_unset(CONF_MII1_RXD3
, CONF_MOD_MMODE_MII
);
691 lan8710a_reg_unset(CONF_MII1_RXD2
, CONF_MOD_SLEW_CTRL
);
692 lan8710a_reg_set(CONF_MII1_RXD2
, CONF_MOD_RX_ACTIVE
);
693 lan8710a_reg_set(CONF_MII1_RXD2
, CONF_MOD_PU_TYPESEL
);
694 lan8710a_reg_unset(CONF_MII1_RXD2
, CONF_MOD_PUDEN
);
695 lan8710a_reg_unset(CONF_MII1_RXD2
, CONF_MOD_MMODE_MII
);
697 lan8710a_reg_unset(CONF_MII1_RXD1
, CONF_MOD_SLEW_CTRL
);
698 lan8710a_reg_set(CONF_MII1_RXD1
, CONF_MOD_RX_ACTIVE
);
699 lan8710a_reg_set(CONF_MII1_RXD1
, CONF_MOD_PU_TYPESEL
);
700 lan8710a_reg_unset(CONF_MII1_RXD1
, CONF_MOD_PUDEN
);
701 lan8710a_reg_unset(CONF_MII1_RXD1
, CONF_MOD_MMODE_MII
);
703 lan8710a_reg_unset(CONF_MII1_RXD0
, CONF_MOD_SLEW_CTRL
);
704 lan8710a_reg_set(CONF_MII1_RXD0
, CONF_MOD_RX_ACTIVE
);
705 lan8710a_reg_set(CONF_MII1_RXD0
, CONF_MOD_PU_TYPESEL
);
706 lan8710a_reg_unset(CONF_MII1_RXD0
, CONF_MOD_PUDEN
);
707 lan8710a_reg_unset(CONF_MII1_RXD0
, CONF_MOD_MMODE_MII
);
709 lan8710a_reg_unset(CONF_MDIO
, CONF_MOD_SLEW_CTRL
);
710 lan8710a_reg_set(CONF_MDIO
, CONF_MOD_RX_ACTIVE
);
711 lan8710a_reg_set(CONF_MDIO
, CONF_MOD_PU_TYPESEL
);
712 lan8710a_reg_unset(CONF_MDIO
, CONF_MOD_PUDEN
);
713 lan8710a_reg_unset(CONF_MDIO
, CONF_MOD_MMODE_MII
);
715 lan8710a_reg_unset(CONF_MDC
, CONF_MOD_SLEW_CTRL
);
716 lan8710a_reg_unset(CONF_MDC
, CONF_MOD_RX_ACTIVE
);
717 lan8710a_reg_set(CONF_MDC
, CONF_MOD_PUDEN
);
718 lan8710a_reg_unset(CONF_MDC
, CONF_MOD_MMODE_MII
);
720 /* Apply soft reset to 3PSW Subsytem, CPSW_3G, CPGMAC_SL, and CPDMA. */
721 lan8710a_reg_write(CPSW_SS_SOFT_RESET
, SOFT_RESET
);
722 lan8710a_reg_write(CPSW_SL_SOFT_RESET(1), SOFT_RESET
);
723 lan8710a_reg_write(CPSW_SL_SOFT_RESET(2), SOFT_RESET
);
725 /* Wait for software resets completion */
726 while ((lan8710a_reg_read(CPSW_SS_SOFT_RESET
) & SOFT_RESET
) ||
727 (lan8710a_reg_read(CPSW_SL_SOFT_RESET(1)) & SOFT_RESET
) ||
728 (lan8710a_reg_read(CPSW_SL_SOFT_RESET(2)) & SOFT_RESET
));
730 /* Configure the Statistics Port Enable register. */
731 /* Enable port 0 and 1 statistics. */
732 lan8710a_reg_write(CPSW_SS_STAT_PORT_EN
, (CPSW_P1_STAT_EN
|
738 * All packets received on ports 1 are
739 * sent to the host (only to the host).
741 lan8710a_reg_write(CPSW_ALE_CONTROL
, (CPSW_ALE_ENABLE
|
743 /* Port 0 (host) in forwarding mode. */
744 lan8710a_reg_write(CPSW_ALE_PORTCTL0
, CPSW_ALE_PORT_FWD
);
745 /* Port 1 in forwarding mode. */
746 lan8710a_reg_write(CPSW_ALE_PORTCTL1
, CPSW_ALE_PORT_FWD
);
749 * Configure CPSW_SL Register
752 lan8710a_reg_write(CPSW_SL_MACCONTROL(1), CPSW_SL_FULLDUPLEX
);
754 /* Initialize MDIO Protocol */
755 lan8710a_init_mdio();
757 /* Getting MAC Address */
758 lan8710a_init_addr();
760 /* Initialize descriptors */
761 lan8710a_init_desc();
763 /* Reset and initialize CPDMA */
764 lan8710a_dma_reset_init();
767 * Configure the Interrupts.
768 * Routing all channel Rx int to RX_PULSE signal.
770 lan8710a_reg_set(CPSW_WR_C0_RX_EN
, CPSW_FIRST_CHAN_INT
);
773 * Enabling LAN8710A Auto-negotiation
775 lan8710a_phy_write(LAN8710A_CTRL_REG
, LAN8710A_AUTO_NEG
);
777 /* Waiting for auto-negotiaion completion. */
778 for (i
= 0; !(lan8710a_phy_read(LAN8710A_STATUS_REG
) &
779 LAN8710A_AUTO_NEG_COMPL
); ++i
) {
781 LAN8710A_DEBUG_PRINT(("Autonegotiation failed"));
787 /* GMII RX and TX release from reset. */
788 lan8710a_reg_set(CPSW_SL_MACCONTROL(1), CPSW_SL_GMII_EN
);
790 /* Enable interrupts. */
791 lan8710a_enable_interrupt(RX_INT
| TX_INT
);
796 /*============================================================================*
797 * lan8710a_init_mdio *
798 *============================================================================*/
800 lan8710a_init_mdio(void)
805 /* Clearing MDIOCONTROL register */
806 lan8710a_reg_write(MDIOCONTROL
, 0);
807 /* Configure the PREAMBLE and CLKDIV in the MDIO control register */
808 lan8710a_reg_unset(MDIOCONTROL
, MDIO_PREAMBLE
); /* CLKDIV default */
809 /* Enable sending MDIO frame preambles */
810 lan8710a_reg_set(MDIOCONTROL
, (MDCLK_DIVIDER
| MDIO_ENABLE
));
811 /* Enable the MDIO module by setting the ENABLE bit in MDIOCONTROL */
813 while (!(r
= lan8710a_reg_read(MDIOALIVE
)));
815 /* Get PHY address */
819 lan8710a_state
.phy_address
= address
;
821 /* Setup appropiate address in MDIOUSERPHYSEL0 */
822 lan8710a_reg_set(MDIOUSERPHYSEL0
, address
);
825 /*============================================================================*
826 * lan8710a_writev_s *
827 *============================================================================*/
829 lan8710a_writev_s(mp
, from_int
)
833 iovec_s_t iovec
[LAN8710A_IOVEC_NR
];
834 lan8710a_t
*e
= &lan8710a_state
;
835 lan8710a_desc_t
*p_tx_desc
;
837 int r
, size
, buf_data_len
, i
;
839 /* Are we called from the interrupt handler? */
841 /* We cannot write twice simultaneously. */
842 assert(!(e
->status
& LAN8710A_WRITING
));
844 /* Copy write message. */
846 e
->client
= mp
->m_source
;
847 e
->status
|= LAN8710A_WRITING
;
849 /* verify vector count */
850 assert(mp
->DL_COUNT
> 0);
851 assert(mp
->DL_COUNT
< LAN8710A_IOVEC_NR
);
854 * Copy the I/O vector table.
856 if ((r
= sys_safecopyfrom(mp
->m_source
, mp
->DL_GRANT
, 0,
858 mp
->DL_COUNT
* sizeof(iovec_s_t
))) != OK
) {
859 panic("sys_safecopyfrom() failed: %d", r
);
861 /* setup descriptors */
862 p_tx_desc
= &(e
->tx_desc
[e
->tx_desc_idx
]);
865 * Check if descriptor is available for host
866 * and drop the packet if not.
868 if (LAN8710A_DESC_FLAG_OWN
& p_tx_desc
->pkt_len_flags
) {
869 panic("No available transmit descriptor.");
872 /* virtual address of buffer */
873 p_buf
= e
->p_tx_buf
+ e
->tx_desc_idx
* LAN8710A_IOBUF_SIZE
;
875 for (i
= 0; i
< mp
->DL_COUNT
; i
++) {
876 if ((buf_data_len
+ iovec
[i
].iov_size
)
877 > LAN8710A_IOBUF_SIZE
) {
878 panic("packet too long");
881 /* copy data to buffer */
882 size
= iovec
[i
].iov_size
883 < (LAN8710A_IOBUF_SIZE
- buf_data_len
) ?
885 : (LAN8710A_IOBUF_SIZE
- buf_data_len
);
887 /* Copy bytes to TX queue buffers. */
888 if ((r
= sys_safecopyfrom(mp
->m_source
,
889 iovec
[i
].iov_grant
, 0,
890 (vir_bytes
) p_buf
, size
)) != OK
) {
891 panic("sys_safecopyfrom() failed: %d", r
);
894 buf_data_len
+= size
;
897 /* set descriptor length */
898 p_tx_desc
->buffer_length_off
= buf_data_len
;
900 p_tx_desc
->pkt_len_flags
= (LAN8710A_DESC_FLAG_OWN
|
901 LAN8710A_DESC_FLAG_SOP
|
902 LAN8710A_DESC_FLAG_EOP
|
905 p_tx_desc
->pkt_len_flags
|= buf_data_len
;
907 /* setup DMA transfer */
908 lan8710a_dma_config_tx(e
->tx_desc_idx
);
911 if (LAN8710A_NUM_TX_DESC
== e
->tx_desc_idx
) {
915 e
->status
|= LAN8710A_TRANSMIT
;
920 /*============================================================================*
922 *============================================================================*/
924 lan8710a_readv_s(mp
, from_int
)
928 iovec_s_t iovec
[LAN8710A_IOVEC_NR
];
929 lan8710a_t
*e
= &lan8710a_state
;
930 lan8710a_desc_t
*p_rx_desc
;
934 u16_t buf_bytes
, buf_len
;
937 /* Are we called from the interrupt handler? */
940 e
->client
= mp
->m_source
;
941 e
->status
|= LAN8710A_READING
;
944 assert(e
->rx_message
.DL_COUNT
> 0);
945 assert(e
->rx_message
.DL_COUNT
< LAN8710A_IOVEC_NR
);
947 if (e
->status
& LAN8710A_READING
) {
949 * Copy the I/O vector table first.
951 if ((r
= sys_safecopyfrom(e
->rx_message
.m_source
,
952 e
->rx_message
.DL_GRANT
, 0, (vir_bytes
) iovec
,
953 e
->rx_message
.DL_COUNT
*
954 sizeof(iovec_s_t
))) != OK
) {
955 panic("sys_safecopyfrom() failed: %d", r
);
959 * Only handle one packet at a time.
961 p_rx_desc
= &(e
->rx_desc
[e
->rx_desc_idx
]);
962 /* find next OWN descriptor with SOP flag */
963 while ((0 == (LAN8710A_DESC_FLAG_SOP
&
964 p_rx_desc
->pkt_len_flags
)) &&
965 (0 == (LAN8710A_DESC_FLAG_OWN
&
966 p_rx_desc
->pkt_len_flags
))) {
967 p_rx_desc
->buffer_length_off
= LAN8710A_IOBUF_SIZE
;
968 /* set ownership of current descriptor to EMAC */
969 p_rx_desc
->pkt_len_flags
= LAN8710A_DESC_FLAG_OWN
;
972 if (LAN8710A_NUM_RX_DESC
== e
->rx_desc_idx
)
974 p_rx_desc
= &(e
->rx_desc
[e
->rx_desc_idx
]);
976 if (0 == (LAN8710A_DESC_FLAG_SOP
& p_rx_desc
->pkt_len_flags
)) {
977 /* SOP was not found */
983 * Copy to vector elements.
987 p_buf
= e
->p_rx_buf
+ e
->rx_desc_idx
* LAN8710A_IOBUF_SIZE
;
988 for (i
= 0; i
< e
->rx_message
.DL_COUNT
; i
++) {
989 buf_len
= p_rx_desc
->buffer_length_off
& 0xFFFF;
990 if (buf_bytes
== buf_len
) {
991 /* Whole buffer move to the next descriptor */
992 p_rx_desc
->buffer_length_off
=
994 /* set ownership of current desc to EMAC */
995 p_rx_desc
->pkt_len_flags
=
996 LAN8710A_DESC_FLAG_OWN
;
1000 if (LAN8710A_NUM_RX_DESC
== e
->rx_desc_idx
)
1002 p_rx_desc
= &(e
->rx_desc
[e
->rx_desc_idx
]);
1003 p_buf
= e
->p_rx_buf
+ (e
->rx_desc_idx
*
1004 LAN8710A_IOBUF_SIZE
) +
1005 (p_rx_desc
->buffer_length_off
>> 16);
1006 buf_len
= p_rx_desc
->buffer_length_off
& 0xFFFF;
1008 size
= iovec
[i
].iov_size
< (buf_len
- buf_bytes
) ?
1010 (buf_len
- buf_bytes
);
1012 if ((r
= sys_safecopyto(e
->rx_message
.m_source
,
1013 iovec
[i
].iov_grant
, 0,
1016 panic("sys_safecopyto() failed: %d", r
);
1020 pkt_data_len
+= size
;
1022 /* if EOP flag is set -> stop processing */
1023 if ((LAN8710A_DESC_FLAG_EOP
& p_rx_desc
->pkt_len_flags
) &&
1024 (buf_bytes
== buf_len
)) {
1030 /* reset owned descriptors up to EOP flag */
1031 flags
= p_rx_desc
->pkt_len_flags
;
1032 p_rx_desc
->buffer_length_off
= LAN8710A_IOBUF_SIZE
;
1033 /* set ownership of current descriptor to EMAC */
1034 p_rx_desc
->pkt_len_flags
= LAN8710A_DESC_FLAG_OWN
;
1037 if (LAN8710A_NUM_RX_DESC
== e
->rx_desc_idx
)
1040 p_rx_desc
= &(e
->rx_desc
[e
->rx_desc_idx
]);
1042 while (0 == (flags
& LAN8710A_DESC_FLAG_EOP
));
1047 e
->status
|= LAN8710A_RECEIVED
;
1048 e
->rx_size
= pkt_data_len
;
1054 /*============================================================================*
1055 * lan8710a_phy_write *
1056 *============================================================================*/
1058 lan8710a_phy_write(reg
, value
)
1062 if (!(lan8710a_reg_read(MDIOUSERACCESS0
) & MDIO_GO
)) {
1063 /* Clearing MDIOUSERACCESS0 register */
1064 lan8710a_reg_write(MDIOUSERACCESS0
, 0);
1065 /* Setting proper values in MDIOUSERACCESS0 */
1066 lan8710a_reg_set(MDIOUSERACCESS0
, MDIO_WRITE
);
1067 lan8710a_reg_set(MDIOUSERACCESS0
, reg
<< MDIO_REGADR
);
1068 lan8710a_reg_set(MDIOUSERACCESS0
,
1069 lan8710a_state
.phy_address
<< MDIO_PHYADR
);
1070 /* Data written only 16 bits. */
1071 lan8710a_reg_set(MDIOUSERACCESS0
, (value
& 0xFFFF) << MDIO_DATA
);
1072 lan8710a_reg_set(MDIOUSERACCESS0
, MDIO_GO
);
1074 /* Waiting for writing completion */
1075 while (lan8710a_reg_read(MDIOUSERACCESS0
) & MDIO_GO
);
1079 /*============================================================================*
1080 * lan8710a_phy_read *
1081 *============================================================================*/
1083 lan8710a_phy_read(reg
)
1086 u32_t value
= 0xFFFFFFFF;
1088 if (!(lan8710a_reg_read(MDIOUSERACCESS0
) & MDIO_GO
)) {
1089 /* Clearing MDIOUSERACCESS0 register */
1090 lan8710a_reg_write(MDIOUSERACCESS0
, 0);
1091 /* Setting proper values in MDIOUSERACCESS0 */
1092 lan8710a_reg_unset(MDIOUSERACCESS0
, MDIO_WRITE
);
1093 /* Reg number must be 5 bit long */
1094 lan8710a_reg_set(MDIOUSERACCESS0
, (reg
& 0x1F) << MDIO_REGADR
);
1095 /* Addr must be 5 bit long */
1096 lan8710a_reg_set(MDIOUSERACCESS0
,
1097 (lan8710a_state
.phy_address
& 0x1F) << MDIO_PHYADR
);
1098 lan8710a_reg_set(MDIOUSERACCESS0
, MDIO_GO
);
1100 /* Waiting for reading completion */
1101 while ((lan8710a_reg_read(MDIOUSERACCESS0
) & MDIO_GO
)
1102 && !(lan8710a_reg_read(MDIOUSERACCESS0
) & MDIO_ACK
));
1105 value
= lan8710a_reg_read(MDIOUSERACCESS0
) & 0xFFFF;
1110 /*============================================================================*
1111 * lan8710a_reset_hw *
1112 *============================================================================*/
1116 /* Assert a Device Reset signal. */
1117 lan8710a_phy_write(LAN8710A_CTRL_REG
, LAN8710A_SOFT_RESET
);
1119 /* Waiting for reset completion. */
1120 while (lan8710a_phy_read(LAN8710A_CTRL_REG
) & LAN8710A_SOFT_RESET
);
1123 /*============================================================================*
1124 * lan8710a_reg_read *
1125 *============================================================================*/
1127 lan8710a_reg_read(reg
)
1128 volatile u32_t
*reg
;
1132 /* Read from memory mapped register. */
1135 /* Return the result. */
1139 /*============================================================================*
1140 * lan8710a_reg_write *
1141 *============================================================================*/
1143 lan8710a_reg_write(reg
, value
)
1144 volatile u32_t
*reg
;
1147 /* Write to memory mapped register. */
1151 /*============================================================================*
1152 * lan8710a_reg_set *
1153 *============================================================================*/
1155 lan8710a_reg_set(reg
, value
)
1156 volatile u32_t
*reg
;
1161 /* First read the current value. */
1162 data
= lan8710a_reg_read(reg
);
1164 /* Set value, and write back. */
1165 lan8710a_reg_write(reg
, data
| value
);
1168 /*============================================================================*
1169 * lan8710a_reg_unset *
1170 *============================================================================*/
1172 lan8710a_reg_unset(reg
, value
)
1173 volatile u32_t
*reg
;
1178 /* First read the current value. */
1179 data
= lan8710a_reg_read(reg
);
1181 /* Unset value, and write back. */
1182 lan8710a_reg_write(reg
, data
& ~value
);
1185 /*============================================================================*
1187 *============================================================================*/
1189 mess_reply(req
, reply
)
1190 message
*req
;message
*reply
;
1192 if (ipc_send(req
->m_source
, reply
) != OK
) {
1193 panic("unable to send reply message");
1197 /*============================================================================*
1199 *============================================================================*/
1207 /* Only reply to client for read/write request. */
1208 if (!(e
->status
& LAN8710A_READING
||
1209 e
->status
& LAN8710A_WRITING
)) {
1212 /* Construct reply message. */
1213 msg
.m_type
= DL_TASK_REPLY
;
1214 msg
.DL_FLAGS
= DL_NOFLAGS
;
1217 /* Did we successfully receive packet(s)? */
1218 if (e
->status
& LAN8710A_READING
&&
1219 e
->status
& LAN8710A_RECEIVED
) {
1220 msg
.DL_FLAGS
|= DL_PACK_RECV
;
1221 msg
.DL_COUNT
= e
->rx_size
>= ETH_MIN_PACK_SIZE
?
1226 e
->status
&= ~(LAN8710A_READING
| LAN8710A_RECEIVED
);
1228 /* Did we successfully transmit packet(s)? */
1229 if (e
->status
& LAN8710A_TRANSMIT
&&
1230 e
->status
& LAN8710A_WRITING
) {
1231 msg
.DL_FLAGS
|= DL_PACK_SEND
;
1234 e
->status
&= ~(LAN8710A_WRITING
| LAN8710A_TRANSMIT
);
1237 /* Acknowledge to INET. */
1238 if ((r
= ipc_send(e
->client
, &msg
) != OK
)) {
1239 panic("ipc_send() failed: %d", r
);