Skip to content

Commit 55afc80

Browse files
committed
Revert "b43: Enforce DMA descriptor memory constraints"
This reverts commit 9bd568a. That commit is shown to cause allocation failures during initialization on some machines. http://bugzilla.kernel.org/show_bug.cgi?id=14844 Signed-off-by: John W. Linville <[email protected]>
1 parent 6c853da commit 55afc80

File tree

2 files changed

+46
-158
lines changed

2 files changed

+46
-158
lines changed

drivers/net/wireless/b43/dma.c

Lines changed: 45 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -383,160 +383,44 @@ static inline
383383
}
384384
}
385385

386-
/* Check if a DMA region fits the device constraints.
387-
* Returns true, if the region is OK for usage with this device. */
388-
static inline bool b43_dma_address_ok(struct b43_dmaring *ring,
389-
dma_addr_t addr, size_t size)
390-
{
391-
switch (ring->type) {
392-
case B43_DMA_30BIT:
393-
if ((u64)addr + size > (1ULL << 30))
394-
return 0;
395-
break;
396-
case B43_DMA_32BIT:
397-
if ((u64)addr + size > (1ULL << 32))
398-
return 0;
399-
break;
400-
case B43_DMA_64BIT:
401-
/* Currently we can't have addresses beyond
402-
* 64bit in the kernel. */
403-
break;
404-
}
405-
return 1;
406-
}
407-
408-
#define is_4k_aligned(addr) (((u64)(addr) & 0x0FFFull) == 0)
409-
#define is_8k_aligned(addr) (((u64)(addr) & 0x1FFFull) == 0)
410-
411-
static void b43_unmap_and_free_ringmem(struct b43_dmaring *ring, void *base,
412-
dma_addr_t dmaaddr, size_t size)
413-
{
414-
ssb_dma_unmap_single(ring->dev->dev, dmaaddr, size, DMA_TO_DEVICE);
415-
free_pages((unsigned long)base, get_order(size));
416-
}
417-
418-
static void * __b43_get_and_map_ringmem(struct b43_dmaring *ring,
419-
dma_addr_t *dmaaddr, size_t size,
420-
gfp_t gfp_flags)
421-
{
422-
void *base;
423-
424-
base = (void *)__get_free_pages(gfp_flags, get_order(size));
425-
if (!base)
426-
return NULL;
427-
memset(base, 0, size);
428-
*dmaaddr = ssb_dma_map_single(ring->dev->dev, base, size,
429-
DMA_TO_DEVICE);
430-
if (ssb_dma_mapping_error(ring->dev->dev, *dmaaddr)) {
431-
free_pages((unsigned long)base, get_order(size));
432-
return NULL;
433-
}
434-
435-
return base;
436-
}
437-
438-
static void * b43_get_and_map_ringmem(struct b43_dmaring *ring,
439-
dma_addr_t *dmaaddr, size_t size)
440-
{
441-
void *base;
442-
443-
base = __b43_get_and_map_ringmem(ring, dmaaddr, size,
444-
GFP_KERNEL);
445-
if (!base) {
446-
b43err(ring->dev->wl, "Failed to allocate or map pages "
447-
"for DMA ringmemory\n");
448-
return NULL;
449-
}
450-
if (!b43_dma_address_ok(ring, *dmaaddr, size)) {
451-
/* The memory does not fit our device constraints.
452-
* Retry with GFP_DMA set to get lower memory. */
453-
b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size);
454-
base = __b43_get_and_map_ringmem(ring, dmaaddr, size,
455-
GFP_KERNEL | GFP_DMA);
456-
if (!base) {
457-
b43err(ring->dev->wl, "Failed to allocate or map pages "
458-
"in the GFP_DMA region for DMA ringmemory\n");
459-
return NULL;
460-
}
461-
if (!b43_dma_address_ok(ring, *dmaaddr, size)) {
462-
b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size);
463-
b43err(ring->dev->wl, "Failed to allocate DMA "
464-
"ringmemory that fits device constraints\n");
465-
return NULL;
466-
}
467-
}
468-
/* We expect the memory to be 4k aligned, at least. */
469-
if (B43_WARN_ON(!is_4k_aligned(*dmaaddr))) {
470-
b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size);
471-
return NULL;
472-
}
473-
474-
return base;
475-
}
476-
477386
static int alloc_ringmemory(struct b43_dmaring *ring)
478387
{
479-
unsigned int required;
480-
void *base;
481-
dma_addr_t dmaaddr;
482-
483-
/* There are several requirements to the descriptor ring memory:
484-
* - The memory region needs to fit the address constraints for the
485-
* device (same as for frame buffers).
486-
* - For 30/32bit DMA devices, the descriptor ring must be 4k aligned.
487-
* - For 64bit DMA devices, the descriptor ring must be 8k aligned.
388+
gfp_t flags = GFP_KERNEL;
389+
390+
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
391+
* alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
392+
* has shown that 4K is sufficient for the latter as long as the buffer
393+
* does not cross an 8K boundary.
394+
*
395+
* For unknown reasons - possibly a hardware error - the BCM4311 rev
396+
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
397+
* which accounts for the GFP_DMA flag below.
398+
*
399+
* The flags here must match the flags in free_ringmemory below!
488400
*/
489-
490401
if (ring->type == B43_DMA_64BIT)
491-
required = ring->nr_slots * sizeof(struct b43_dmadesc64);
492-
else
493-
required = ring->nr_slots * sizeof(struct b43_dmadesc32);
494-
if (B43_WARN_ON(required > 0x1000))
402+
flags |= GFP_DMA;
403+
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
404+
B43_DMA_RINGMEMSIZE,
405+
&(ring->dmabase), flags);
406+
if (!ring->descbase) {
407+
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
495408
return -ENOMEM;
496-
497-
ring->alloc_descsize = 0x1000;
498-
base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize);
499-
if (!base)
500-
return -ENOMEM;
501-
ring->alloc_descbase = base;
502-
ring->alloc_dmabase = dmaaddr;
503-
504-
if ((ring->type != B43_DMA_64BIT) || is_8k_aligned(dmaaddr)) {
505-
/* We're on <=32bit DMA, or we already got 8k aligned memory.
506-
* That's all we need, so we're fine. */
507-
ring->descbase = base;
508-
ring->dmabase = dmaaddr;
509-
return 0;
510-
}
511-
b43_unmap_and_free_ringmem(ring, base, dmaaddr, ring->alloc_descsize);
512-
513-
/* Ok, we failed at the 8k alignment requirement.
514-
* Try to force-align the memory region now. */
515-
ring->alloc_descsize = 0x2000;
516-
base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize);
517-
if (!base)
518-
return -ENOMEM;
519-
ring->alloc_descbase = base;
520-
ring->alloc_dmabase = dmaaddr;
521-
522-
if (is_8k_aligned(dmaaddr)) {
523-
/* We're already 8k aligned. That Ok, too. */
524-
ring->descbase = base;
525-
ring->dmabase = dmaaddr;
526-
return 0;
527409
}
528-
/* Force-align it to 8k */
529-
ring->descbase = (void *)((u8 *)base + 0x1000);
530-
ring->dmabase = dmaaddr + 0x1000;
531-
B43_WARN_ON(!is_8k_aligned(ring->dmabase));
410+
memset(ring->descbase, 0, B43_DMA_RINGMEMSIZE);
532411

533412
return 0;
534413
}
535414

536415
static void free_ringmemory(struct b43_dmaring *ring)
537416
{
538-
b43_unmap_and_free_ringmem(ring, ring->alloc_descbase,
539-
ring->alloc_dmabase, ring->alloc_descsize);
417+
gfp_t flags = GFP_KERNEL;
418+
419+
if (ring->type == B43_DMA_64BIT)
420+
flags |= GFP_DMA;
421+
422+
ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
423+
ring->descbase, ring->dmabase, flags);
540424
}
541425

542426
/* Reset the RX DMA channel */
@@ -646,14 +530,29 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
646530
if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
647531
return 1;
648532

649-
if (!b43_dma_address_ok(ring, addr, buffersize)) {
650-
/* We can't support this address. Unmap it again. */
651-
unmap_descbuffer(ring, addr, buffersize, dma_to_device);
652-
return 1;
533+
switch (ring->type) {
534+
case B43_DMA_30BIT:
535+
if ((u64)addr + buffersize > (1ULL << 30))
536+
goto address_error;
537+
break;
538+
case B43_DMA_32BIT:
539+
if ((u64)addr + buffersize > (1ULL << 32))
540+
goto address_error;
541+
break;
542+
case B43_DMA_64BIT:
543+
/* Currently we can't have addresses beyond
544+
* 64bit in the kernel. */
545+
break;
653546
}
654547

655548
/* The address is OK. */
656549
return 0;
550+
551+
address_error:
552+
/* We can't support this address. Unmap it again. */
553+
unmap_descbuffer(ring, addr, buffersize, dma_to_device);
554+
555+
return 1;
657556
}
658557

659558
static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb)
@@ -715,9 +614,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
715614
meta->dmaaddr = dmaaddr;
716615
ring->ops->fill_descriptor(ring, desc, dmaaddr,
717616
ring->rx_buffersize, 0, 0, 0);
718-
ssb_dma_sync_single_for_device(ring->dev->dev,
719-
ring->alloc_dmabase,
720-
ring->alloc_descsize, DMA_TO_DEVICE);
721617

722618
return 0;
723619
}
@@ -1354,9 +1250,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
13541250
}
13551251
/* Now transfer the whole frame. */
13561252
wmb();
1357-
ssb_dma_sync_single_for_device(ring->dev->dev,
1358-
ring->alloc_dmabase,
1359-
ring->alloc_descsize, DMA_TO_DEVICE);
13601253
ops->poke_tx(ring, next_slot(ring, slot));
13611254
return 0;
13621255

drivers/net/wireless/b43/dma.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct b43_dmadesc_generic {
157157
} __attribute__ ((__packed__));
158158

159159
/* Misc DMA constants */
160+
#define B43_DMA_RINGMEMSIZE PAGE_SIZE
160161
#define B43_DMA0_RX_FRAMEOFFSET 30
161162

162163
/* DMA engine tuning knobs */
@@ -246,12 +247,6 @@ struct b43_dmaring {
246247
/* The QOS priority assigned to this ring. Only used for TX rings.
247248
* This is the mac80211 "queue" value. */
248249
u8 queue_prio;
249-
/* Pointers and size of the originally allocated and mapped memory
250-
* region for the descriptor ring. */
251-
void *alloc_descbase;
252-
dma_addr_t alloc_dmabase;
253-
unsigned int alloc_descsize;
254-
/* Pointer to our wireless device. */
255250
struct b43_wldev *dev;
256251
#ifdef CONFIG_B43_DEBUG
257252
/* Maximum number of used slots. */

0 commit comments

Comments
 (0)