Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
@@ -441,6 +441,8 @@ enum {
|
||||
#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
|
||||
#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
|
||||
|
||||
/* The firmware register that contains the watchdog counter. */
|
||||
#define B43_WATCHDOG_REG 1
|
||||
|
||||
/* Device specific rate values.
|
||||
* The actual values defined here are (rate_in_mbps * 2).
|
||||
|
@@ -74,6 +74,299 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
|
||||
} while (0)
|
||||
|
||||
|
||||
/* The biggest address values for SHM access from the debugfs files. */
|
||||
#define B43_MAX_SHM_ROUTING 4
|
||||
#define B43_MAX_SHM_ADDR 0xFFFF
|
||||
|
||||
static ssize_t shm16read__read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
unsigned int routing, addr;
|
||||
u16 val;
|
||||
|
||||
routing = dev->dfsentry->shm16read_routing_next;
|
||||
addr = dev->dfsentry->shm16read_addr_next;
|
||||
if ((routing > B43_MAX_SHM_ROUTING) ||
|
||||
(addr > B43_MAX_SHM_ADDR))
|
||||
return -EDESTADDRREQ;
|
||||
|
||||
val = b43_shm_read16(dev, routing, addr);
|
||||
fappend("0x%04X\n", val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int shm16read__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int routing, addr;
|
||||
int res;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
|
||||
if (res != 2)
|
||||
return -EINVAL;
|
||||
if (routing > B43_MAX_SHM_ROUTING)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (addr > B43_MAX_SHM_ADDR)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
if ((addr % 2) != 0)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
dev->dfsentry->shm16read_routing_next = routing;
|
||||
dev->dfsentry->shm16read_addr_next = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shm16write__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int routing, addr, mask, set;
|
||||
u16 val;
|
||||
int res;
|
||||
unsigned long flags;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
|
||||
&routing, &addr, &mask, &set);
|
||||
if (res != 4)
|
||||
return -EINVAL;
|
||||
if (routing > B43_MAX_SHM_ROUTING)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (addr > B43_MAX_SHM_ADDR)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
if ((addr % 2) != 0)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
if ((mask > 0xFFFF) || (set > 0xFFFF))
|
||||
return -E2BIG;
|
||||
|
||||
spin_lock_irqsave(&dev->wl->shm_lock, flags);
|
||||
if (mask == 0)
|
||||
val = 0;
|
||||
else
|
||||
val = __b43_shm_read16(dev, routing, addr);
|
||||
val &= mask;
|
||||
val |= set;
|
||||
__b43_shm_write16(dev, routing, addr, val);
|
||||
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t shm32read__read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
unsigned int routing, addr;
|
||||
u32 val;
|
||||
|
||||
routing = dev->dfsentry->shm32read_routing_next;
|
||||
addr = dev->dfsentry->shm32read_addr_next;
|
||||
if ((routing > B43_MAX_SHM_ROUTING) ||
|
||||
(addr > B43_MAX_SHM_ADDR))
|
||||
return -EDESTADDRREQ;
|
||||
|
||||
val = b43_shm_read32(dev, routing, addr);
|
||||
fappend("0x%08X\n", val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int shm32read__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int routing, addr;
|
||||
int res;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
|
||||
if (res != 2)
|
||||
return -EINVAL;
|
||||
if (routing > B43_MAX_SHM_ROUTING)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (addr > B43_MAX_SHM_ADDR)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
if ((addr % 2) != 0)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
dev->dfsentry->shm32read_routing_next = routing;
|
||||
dev->dfsentry->shm32read_addr_next = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shm32write__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int routing, addr, mask, set;
|
||||
u32 val;
|
||||
int res;
|
||||
unsigned long flags;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
|
||||
&routing, &addr, &mask, &set);
|
||||
if (res != 4)
|
||||
return -EINVAL;
|
||||
if (routing > B43_MAX_SHM_ROUTING)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (addr > B43_MAX_SHM_ADDR)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
if ((addr % 2) != 0)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
|
||||
return -E2BIG;
|
||||
|
||||
spin_lock_irqsave(&dev->wl->shm_lock, flags);
|
||||
if (mask == 0)
|
||||
val = 0;
|
||||
else
|
||||
val = __b43_shm_read32(dev, routing, addr);
|
||||
val &= mask;
|
||||
val |= set;
|
||||
__b43_shm_write32(dev, routing, addr, val);
|
||||
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The biggest MMIO address that we allow access to from the debugfs files. */
|
||||
#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
|
||||
|
||||
static ssize_t mmio16read__read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
unsigned int addr;
|
||||
u16 val;
|
||||
|
||||
addr = dev->dfsentry->mmio16read_next;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EDESTADDRREQ;
|
||||
|
||||
val = b43_read16(dev, addr);
|
||||
fappend("0x%04X\n", val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int mmio16read__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int addr;
|
||||
int res;
|
||||
|
||||
res = sscanf(buf, "0x%X", &addr);
|
||||
if (res != 1)
|
||||
return -EINVAL;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EADDRNOTAVAIL;
|
||||
if ((addr % 2) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev->dfsentry->mmio16read_next = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmio16write__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int addr, mask, set;
|
||||
int res;
|
||||
u16 val;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
|
||||
if (res != 3)
|
||||
return -EINVAL;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EADDRNOTAVAIL;
|
||||
if ((mask > 0xFFFF) || (set > 0xFFFF))
|
||||
return -E2BIG;
|
||||
if ((addr % 2) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (mask == 0)
|
||||
val = 0;
|
||||
else
|
||||
val = b43_read16(dev, addr);
|
||||
val &= mask;
|
||||
val |= set;
|
||||
b43_write16(dev, addr, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mmio32read__read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
unsigned int addr;
|
||||
u32 val;
|
||||
|
||||
addr = dev->dfsentry->mmio32read_next;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EDESTADDRREQ;
|
||||
|
||||
val = b43_read32(dev, addr);
|
||||
fappend("0x%08X\n", val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int mmio32read__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int addr;
|
||||
int res;
|
||||
|
||||
res = sscanf(buf, "0x%X", &addr);
|
||||
if (res != 1)
|
||||
return -EINVAL;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EADDRNOTAVAIL;
|
||||
if ((addr % 4) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev->dfsentry->mmio32read_next = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmio32write__write_file(struct b43_wldev *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int addr, mask, set;
|
||||
int res;
|
||||
u32 val;
|
||||
|
||||
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
|
||||
if (res != 3)
|
||||
return -EINVAL;
|
||||
if (addr > B43_MAX_MMIO_ACCESS)
|
||||
return -EADDRNOTAVAIL;
|
||||
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
|
||||
return -E2BIG;
|
||||
if ((addr % 4) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (mask == 0)
|
||||
val = 0;
|
||||
else
|
||||
val = b43_read32(dev, addr);
|
||||
val &= mask;
|
||||
val |= set;
|
||||
b43_write32(dev, addr, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wl->irq_lock is locked */
|
||||
static ssize_t tsf_read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
@@ -102,42 +395,6 @@ static int tsf_write_file(struct b43_wldev *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wl->irq_lock is locked */
|
||||
static ssize_t ucode_regs_read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
fappend("r%d = 0x%04x\n", i,
|
||||
b43_shm_read16(dev, B43_SHM_SCRATCH, i));
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* wl->irq_lock is locked */
|
||||
static ssize_t shm_read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
int i;
|
||||
u16 tmp;
|
||||
__le16 *le16buf = (__le16 *)buf;
|
||||
|
||||
for (i = 0; i < 0x1000; i++) {
|
||||
if (bufsize < sizeof(tmp))
|
||||
break;
|
||||
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
|
||||
le16buf[i] = cpu_to_le16(tmp);
|
||||
count += sizeof(tmp);
|
||||
bufsize -= sizeof(tmp);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t txstat_read_file(struct b43_wldev *dev,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
@@ -496,9 +753,15 @@ out_unlock:
|
||||
.take_irqlock = _take_irqlock, \
|
||||
}
|
||||
|
||||
B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
|
||||
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
|
||||
B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
|
||||
B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
|
||||
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
|
||||
B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
|
||||
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
|
||||
@@ -538,6 +801,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
|
||||
add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0);
|
||||
add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0);
|
||||
add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
|
||||
add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
|
||||
|
||||
#undef add_dyn_dbg
|
||||
}
|
||||
@@ -584,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
e->mmio16read_next = 0xFFFF; /* invalid address */
|
||||
e->mmio32read_next = 0xFFFF; /* invalid address */
|
||||
e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
|
||||
e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
|
||||
e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
|
||||
e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
|
||||
|
||||
#define ADD_FILE(name, mode) \
|
||||
do { \
|
||||
struct dentry *d; \
|
||||
@@ -596,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
|
||||
} while (0)
|
||||
|
||||
|
||||
ADD_FILE(shm16read, 0600);
|
||||
ADD_FILE(shm16write, 0200);
|
||||
ADD_FILE(shm32read, 0600);
|
||||
ADD_FILE(shm32write, 0200);
|
||||
ADD_FILE(mmio16read, 0600);
|
||||
ADD_FILE(mmio16write, 0200);
|
||||
ADD_FILE(mmio32read, 0600);
|
||||
ADD_FILE(mmio32write, 0200);
|
||||
ADD_FILE(tsf, 0600);
|
||||
ADD_FILE(ucode_regs, 0400);
|
||||
ADD_FILE(shm, 0400);
|
||||
ADD_FILE(txstat, 0400);
|
||||
ADD_FILE(txpower_g, 0600);
|
||||
ADD_FILE(restart, 0200);
|
||||
@@ -620,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
|
||||
return;
|
||||
b43_remove_dynamic_debug(dev);
|
||||
|
||||
debugfs_remove(e->file_shm16read.dentry);
|
||||
debugfs_remove(e->file_shm16write.dentry);
|
||||
debugfs_remove(e->file_shm32read.dentry);
|
||||
debugfs_remove(e->file_shm32write.dentry);
|
||||
debugfs_remove(e->file_mmio16read.dentry);
|
||||
debugfs_remove(e->file_mmio16write.dentry);
|
||||
debugfs_remove(e->file_mmio32read.dentry);
|
||||
debugfs_remove(e->file_mmio32write.dentry);
|
||||
debugfs_remove(e->file_tsf.dentry);
|
||||
debugfs_remove(e->file_ucode_regs.dentry);
|
||||
debugfs_remove(e->file_shm.dentry);
|
||||
debugfs_remove(e->file_txstat.dentry);
|
||||
debugfs_remove(e->file_txpower_g.dentry);
|
||||
debugfs_remove(e->file_restart.dentry);
|
||||
|
@@ -11,6 +11,7 @@ enum b43_dyndbg { /* Dynamic debugging features */
|
||||
B43_DBG_PWORK_FAST,
|
||||
B43_DBG_PWORK_STOP,
|
||||
B43_DBG_LO,
|
||||
B43_DBG_FIRMWARE,
|
||||
__B43_NR_DYNDBG,
|
||||
};
|
||||
|
||||
@@ -36,9 +37,15 @@ struct b43_dfsentry {
|
||||
struct b43_wldev *dev;
|
||||
struct dentry *subdir;
|
||||
|
||||
struct b43_dfs_file file_shm16read;
|
||||
struct b43_dfs_file file_shm16write;
|
||||
struct b43_dfs_file file_shm32read;
|
||||
struct b43_dfs_file file_shm32write;
|
||||
struct b43_dfs_file file_mmio16read;
|
||||
struct b43_dfs_file file_mmio16write;
|
||||
struct b43_dfs_file file_mmio32read;
|
||||
struct b43_dfs_file file_mmio32write;
|
||||
struct b43_dfs_file file_tsf;
|
||||
struct b43_dfs_file file_ucode_regs;
|
||||
struct b43_dfs_file file_shm;
|
||||
struct b43_dfs_file file_txstat;
|
||||
struct b43_dfs_file file_txpower_g;
|
||||
struct b43_dfs_file file_restart;
|
||||
@@ -46,6 +53,18 @@ struct b43_dfsentry {
|
||||
|
||||
struct b43_txstatus_log txstatlog;
|
||||
|
||||
/* The cached address for the next mmio16read file read */
|
||||
u16 mmio16read_next;
|
||||
/* The cached address for the next mmio32read file read */
|
||||
u16 mmio32read_next;
|
||||
|
||||
/* The cached address for the next shm16read file read */
|
||||
u32 shm16read_routing_next;
|
||||
u32 shm16read_addr_next;
|
||||
/* The cached address for the next shm32read file read */
|
||||
u32 shm32read_routing_next;
|
||||
u32 shm32read_addr_next;
|
||||
|
||||
/* Enabled/Disabled list for the dynamic debugging features. */
|
||||
u32 dyn_debug[__B43_NR_DYNDBG];
|
||||
/* Dentries for the dynamic debugging entries. */
|
||||
|
@@ -328,11 +328,11 @@ static inline
|
||||
dma_addr_t dmaaddr;
|
||||
|
||||
if (tx) {
|
||||
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
|
||||
buf, len, DMA_TO_DEVICE);
|
||||
dmaaddr = ssb_dma_map_single(ring->dev->dev,
|
||||
buf, len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
|
||||
buf, len, DMA_FROM_DEVICE);
|
||||
dmaaddr = ssb_dma_map_single(ring->dev->dev,
|
||||
buf, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
return dmaaddr;
|
||||
@@ -343,11 +343,11 @@ static inline
|
||||
dma_addr_t addr, size_t len, int tx)
|
||||
{
|
||||
if (tx) {
|
||||
dma_unmap_single(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_TO_DEVICE);
|
||||
ssb_dma_unmap_single(ring->dev->dev,
|
||||
addr, len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dma_unmap_single(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
ssb_dma_unmap_single(ring->dev->dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,8 +356,8 @@ static inline
|
||||
dma_addr_t addr, size_t len)
|
||||
{
|
||||
B43_WARN_ON(ring->tx);
|
||||
dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
ssb_dma_sync_single_for_cpu(ring->dev->dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -365,8 +365,8 @@ static inline
|
||||
dma_addr_t addr, size_t len)
|
||||
{
|
||||
B43_WARN_ON(ring->tx);
|
||||
dma_sync_single_for_device(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
ssb_dma_sync_single_for_device(ring->dev->dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -381,7 +381,6 @@ static inline
|
||||
|
||||
static int alloc_ringmemory(struct b43_dmaring *ring)
|
||||
{
|
||||
struct device *dma_dev = ring->dev->dev->dma_dev;
|
||||
gfp_t flags = GFP_KERNEL;
|
||||
|
||||
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
|
||||
@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
|
||||
* For unknown reasons - possibly a hardware error - the BCM4311 rev
|
||||
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
|
||||
* which accounts for the GFP_DMA flag below.
|
||||
*
|
||||
* The flags here must match the flags in free_ringmemory below!
|
||||
*/
|
||||
if (ring->type == B43_DMA_64BIT)
|
||||
flags |= GFP_DMA;
|
||||
ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
|
||||
&(ring->dmabase), flags);
|
||||
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
|
||||
B43_DMA_RINGMEMSIZE,
|
||||
&(ring->dmabase), flags);
|
||||
if (!ring->descbase) {
|
||||
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
|
||||
return -ENOMEM;
|
||||
@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
|
||||
|
||||
static void free_ringmemory(struct b43_dmaring *ring)
|
||||
{
|
||||
struct device *dma_dev = ring->dev->dev->dma_dev;
|
||||
gfp_t flags = GFP_KERNEL;
|
||||
|
||||
dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
|
||||
ring->descbase, ring->dmabase);
|
||||
if (ring->type == B43_DMA_64BIT)
|
||||
flags |= GFP_DMA;
|
||||
|
||||
ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
|
||||
ring->descbase, ring->dmabase, flags);
|
||||
}
|
||||
|
||||
/* Reset the RX DMA channel */
|
||||
@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
|
||||
dma_addr_t addr,
|
||||
size_t buffersize, bool dma_to_device)
|
||||
{
|
||||
if (unlikely(dma_mapping_error(addr)))
|
||||
if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
|
||||
return 1;
|
||||
|
||||
switch (ring->type) {
|
||||
@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
goto err_kfree_meta;
|
||||
|
||||
/* test for ability to dma to txhdr_cache */
|
||||
dma_test = dma_map_single(dev->dev->dma_dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
dma_test = ssb_dma_map_single(dev->dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
if (b43_dma_mapping_error(ring, dma_test,
|
||||
b43_txhdr_size(dev), 1)) {
|
||||
@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
if (!ring->txhdr_cache)
|
||||
goto err_kfree_meta;
|
||||
|
||||
dma_test = dma_map_single(dev->dev->dma_dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
dma_test = ssb_dma_map_single(dev->dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
if (b43_dma_mapping_error(ring, dma_test,
|
||||
b43_txhdr_size(dev), 1)) {
|
||||
@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
dma_unmap_single(dev->dev->dma_dev,
|
||||
dma_test, b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
ssb_dma_unmap_single(dev->dev,
|
||||
dma_test, b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
err = alloc_ringmemory(ring);
|
||||
|
@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
|
||||
b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
|
||||
}
|
||||
|
||||
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u32 ret;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
B43_WARN_ON(offset & 0x0001);
|
||||
if (offset & 0x0003) {
|
||||
@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
b43_shm_control_word(dev, routing, offset);
|
||||
ret = b43_read32(dev, B43_MMIO_SHM_DATA);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u32 ret;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
ret = __b43_shm_read32(dev, routing, offset);
|
||||
spin_unlock_irqrestore(&wl->shm_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
|
||||
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u16 ret;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
B43_WARN_ON(offset & 0x0001);
|
||||
if (offset & 0x0003) {
|
||||
@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
|
||||
b43_shm_control_word(dev, routing, offset);
|
||||
ret = b43_read16(dev, B43_MMIO_SHM_DATA);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u16 ret;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
ret = __b43_shm_read16(dev, routing, offset);
|
||||
spin_unlock_irqrestore(&wl->shm_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
|
||||
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
B43_WARN_ON(offset & 0x0001);
|
||||
if (offset & 0x0003) {
|
||||
@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
|
||||
(value >> 16) & 0xffff);
|
||||
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
|
||||
b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
offset >>= 2;
|
||||
}
|
||||
b43_shm_control_word(dev, routing, offset);
|
||||
b43_write32(dev, B43_MMIO_SHM_DATA, value);
|
||||
out:
|
||||
}
|
||||
|
||||
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
__b43_shm_write32(dev, routing, offset, value);
|
||||
spin_unlock_irqrestore(&wl->shm_lock, flags);
|
||||
}
|
||||
|
||||
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
|
||||
{
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
B43_WARN_ON(offset & 0x0001);
|
||||
if (offset & 0x0003) {
|
||||
/* Unaligned access */
|
||||
b43_shm_control_word(dev, routing, offset >> 2);
|
||||
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
|
||||
return;
|
||||
}
|
||||
offset >>= 2;
|
||||
}
|
||||
b43_shm_control_word(dev, routing, offset);
|
||||
b43_write16(dev, B43_MMIO_SHM_DATA, value);
|
||||
}
|
||||
|
||||
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&wl->shm_lock, flags);
|
||||
if (routing == B43_SHM_SHARED) {
|
||||
B43_WARN_ON(offset & 0x0001);
|
||||
if (offset & 0x0003) {
|
||||
/* Unaligned access */
|
||||
b43_shm_control_word(dev, routing, offset >> 2);
|
||||
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
|
||||
goto out;
|
||||
}
|
||||
offset >>= 2;
|
||||
}
|
||||
b43_shm_control_word(dev, routing, offset);
|
||||
b43_write16(dev, B43_MMIO_SHM_DATA, value);
|
||||
out:
|
||||
__b43_shm_write16(dev, routing, offset, value);
|
||||
spin_unlock_irqrestore(&wl->shm_lock, flags);
|
||||
}
|
||||
|
||||
@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
|
||||
/* http://bcm-specs.sipsolutions.net/EnableMac */
|
||||
void b43_mac_enable(struct b43_wldev *dev)
|
||||
{
|
||||
if (b43_debug(dev, B43_DBG_FIRMWARE)) {
|
||||
u16 fwstate;
|
||||
|
||||
fwstate = b43_shm_read16(dev, B43_SHM_SHARED,
|
||||
B43_SHM_SH_UCODESTAT);
|
||||
if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) &&
|
||||
(fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) {
|
||||
b43err(dev->wl, "b43_mac_enable(): The firmware "
|
||||
"should be suspended, but current state is %u\n",
|
||||
fwstate);
|
||||
}
|
||||
}
|
||||
|
||||
dev->mac_suspended--;
|
||||
B43_WARN_ON(dev->mac_suspended < 0);
|
||||
if (dev->mac_suspended == 0) {
|
||||
@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev)
|
||||
static void b43_periodic_every15sec(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u16 wdr;
|
||||
|
||||
if (dev->fw.opensource) {
|
||||
/* Check if the firmware is still alive.
|
||||
* It will reset the watchdog counter to 0 in its idle loop. */
|
||||
wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
|
||||
if (unlikely(wdr)) {
|
||||
b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
|
||||
b43_controller_restart(dev, "Firmware watchdog");
|
||||
return;
|
||||
} else {
|
||||
b43_shm_write16(dev, B43_SHM_SCRATCH,
|
||||
B43_WATCHDOG_REG, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
//TODO: update_aci_moving_average
|
||||
|
@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
|
||||
void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
|
||||
|
||||
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
|
||||
u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
|
||||
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
|
||||
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
|
||||
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
|
||||
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
|
||||
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
|
||||
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
|
||||
|
||||
u64 b43_hf_read(struct b43_wldev *dev);
|
||||
void b43_hf_write(struct b43_wldev *dev, u64 value);
|
||||
|
@@ -586,7 +586,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
|
||||
|
||||
spin_lock(&q->lock); /* IRQs are already disabled. */
|
||||
|
||||
info = (void *)pack->skb;
|
||||
info = IEEE80211_SKB_CB(pack->skb);
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
|
||||
b43_fill_txstatus_report(info, status);
|
||||
|
@@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
|
||||
goto out_unlock;
|
||||
err = 0;
|
||||
switch (state) {
|
||||
case RFKILL_STATE_ON:
|
||||
case RFKILL_STATE_UNBLOCKED:
|
||||
if (!dev->radio_hw_enable) {
|
||||
/* No luck. We can't toggle the hardware RF-kill
|
||||
* button from software. */
|
||||
@@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
|
||||
if (!dev->phy.radio_on)
|
||||
b43_radio_turn_on(dev);
|
||||
break;
|
||||
case RFKILL_STATE_OFF:
|
||||
case RFKILL_STATE_SOFT_BLOCKED:
|
||||
if (dev->phy.radio_on)
|
||||
b43_radio_turn_off(dev, 0);
|
||||
break;
|
||||
default:
|
||||
b43warn(wl, "Received unexpected rfkill state %d.\n", state);
|
||||
break;
|
||||
}
|
||||
out_unlock:
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
@@ -193,7 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||
const struct ieee80211_hdr *wlhdr =
|
||||
(const struct ieee80211_hdr *)fragment_data;
|
||||
int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
|
||||
u16 fctl = le16_to_cpu(wlhdr->frame_control);
|
||||
__le16 fctl = wlhdr->frame_control;
|
||||
struct ieee80211_rate *fbrate;
|
||||
u8 rate, rate_fb;
|
||||
int rate_ofdm, rate_fb_ofdm;
|
||||
@@ -259,7 +259,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||
B43_TXH_MAC_KEYIDX;
|
||||
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
|
||||
B43_TXH_MAC_KEYALG;
|
||||
wlhdr_len = ieee80211_get_hdrlen(fctl);
|
||||
wlhdr_len = ieee80211_hdrlen(fctl);
|
||||
iv_len = min((size_t) info->control.iv_len,
|
||||
ARRAY_SIZE(txhdr->iv));
|
||||
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
|
||||
@@ -317,8 +317,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||
/* MAC control */
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
mac_ctl |= B43_TXH_MAC_ACK;
|
||||
if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
|
||||
((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
|
||||
if (!ieee80211_is_pspoll(fctl))
|
||||
mac_ctl |= B43_TXH_MAC_HWSEQ;
|
||||
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
||||
mac_ctl |= B43_TXH_MAC_STMSDU;
|
||||
@@ -509,7 +508,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
struct b43_plcp_hdr6 *plcp;
|
||||
struct ieee80211_hdr *wlhdr;
|
||||
const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
|
||||
u16 fctl;
|
||||
__le16 fctl;
|
||||
u16 phystat0, phystat3, chanstat, mactime;
|
||||
u32 macstat;
|
||||
u16 chanid;
|
||||
@@ -549,7 +548,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
goto drop;
|
||||
}
|
||||
wlhdr = (struct ieee80211_hdr *)(skb->data);
|
||||
fctl = le16_to_cpu(wlhdr->frame_control);
|
||||
fctl = wlhdr->frame_control;
|
||||
|
||||
if (macstat & B43_RX_MAC_DEC) {
|
||||
unsigned int keyidx;
|
||||
@@ -564,7 +563,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
B43_WARN_ON(keyidx >= dev->max_nr_keys);
|
||||
|
||||
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
|
||||
wlhdr_len = ieee80211_get_hdrlen(fctl);
|
||||
wlhdr_len = ieee80211_hdrlen(fctl);
|
||||
if (unlikely(skb->len < (wlhdr_len + 3))) {
|
||||
b43dbg(dev->wl,
|
||||
"RX: Packet size underrun (3)\n");
|
||||
@@ -604,9 +603,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
* of timestamp, i.e. about 65 milliseconds after the PHY received
|
||||
* the first symbol.
|
||||
*/
|
||||
if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
|
||||
== (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
|
||||
dev->wl->radiotap_enabled) {
|
||||
if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
|
||||
u16 low_mactime_now;
|
||||
|
||||
b43_tsf_read(dev, &status.mactime);
|
||||
|
مرجع در شماره جدید
Block a user