On 30 August 2016 at 17:04, Alan Ott alan@softiron.co.uk wrote:
Add support for 64-bit DMA transfers, since some 64-bit platforms don't have the ability to generate DMA addresses which can fit in 32-bits.
This code came from the FreeBSD driver, the one from which this driver was derived.
This patch makes this driver use 64-bit DMA in all cases, because it was determined that there is no good way to test whether 64-bit DMA is required.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Alan Ott alan@softiron.co.uk
Reviewed-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Drivers/Net/MarvellYukonDxe/if_msk.c | 55 ++++++++++++++++++++++++++++----- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 16 ++++++++++ 2 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.c b/Drivers/Net/MarvellYukonDxe/if_msk.c index 6a395bd..eedf717 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.c +++ b/Drivers/Net/MarvellYukonDxe/if_msk.c @@ -492,6 +492,7 @@ msk_init_rx_ring ( struct msk_rxdesc *rxd; INTN i; INTN prod;
INTN nbuf; EFI_STATUS Status;
sc_if->msk_cdata.msk_rx_cons = 0;
@@ -500,17 +501,22 @@ msk_init_rx_ring (
rd = &sc_if->msk_rdata; gBS->SetMem (rd->msk_rx_ring, MSK_RX_RING_SZ, 0);
- prod = sc_if->msk_cdata.msk_rx_prod;
- for (i = 0; i < MSK_RX_RING_CNT; i++) {
- for (i = prod = 0; i < MSK_RX_RING_CNT; i++) { rxd = &sc_if->msk_cdata.msk_rxdesc[prod]; gBS->SetMem (&rxd->rx_m, sizeof (MSK_DMA_BUF), 0); rxd->rx_le = &rd->msk_rx_ring[prod];
- Status = msk_newbuf (sc_if, prod);
- if (EFI_ERROR (Status)) {
return Status;
- } MSK_INC (prod, MSK_RX_RING_CNT); }
nbuf = MSK_RX_BUF_CNT;
prod = 0;
for (i = 0; i < nbuf; i++) {
Status = msk_newbuf (sc_if, prod);
if (EFI_ERROR (Status)) {
return Status;
}
MSK_RX_INC(prod, MSK_RX_RING_CNT);
}
// Update prefetch unit. sc_if->msk_cdata.msk_rx_prod = MSK_RX_RING_CNT - 1;
@@ -532,6 +538,7 @@ msk_init_tx_ring ( sc_if->msk_cdata.msk_tx_prod = 0; sc_if->msk_cdata.msk_tx_cons = 0; sc_if->msk_cdata.msk_tx_cnt = 0;
sc_if->msk_cdata.msk_tx_high_addr = 0;
rd = &sc_if->msk_rdata; gBS->SetMem (rd->msk_tx_ring, sizeof (struct msk_tx_desc) * MSK_TX_RING_CNT, 0);
@@ -556,6 +563,13 @@ msk_discard_rxbuf (
DEBUG ((EFI_D_NET, "Marvell Yukon: discard rxbuf\n"));
+#ifdef MSK_64BIT_DMA
- rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
- rx_le = rxd->rx_le;
- rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
- MSK_INC(idx, MSK_RX_RING_CNT);
+#endif
- rxd = &sc_if->msk_cdata.msk_rxdesc[idx]; DmaBuffer = &rxd->rx_m; rx_le = rxd->rx_le;
@@ -594,6 +608,14 @@ msk_newbuf ( return Status; }
+#ifdef MSK_64BIT_DMA
- rx_le = rxd->rx_le;
- rx_le->msk_addr = htole32(MSK_ADDR_HI(PhysAddr));
- rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
- MSK_INC(idx, MSK_RX_RING_CNT);
- rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
+#endif
- gBS->SetMem (&(rxd->rx_m), sizeof (MSK_DMA_BUF), 0); rxd->rx_m.DmaMapping = Mapping; rxd->rx_m.Buf = Buffer;
@@ -1649,6 +1671,19 @@ msk_encap (
control = 0;
+#ifdef MSK_64BIT_DMA
- if (MSK_ADDR_HI(BusPhysAddr) !=
- sc_if->msk_cdata.msk_tx_high_addr) {
sc_if->msk_cdata.msk_tx_high_addr =
MSK_ADDR_HI(BusPhysAddr);
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
tx_le->msk_addr = htole32(MSK_ADDR_HI(BusPhysAddr));
tx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
sc_if->msk_cdata.msk_tx_cnt++;
MSK_INC(prod, MSK_TX_RING_CNT);
- }
+#endif
- si = prod; tx_le = &sc_if->msk_rdata.msk_tx_ring[prod]; tx_le->msk_addr = htole32 (MSK_ADDR_LO (BusPhysAddr));
@@ -1866,7 +1901,11 @@ msk_rxeof ( break; }
+#ifdef MSK_64BIT_DMA
- rxd = &sc_if->msk_cdata.msk_rxdesc[(cons + 1) % MSK_RX_RING_CNT];
+#else rxd = &sc_if->msk_cdata.msk_rxdesc[cons]; +#endif
m = rxd->rx_m; Status = msk_newbuf (sc_if, cons);
@@ -1911,8 +1950,8 @@ msk_rxeof ( mPciIo->FreeBuffer (mPciIo, EFI_SIZE_TO_PAGES (m.Length), m.Buf); } while (0);
- MSK_INC (sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
- MSK_INC (sc_if->msk_cdata.msk_rx_prod, MSK_RX_RING_CNT);
- MSK_RX_INC (sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
- MSK_RX_INC (sc_if->msk_cdata.msk_rx_prod, MSK_RX_RING_CNT);
}
static diff --git a/Drivers/Net/MarvellYukonDxe/if_mskreg.h b/Drivers/Net/MarvellYukonDxe/if_mskreg.h index f0dd05e..c95578d 100644 --- a/Drivers/Net/MarvellYukonDxe/if_mskreg.h +++ b/Drivers/Net/MarvellYukonDxe/if_mskreg.h @@ -2239,6 +2239,12 @@ struct msk_stat_desc { #define BMU_UDP_CHECK (0x57<<16) // Descr with UDP ext (YUKON only) #define BMU_BBC 0xffff // Bit 15.. 0: Buffer Byte Counter
+/* Use 64-bit DMA in all cases in UEFI. After much discussion on the mailing
- list, it was determined that there is not currently a good way to detect
- whether 32-bit DMA should be used (if ever) or whether there are any
- supported platforms on which 64-bit DMA would not work */
+#define MSK_64BIT_DMA
#define MSK_TX_RING_CNT 512 #define MSK_RX_RING_CNT 512 #define MSK_RX_BUF_ALIGN 8 @@ -2323,6 +2329,7 @@ struct msk_chain_data { void *msk_tx_ring_map; void *msk_rx_ring_map; // struct msk_rxdesc msk_jumbo_rxdesc[MSK_JUMBO_RX_RING_CNT];
- INTN msk_tx_high_addr; INTN msk_tx_prod; INTN msk_tx_cons; INTN msk_tx_cnt;
@@ -2352,6 +2359,15 @@ struct msk_ring_data { #define MSK_STAT_RING_SZ (sizeof (struct msk_stat_desc) * MSK_STAT_RING_CNT)
#define MSK_INC(x, y) ((x) = (x + 1) % y) +#ifdef MSK_64BIT_DMA +#define MSK_RX_INC(x, y) (x) = (x + 2) % y +#define MSK_RX_BUF_CNT (MSK_RX_RING_CNT / 2) +#define MSK_JUMBO_RX_BUF_CNT (MSK_JUMBO_RX_RING_CNT / 2) +#else +#define MSK_RX_INC(x, y) (x) = (x + 1) % y +#define MSK_RX_BUF_CNT MSK_RX_RING_CNT +#define MSK_JUMBO_RX_BUF_CNT MSK_JUMBO_RX_RING_CNT +#endif
#define MSK_PCI_BUS 0
#define MSK_PCIX_BUS 1
2.5.0