Date: Sat, 3 May 2003 02:42:03 -0400 From: Jake Burkholder <jake@locore.ca> To: Prafulla Deuskar <pdeuskar@FreeBSD.org> Cc: cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/dev/em if_em.c if_em.h if_em_hw.c if_em_hw.h if_em_osdep.h Message-ID: <20030503064203.GB17896@locore.ca> In-Reply-To: <200305022117.h42LH8VD046042@repoman.freebsd.org> References: <200305022117.h42LH8VD046042@repoman.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Apparently, On Fri, May 02, 2003 at 02:17:08PM -0700, Prafulla Deuskar said words to the effect of; > pdeuskar 2003/05/02 14:17:08 PDT > > FreeBSD src repository > > Modified files: > sys/dev/em if_em.c if_em.h if_em_hw.c if_em_hw.h > if_em_osdep.h > Log: > - Bus DMA'fy the driver > - Use htole* macros where appropriate so that the driver could work on > non-x86 architectures > - Use m_getcl() instead of MGETHDR/MCLGET macros > Submitted by: sam (Sam Leffler) This isn't 64 bit clean and breaks when compiled with PAE. Passing pointers to 32 bit values to bus_dmamap_load causes the next 4 bytes of memory to get overwritten when a 64 bit value is assigned through the pointer. The tx and rx header structures used to be allocated with contigmalloc, which is highly unlikely to allocate a physical address above 4G even when passed incorrect arguments, so it did not matter much that the top 32 bits were ignored. You really need to set the top 32 bits of the hardware registers which point to these structures now that they are allocated with malloc. Included below is a patch to fix these problems and make the driver work with PAE in large memory machines again. This is the only network driver we have which works in large memory machines without requiring bounce buffers, so its important to have it working for 5.1-RELEASE. I also fixed an unnecessary vtophys call for the tx_desc_base, you should use the bus address returned from bus_dmamap_load instead of converting it again with vtophys. vtophys is still used on the rx_buffer_area, this should be allocated with bus_dmamem_alloc, and bus_dmamap_load should be used to get the bus address. Bus addresses may not be equal to physical addresses, portable device drivers which make proper use of busdma must not use vtophys. Jake Index: if_em.c =================================================================== RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v retrieving revision 1.23 diff -u -r1.23 if_em.c --- if_em.c 2 May 2003 21:17:07 -0000 1.23 +++ if_em.c 2 May 2003 23:29:54 -0000 @@ -1895,11 +1895,12 @@ { u_int32_t reg_tctl; u_int32_t reg_tipg = 0; + u_int64_t bus_addr; /* Setup the Base and Length of the Tx Descriptor Ring */ - E1000_WRITE_REG(&adapter->hw, TDBAL, - vtophys((vm_offset_t) adapter->tx_desc_base)); - E1000_WRITE_REG(&adapter->hw, TDBAH, 0); + bus_addr = adapter->txdma.dma_paddr; + E1000_WRITE_REG(&adapter->hw, TDBAL, (u_int32_t)bus_addr); + E1000_WRITE_REG(&adapter->hw, TDBAH, (u_int32_t)(bus_addr >> 32)); E1000_WRITE_REG(&adapter->hw, TDLEN, adapter->num_tx_desc * sizeof(struct em_tx_desc)); @@ -2170,7 +2171,7 @@ register struct mbuf *mp = nmp; struct em_buffer *rx_buffer; struct ifnet *ifp; - u_int32_t paddr; + bus_addr_t paddr; int error; ifp = &adapter->interface_data.ac_if; @@ -2317,6 +2318,7 @@ u_int32_t reg_rctl; u_int32_t reg_rxcsum; struct ifnet *ifp; + u_int64_t bus_addr; ifp = &adapter->interface_data.ac_if; @@ -2338,9 +2340,9 @@ } /* Setup the Base and Length of the Rx Descriptor Ring */ - E1000_WRITE_REG(&adapter->hw, RDBAL, - vtophys((vm_offset_t) adapter->rx_desc_base)); - E1000_WRITE_REG(&adapter->hw, RDBAH, 0); + bus_addr = vtophys((vm_offset_t)adapter->rx_desc_base); + E1000_WRITE_REG(&adapter->hw, RDBAL, (u_int32_t)bus_addr); + E1000_WRITE_REG(&adapter->hw, RDBAH, (u_int32_t)(bus_addr >> 32)); E1000_WRITE_REG(&adapter->hw, RDLEN, adapter->num_rx_desc * sizeof(struct em_rx_desc)); Index: if_em.h =================================================================== RCS file: /home/ncvs/src/sys/dev/em/if_em.h,v retrieving revision 1.14 diff -u -r1.14 if_em.h --- if_em.h 2 May 2003 21:17:07 -0000 1.14 +++ if_em.h 2 May 2003 23:13:54 -0000 @@ -282,7 +282,7 @@ * em_dma_malloc and em_dma_free. */ struct em_dma_alloc { - u_int32_t dma_paddr; + bus_addr_t dma_paddr; caddr_t dma_vaddr; bus_dma_tag_t dma_tag; bus_dmamap_t dma_map;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030503064203.GB17896>