#define DI_INFO(dmah) ((dma_info_t *)dmah)
-/* One physical DMA segment */
-struct dma_seg {
- unsigned long addr;
- u32 length;
-};
-
-struct dma_seg_map {
- uint origsize; /* Size of the virtual packet */
- uint nsegs;
- struct dma_seg segs[MAX_DMA_SEGS];
-};
-
/*
* DMA Descriptor
* Descriptors are only read by the hardware, never written back.
u16 txout; /* index of next descriptor to post */
/* pointer to parallel array of pointers to packets */
struct sk_buff **txp;
- struct dma_seg_map *txp_dmah; /* DMA MAP meta-data handle */
/* Aligned physical address of descriptor ring */
unsigned long txdpa;
/* Original physical address of descriptor ring */
u16 rxout; /* index of next descriptor to post */
/* pointer to parallel array of pointers to packets */
struct sk_buff **rxp;
- struct dma_seg_map *rxp_dmah; /* DMA MAP meta-data handle */
/* Aligned physical address of descriptor ring */
unsigned long rxdpa;
/* Original physical address of descriptor ring */
bool aligndesc_4k;
};
-/*
- * DMA Scatter-gather list is supported. Note this is limited to TX
- * direction only
- */
-#ifdef BCMDMASGLISTOSL
-#define DMASGLIST_ENAB true
-#else
-#define DMASGLIST_ENAB false
-#endif /* BCMDMASGLISTOSL */
-
/* descriptor bumping macros */
/* faster than %, but n must be power of 2 */
#define XXD(x, n) ((x) & ((n) - 1))
di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh,
di->addrext));
- /* allocate DMA mapping vectors */
- if (DMASGLIST_ENAB) {
- if (ntxd) {
- size = ntxd * sizeof(struct dma_seg_map);
- di->txp_dmah = kzalloc(size, GFP_ATOMIC);
- if (di->txp_dmah == NULL)
- goto fail;
- }
-
- if (nrxd) {
- size = nrxd * sizeof(struct dma_seg_map);
- di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
- if (di->rxp_dmah == NULL)
- goto fail;
- }
- }
-
return (struct dma_pub *) di;
fail:
kfree(di->txp);
kfree(di->rxp);
- /* free tx packet DMA handles */
- kfree(di->txp_dmah);
-
- /* free rx packet DMA handles */
- kfree(di->rxp_dmah);
-
/* free our private info structure */
kfree(di);
*/
*(u32 *) (p->data) = 0;
- if (DMASGLIST_ENAB)
- memset(&di->rxp_dmah[rxout], 0,
- sizeof(struct dma_seg_map));
-
pa = pci_map_single(di->pbus, p->data,
di->rxbufsize, PCI_DMA_FROMDEVICE);
* allocating and initializing transmit descriptor entries.
*/
for (p = p0; p; p = next) {
- uint nsegs, j;
- struct dma_seg_map *map;
-
data = p->data;
len = p->len;
next = p->next;
continue;
/* get physical address of buffer start */
- if (DMASGLIST_ENAB)
- memset(&di->txp_dmah[txout], 0,
- sizeof(struct dma_seg_map));
-
pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
- if (DMASGLIST_ENAB) {
- map = &di->txp_dmah[txout];
-
- /* See if all the segments can be accounted for */
- if (map->nsegs >
- (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
- 1))
- goto outoftxd;
-
- nsegs = map->nsegs;
- } else
- nsegs = 1;
-
- for (j = 1; j <= nsegs; j++) {
- flags = 0;
- if (p == p0 && j == 1)
- flags |= D64_CTRL1_SOF;
+ flags = 0;
+ if (p == p0)
+ flags |= D64_CTRL1_SOF;
- /* With a DMA segment list, Descriptor table is filled
- * using the segment list instead of looping over
- * buffers in multi-chain DMA. Therefore, EOF for SGLIST
- * is when end of segment list is reached.
- */
- if ((!DMASGLIST_ENAB && next == NULL) ||
- (DMASGLIST_ENAB && j == nsegs))
- flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
- if (txout == (di->ntxd - 1))
- flags |= D64_CTRL1_EOT;
-
- if (DMASGLIST_ENAB) {
- len = map->segs[j - 1].length;
- pa = map->segs[j - 1].addr;
- }
- dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+ /* With a DMA segment list, Descriptor table is filled
+ * using the segment list instead of looping over
+ * buffers in multi-chain DMA. Therefore, EOF for SGLIST
+ * is when end of segment list is reached.
+ */
+ if (next == NULL)
+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= D64_CTRL1_EOT;
- txout = NEXTTXD(txout);
- }
+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
- /* See above. No need to loop over individual buffers */
- if (DMASGLIST_ENAB)
- break;
+ txout = NEXTTXD(txout);
}
/* if last txd eof not set, fix it */
for (i = start; i != end && !txp; i = NEXTTXD(i)) {
unsigned long pa;
- struct dma_seg_map *map = NULL;
- uint size, j, nsegs;
+ uint size;
pa = cpu_to_le32(di->txd64[i].addrlow) - di->dataoffsetlow;
- if (DMASGLIST_ENAB) {
- map = &di->txp_dmah[i];
- size = map->origsize;
- nsegs = map->nsegs;
- } else {
- size =
- (cpu_to_le32(di->txd64[i].ctrl2) &
- D64_CTRL2_BC_MASK);
- nsegs = 1;
- }
+ size =
+ (cpu_to_le32(di->txd64[i].ctrl2) &
+ D64_CTRL2_BC_MASK);
- for (j = nsegs; j > 0; j--) {
- di->txd64[i].addrlow = 0xdeadbeef;
- di->txd64[i].addrhigh = 0xdeadbeef;
+ di->txd64[i].addrlow = 0xdeadbeef;
+ di->txd64[i].addrhigh = 0xdeadbeef;
- txp = di->txp[i];
- di->txp[i] = NULL;
- if (j > 1)
- i = NEXTTXD(i);
- }
+ txp = di->txp[i];
+ di->txp[i] = NULL;
pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
}