| 614 | } |
| 615 | |
| 616 | static void |
| 617 | emac_start_locked(struct ifnet *ifp) |
| 618 | { |
| 619 | struct emac_softc *sc; |
| 620 | struct mbuf *m, *m0; |
| 621 | uint32_t fifo, reg; |
| 622 | |
| 623 | sc = ifp->if_softc; |
| 624 | if (ifp->if_drv_flags & IFF_DRV_OACTIVE) |
| 625 | return; |
| 626 | if (sc->emac_fifo_mask == (EMAC_TX_FIFO0 | EMAC_TX_FIFO1)) |
| 627 | return; |
| 628 | if (sc->emac_link == 0) |
| 629 | return; |
| 630 | IFQ_DRV_DEQUEUE(&ifp->if_snd, m); |
| 631 | if (m == NULL) |
| 632 | return; |
| 633 | |
| 634 | /* Select channel */ |
| 635 | if (sc->emac_fifo_mask & EMAC_TX_FIFO0) |
| 636 | fifo = 1; |
| 637 | else |
| 638 | fifo = 0; |
| 639 | sc->emac_fifo_mask |= (1 << fifo); |
| 640 | if (sc->emac_fifo_mask == (EMAC_TX_FIFO0 | EMAC_TX_FIFO1)) |
| 641 | ifp->if_drv_flags |= IFF_DRV_OACTIVE; |
| 642 | EMAC_WRITE_REG(sc, EMAC_TX_INS, fifo); |
| 643 | |
| 644 | /* |
| 645 | * Emac controller wants 4 byte aligned TX buffers. |
| 646 | * We have to copy pretty much all the time. |
| 647 | */ |
| 648 | if (m->m_next != NULL || (mtod(m, uintptr_t) & 3) != 0) { |
| 649 | m0 = m_defrag(m, M_NOWAIT); |
| 650 | if (m0 == NULL) { |
| 651 | m_freem(m); |
| 652 | m = NULL; |
| 653 | return; |
| 654 | } |
| 655 | m = m0; |
| 656 | } |
| 657 | /* Write data */ |
| 658 | bus_space_write_multi_4(sc->emac_tag, sc->emac_handle, |
| 659 | EMAC_TX_IO_DATA, mtod(m, uint32_t *), |
| 660 | roundup2(m->m_len, 4) / 4); |
| 661 | |
| 662 | /* Send the data lengh. */ |
| 663 | reg = (fifo == 0) ? EMAC_TX_PL0 : EMAC_TX_PL1; |
| 664 | EMAC_WRITE_REG(sc, reg, m->m_len); |
| 665 | |
| 666 | /* Start translate from fifo to phy. */ |
| 667 | reg = (fifo == 0) ? EMAC_TX_CTL0 : EMAC_TX_CTL1; |
| 668 | EMAC_WRITE_REG(sc, reg, EMAC_READ_REG(sc, reg) | 1); |
| 669 | |
| 670 | /* Set timeout */ |
| 671 | sc->emac_watchdog_timer = 5; |
| 672 | |
| 673 | /* Data have been sent to hardware, it is okay to free the mbuf now. */ |
no test coverage detected