static u64 supported_dma_mask(struct b43_wldev *dev) { u32 tmp; u16 mmio_base; switch (dev->dev->bus_type) { #ifdef CPTCFG_B43_BCMA case B43_BUS_BCMA: tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); if (tmp & BCMA_IOST_DMA64) return DMA_BIT_MASK(64); break; #endif #ifdef CPTCFG_B43_SSB case B43_BUS_SSB: tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); if (tmp & SSB_TMSHIGH_DMA64) return DMA_BIT_MASK(64); break; #endif } mmio_base = b43_dmacontroller_base(0, 0); b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK); tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL); if (tmp & B43_DMA32_TXADDREXT_MASK) return DMA_BIT_MASK(32); return DMA_BIT_MASK(30); }
/* Reset the TX DMA channel */ static int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, enum b43_dmatype type) { int i; u32 value; u16 offset; might_sleep(); for (i = 0; i < 10; i++) { offset = (type == B43_DMA_64BIT) ? B43_DMA64_TXSTATUS : B43_DMA32_TXSTATUS; value = b43_read32(dev, mmio_base + offset); if (type == B43_DMA_64BIT) { value &= B43_DMA64_TXSTAT; if (value == B43_DMA64_TXSTAT_DISABLED || value == B43_DMA64_TXSTAT_IDLEWAIT || value == B43_DMA64_TXSTAT_STOPPED) break; } else { value &= B43_DMA32_TXSTATE; if (value == B43_DMA32_TXSTAT_DISABLED || value == B43_DMA32_TXSTAT_IDLEWAIT || value == B43_DMA32_TXSTAT_STOPPED) break; } msleep(1); } offset = (type == B43_DMA_64BIT) ? B43_DMA64_TXCTL : B43_DMA32_TXCTL; b43_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { offset = (type == B43_DMA_64BIT) ? B43_DMA64_TXSTATUS : B43_DMA32_TXSTATUS; value = b43_read32(dev, mmio_base + offset); if (type == B43_DMA_64BIT) { value &= B43_DMA64_TXSTAT; if (value == B43_DMA64_TXSTAT_DISABLED) { i = -1; break; } } else { value &= B43_DMA32_TXSTATE; if (value == B43_DMA32_TXSTAT_DISABLED) { i = -1; break; } } msleep(1); } if (i != -1) { b43err(dev->wl, "DMA TX reset timed out\n"); return -ENODEV; } /* ensure the reset is completed. */ msleep(1); return 0; }
static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, u16 mmio_base, bool enable) { u32 ctl; if (type == B43_DMA_64BIT) { ctl = b43_read32(dev, mmio_base + B43_DMA64_RXCTL); ctl &= ~B43_DMA64_RXDIRECTFIFO; if (enable) ctl |= B43_DMA64_RXDIRECTFIFO; b43_write32(dev, mmio_base + B43_DMA64_RXCTL, ctl); } else { ctl = b43_read32(dev, mmio_base + B43_DMA32_RXCTL); ctl &= ~B43_DMA32_RXDIRECTFIFO; if (enable) ctl |= B43_DMA32_RXDIRECTFIFO; b43_write32(dev, mmio_base + B43_DMA32_RXCTL, ctl); } }
int b43_pio_init(struct b43_wldev *dev) { struct b43_pio *pio = &dev->pio; int err = -ENOMEM; b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) & ~B43_MACCTL_BE); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RXPADOFF, 0); pio->tx_queue_AC_BK = b43_setup_pioqueue_tx(dev, 0); if (!pio->tx_queue_AC_BK) goto out; pio->tx_queue_AC_BE = b43_setup_pioqueue_tx(dev, 1); if (!pio->tx_queue_AC_BE) goto err_destroy_bk; pio->tx_queue_AC_VI = b43_setup_pioqueue_tx(dev, 2); if (!pio->tx_queue_AC_VI) goto err_destroy_be; pio->tx_queue_AC_VO = b43_setup_pioqueue_tx(dev, 3); if (!pio->tx_queue_AC_VO) goto err_destroy_vi; pio->tx_queue_mcast = b43_setup_pioqueue_tx(dev, 4); if (!pio->tx_queue_mcast) goto err_destroy_vo; pio->rx_queue = b43_setup_pioqueue_rx(dev, 0); if (!pio->rx_queue) goto err_destroy_mcast; b43dbg(dev->wl, "PIO initialized\n"); err = 0; out: return err; err_destroy_mcast: destroy_queue_tx(pio, tx_queue_mcast); err_destroy_vo: destroy_queue_tx(pio, tx_queue_AC_VO); err_destroy_vi: destroy_queue_tx(pio, tx_queue_AC_VI); err_destroy_be: destroy_queue_tx(pio, tx_queue_AC_BE); err_destroy_bk: destroy_queue_tx(pio, tx_queue_AC_BK); return err; }
void b43_radio_unlock(struct b43_wldev *dev) { u32 macctl; #if B43_DEBUG B43_WARN_ON(!dev->phy.radio_locked); dev->phy.radio_locked = false; #endif /* Commit any write */ b43_read16(dev, B43_MMIO_PHY_VER); /* unlock */ macctl = b43_read32(dev, B43_MMIO_MACCTL); macctl &= ~B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); }
void b43_radio_lock(struct b43_wldev *dev) { u32 macctl; #if B43_DEBUG B43_WARN_ON(dev->phy.radio_locked); dev->phy.radio_locked = true; #endif macctl = b43_read32(dev, B43_MMIO_MACCTL); macctl |= B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit the write and wait for the firmware * to finish any radio register access. */ b43_read32(dev, B43_MMIO_MACCTL); udelay(10); }
/* Reset the RX DMA channel */ static int b43_dmacontroller_rx_reset(struct b43_wldev *dev, u16 mmio_base, enum b43_dmatype type) { int i; u32 value; u16 offset; might_sleep(); offset = (type == B43_DMA_64BIT) ? B43_DMA64_RXCTL : B43_DMA32_RXCTL; b43_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { offset = (type == B43_DMA_64BIT) ? B43_DMA64_RXSTATUS : B43_DMA32_RXSTATUS; value = b43_read32(dev, mmio_base + offset); if (type == B43_DMA_64BIT) { value &= B43_DMA64_RXSTAT; if (value == B43_DMA64_RXSTAT_DISABLED) { i = -1; break; } } else { value &= B43_DMA32_RXSTATE; if (value == B43_DMA32_RXSTAT_DISABLED) { i = -1; break; } } msleep(1); } if (i != -1) { b43err(dev->wl, "DMA RX reset timed out\n"); return -ENODEV; } return 0; }