提交 14599f1e 编写于 作者: D David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6

Conflicts:
	drivers/net/wireless/wl12xx/wl1271.h
	drivers/net/wireless/wl12xx/wl1271_cmd.h
...@@ -2978,7 +2978,6 @@ F: drivers/net/ixgb/ ...@@ -2978,7 +2978,6 @@ F: drivers/net/ixgb/
F: drivers/net/ixgbe/ F: drivers/net/ixgbe/
INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
M: Zhu Yi <yi.zhu@intel.com>
M: Reinette Chatre <reinette.chatre@intel.com> M: Reinette Chatre <reinette.chatre@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com> M: Intel Linux Wireless <ilw@linux.intel.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
...@@ -2988,7 +2987,6 @@ F: Documentation/networking/README.ipw2100 ...@@ -2988,7 +2987,6 @@ F: Documentation/networking/README.ipw2100
F: drivers/net/wireless/ipw2x00/ipw2100.* F: drivers/net/wireless/ipw2x00/ipw2100.*
INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
M: Zhu Yi <yi.zhu@intel.com>
M: Reinette Chatre <reinette.chatre@intel.com> M: Reinette Chatre <reinette.chatre@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com> M: Intel Linux Wireless <ilw@linux.intel.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
...@@ -3019,8 +3017,8 @@ F: drivers/net/wimax/i2400m/ ...@@ -3019,8 +3017,8 @@ F: drivers/net/wimax/i2400m/
F: include/linux/wimax/i2400m.h F: include/linux/wimax/i2400m.h
INTEL WIRELESS WIFI LINK (iwlwifi) INTEL WIRELESS WIFI LINK (iwlwifi)
M: Zhu Yi <yi.zhu@intel.com>
M: Reinette Chatre <reinette.chatre@intel.com> M: Reinette Chatre <reinette.chatre@intel.com>
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com> M: Intel Linux Wireless <ilw@linux.intel.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
W: http://intellinuxwireless.org W: http://intellinuxwireless.org
...@@ -3030,7 +3028,6 @@ F: drivers/net/wireless/iwlwifi/ ...@@ -3030,7 +3028,6 @@ F: drivers/net/wireless/iwlwifi/
INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi) INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi)
M: Samuel Ortiz <samuel.ortiz@intel.com> M: Samuel Ortiz <samuel.ortiz@intel.com>
M: Zhu Yi <yi.zhu@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com> M: Intel Linux Wireless <ilw@linux.intel.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
S: Supported S: Supported
......
...@@ -150,9 +150,8 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev, ...@@ -150,9 +150,8 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
unsigned long offset, unsigned long offset,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
ssb_dma_sync_single_range_for_device(sdev, dma_base, dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
offset & dma_desc_align_mask, dma_desc_sync_size, dir);
dma_desc_sync_size, dir);
} }
static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
...@@ -160,9 +159,8 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, ...@@ -160,9 +159,8 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
unsigned long offset, unsigned long offset,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
ssb_dma_sync_single_range_for_cpu(sdev, dma_base, dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
offset & dma_desc_align_mask, dma_desc_sync_size, dir);
dma_desc_sync_size, dir);
} }
static inline unsigned long br32(const struct b44 *bp, unsigned long reg) static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
...@@ -608,10 +606,10 @@ static void b44_tx(struct b44 *bp) ...@@ -608,10 +606,10 @@ static void b44_tx(struct b44 *bp)
BUG_ON(skb == NULL); BUG_ON(skb == NULL);
ssb_dma_unmap_single(bp->sdev, dma_unmap_single(bp->sdev->dma_dev,
rp->mapping, rp->mapping,
skb->len, skb->len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
rp->skb = NULL; rp->skb = NULL;
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
...@@ -648,29 +646,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -648,29 +646,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
mapping = ssb_dma_map_single(bp->sdev, skb->data, mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
/* Hardware bug work-around, the chip is unable to do PCI DMA /* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */ to/from anything above 1GB :-( */
if (ssb_dma_mapping_error(bp->sdev, mapping) || if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) { mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
/* Sigh... */ /* Sigh... */
if (!ssb_dma_mapping_error(bp->sdev, mapping)) if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, dma_unmap_single(bp->sdev->dma_dev, mapping,
RX_PKT_BUF_SZ, DMA_FROM_DEVICE); RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
mapping = ssb_dma_map_single(bp->sdev, skb->data, mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) || if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) { mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
if (!ssb_dma_mapping_error(bp->sdev, mapping)) if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE); dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -ENOMEM; return -ENOMEM;
} }
...@@ -745,9 +743,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -745,9 +743,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_idx * sizeof(*dest_desc), dest_idx * sizeof(*dest_desc),
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping, dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
} }
static int b44_rx(struct b44 *bp, int budget) static int b44_rx(struct b44 *bp, int budget)
...@@ -767,9 +765,9 @@ static int b44_rx(struct b44 *bp, int budget) ...@@ -767,9 +765,9 @@ static int b44_rx(struct b44 *bp, int budget)
struct rx_header *rh; struct rx_header *rh;
u16 len; u16 len;
ssb_dma_sync_single_for_cpu(bp->sdev, map, dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
rh = (struct rx_header *) skb->data; rh = (struct rx_header *) skb->data;
len = le16_to_cpu(rh->len); len = le16_to_cpu(rh->len);
if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) || if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
...@@ -801,8 +799,8 @@ static int b44_rx(struct b44 *bp, int budget) ...@@ -801,8 +799,8 @@ static int b44_rx(struct b44 *bp, int budget)
skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
if (skb_size < 0) if (skb_size < 0)
goto drop_it; goto drop_it;
ssb_dma_unmap_single(bp->sdev, map, dma_unmap_single(bp->sdev->dma_dev, map,
skb_size, DMA_FROM_DEVICE); skb_size, DMA_FROM_DEVICE);
/* Leave out rx_header */ /* Leave out rx_header */
skb_put(skb, len + RX_PKT_OFFSET); skb_put(skb, len + RX_PKT_OFFSET);
skb_pull(skb, RX_PKT_OFFSET); skb_pull(skb, RX_PKT_OFFSET);
...@@ -954,24 +952,24 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -954,24 +952,24 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto err_out; goto err_out;
} }
mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE); mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) { if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
struct sk_buff *bounce_skb; struct sk_buff *bounce_skb;
/* Chip can't handle DMA to/from >1GB, use bounce buffer */ /* Chip can't handle DMA to/from >1GB, use bounce buffer */
if (!ssb_dma_mapping_error(bp->sdev, mapping)) if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, len, dma_unmap_single(bp->sdev->dma_dev, mapping, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA); bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) if (!bounce_skb)
goto err_out; goto err_out;
mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data, mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
len, DMA_TO_DEVICE); len, DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) { if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
if (!ssb_dma_mapping_error(bp->sdev, mapping)) if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, dma_unmap_single(bp->sdev->dma_dev, mapping,
len, DMA_TO_DEVICE); len, DMA_TO_DEVICE);
dev_kfree_skb_any(bounce_skb); dev_kfree_skb_any(bounce_skb);
goto err_out; goto err_out;
...@@ -1068,8 +1066,8 @@ static void b44_free_rings(struct b44 *bp) ...@@ -1068,8 +1066,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL) if (rp->skb == NULL)
continue; continue;
ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ, dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
dev_kfree_skb_any(rp->skb); dev_kfree_skb_any(rp->skb);
rp->skb = NULL; rp->skb = NULL;
} }
...@@ -1080,8 +1078,8 @@ static void b44_free_rings(struct b44 *bp) ...@@ -1080,8 +1078,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL) if (rp->skb == NULL)
continue; continue;
ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len, dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
dev_kfree_skb_any(rp->skb); dev_kfree_skb_any(rp->skb);
rp->skb = NULL; rp->skb = NULL;
} }
...@@ -1103,14 +1101,12 @@ static void b44_init_rings(struct b44 *bp) ...@@ -1103,14 +1101,12 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->tx_ring, 0, B44_TX_RING_BYTES); memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
if (bp->flags & B44_FLAG_RX_RING_HACK) if (bp->flags & B44_FLAG_RX_RING_HACK)
ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma, dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
DMA_TABLE_BYTES, DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
DMA_BIDIRECTIONAL);
if (bp->flags & B44_FLAG_TX_RING_HACK) if (bp->flags & B44_FLAG_TX_RING_HACK)
ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma, dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
DMA_TABLE_BYTES, DMA_TABLE_BYTES, DMA_TO_DEVICE);
DMA_TO_DEVICE);
for (i = 0; i < bp->rx_pending; i++) { for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0) if (b44_alloc_rx_skb(bp, -1, i) < 0)
...@@ -1130,27 +1126,23 @@ static void b44_free_consistent(struct b44 *bp) ...@@ -1130,27 +1126,23 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL; bp->tx_buffers = NULL;
if (bp->rx_ring) { if (bp->rx_ring) {
if (bp->flags & B44_FLAG_RX_RING_HACK) { if (bp->flags & B44_FLAG_RX_RING_HACK) {
ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma, dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
DMA_TABLE_BYTES, DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
DMA_BIDIRECTIONAL);
kfree(bp->rx_ring); kfree(bp->rx_ring);
} else } else
ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma, bp->rx_ring, bp->rx_ring_dma);
GFP_KERNEL);
bp->rx_ring = NULL; bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK; bp->flags &= ~B44_FLAG_RX_RING_HACK;
} }
if (bp->tx_ring) { if (bp->tx_ring) {
if (bp->flags & B44_FLAG_TX_RING_HACK) { if (bp->flags & B44_FLAG_TX_RING_HACK) {
ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma, dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
DMA_TABLE_BYTES, DMA_TABLE_BYTES, DMA_TO_DEVICE);
DMA_TO_DEVICE);
kfree(bp->tx_ring); kfree(bp->tx_ring);
} else } else
ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma, bp->tx_ring, bp->tx_ring_dma);
GFP_KERNEL);
bp->tx_ring = NULL; bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK; bp->flags &= ~B44_FLAG_TX_RING_HACK;
} }
...@@ -1175,7 +1167,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1175,7 +1167,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
goto out_err; goto out_err;
size = DMA_TABLE_BYTES; size = DMA_TABLE_BYTES;
bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp); bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
&bp->rx_ring_dma, gfp);
if (!bp->rx_ring) { if (!bp->rx_ring) {
/* Allocation may have failed due to pci_alloc_consistent /* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive insisting on use of GFP_DMA, which is more restrictive
...@@ -1187,11 +1180,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1187,11 +1180,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!rx_ring) if (!rx_ring)
goto out_err; goto out_err;
rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring, rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) || if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
rx_ring_dma + size > DMA_BIT_MASK(30)) { rx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(rx_ring); kfree(rx_ring);
goto out_err; goto out_err;
...@@ -1202,7 +1195,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1202,7 +1195,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
bp->flags |= B44_FLAG_RX_RING_HACK; bp->flags |= B44_FLAG_RX_RING_HACK;
} }
bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp); bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
&bp->tx_ring_dma, gfp);
if (!bp->tx_ring) { if (!bp->tx_ring) {
/* Allocation may have failed due to ssb_dma_alloc_consistent /* Allocation may have failed due to ssb_dma_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive insisting on use of GFP_DMA, which is more restrictive
...@@ -1214,11 +1208,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1214,11 +1208,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!tx_ring) if (!tx_ring)
goto out_err; goto out_err;
tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring, tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) || if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||
tx_ring_dma + size > DMA_BIT_MASK(30)) { tx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(tx_ring); kfree(tx_ring);
goto out_err; goto out_err;
...@@ -2176,12 +2170,14 @@ static int __devinit b44_init_one(struct ssb_device *sdev, ...@@ -2176,12 +2170,14 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
"Failed to powerup the bus\n"); "Failed to powerup the bus\n");
goto err_out_free_dev; goto err_out_free_dev;
} }
err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30));
if (err) { if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) ||
dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) {
dev_err(sdev->dev, dev_err(sdev->dev,
"Required 30BIT DMA mask unsupported by the system\n"); "Required 30BIT DMA mask unsupported by the system\n");
goto err_out_powerdown; goto err_out_powerdown;
} }
err = b44_get_invariants(bp); err = b44_get_invariants(bp);
if (err) { if (err) {
dev_err(sdev->dev, dev_err(sdev->dev,
......
...@@ -13,5 +13,6 @@ ath5k-y += base.o ...@@ -13,5 +13,6 @@ ath5k-y += base.o
ath5k-y += led.o ath5k-y += led.o
ath5k-y += rfkill.o ath5k-y += rfkill.o
ath5k-y += ani.o ath5k-y += ani.o
ath5k-y += sysfs.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o obj-$(CONFIG_ATH5K) += ath5k.o
...@@ -74,8 +74,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) ...@@ -74,8 +74,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
const s8 fr[] = { -78, -80 }; const s8 fr[] = { -78, -80 };
#endif #endif
if (level < 0 || level >= ARRAY_SIZE(sz)) { if (level < 0 || level >= ARRAY_SIZE(sz)) {
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
"level out of range %d", level); level);
return; return;
} }
...@@ -106,8 +106,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) ...@@ -106,8 +106,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
if (level < 0 || level >= ARRAY_SIZE(val) || if (level < 0 || level >= ARRAY_SIZE(val) ||
level > ah->ah_sc->ani_state.max_spur_level) { level > ah->ah_sc->ani_state.max_spur_level) {
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, ATH5K_ERR(ah->ah_sc, "spur immunity level %d out of range",
"level out of range %d", level); level);
return; return;
} }
...@@ -130,8 +130,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) ...@@ -130,8 +130,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
const int val[] = { 0, 4, 8 }; const int val[] = { 0, 4, 8 };
if (level < 0 || level >= ARRAY_SIZE(val)) { if (level < 0 || level >= ARRAY_SIZE(val)) {
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
"level out of range %d", level);
return; return;
} }
...@@ -481,14 +480,15 @@ ath5k_ani_calibration(struct ath5k_hw *ah) ...@@ -481,14 +480,15 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
struct ath5k_ani_state *as = &ah->ah_sc->ani_state; struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
int listen, ofdm_high, ofdm_low, cck_high, cck_low; int listen, ofdm_high, ofdm_low, cck_high, cck_low;
if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
return;
/* get listen time since last call and add it to the counter because we /* get listen time since last call and add it to the counter because we
* might not have restarted the "ani period" last time */ * might not have restarted the "ani period" last time.
* always do this to calculate the busy time also in manual mode */
listen = ath5k_hw_ani_get_listen_time(ah, as); listen = ath5k_hw_ani_get_listen_time(ah, as);
as->listen_time += listen; as->listen_time += listen;
if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
return;
ath5k_ani_save_and_clear_phy_errors(ah, as); ath5k_ani_save_and_clear_phy_errors(ah, as);
ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000;
......
...@@ -204,6 +204,7 @@ ...@@ -204,6 +204,7 @@
#define AR5K_TUNE_TPC_TXPOWER false #define AR5K_TUNE_TPC_TXPOWER false
#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */ #define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */
#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
#define AR5K_INIT_CARR_SENSE_EN 1 #define AR5K_INIT_CARR_SENSE_EN 1
...@@ -1118,6 +1119,7 @@ struct ath5k_hw { ...@@ -1118,6 +1119,7 @@ struct ath5k_hw {
/* Calibration timestamp */ /* Calibration timestamp */
unsigned long ah_cal_next_full; unsigned long ah_cal_next_full;
unsigned long ah_cal_next_ani; unsigned long ah_cal_next_ani;
unsigned long ah_cal_next_nf;
/* Calibration mask */ /* Calibration mask */
u8 ah_cal_mask; u8 ah_cal_mask;
...@@ -1148,6 +1150,9 @@ struct ath5k_hw { ...@@ -1148,6 +1150,9 @@ struct ath5k_hw {
int ath5k_hw_attach(struct ath5k_softc *sc); int ath5k_hw_attach(struct ath5k_softc *sc);
void ath5k_hw_detach(struct ath5k_hw *ah); void ath5k_hw_detach(struct ath5k_hw *ah);
int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
/* LED functions */ /* LED functions */
int ath5k_init_leds(struct ath5k_softc *sc); int ath5k_init_leds(struct ath5k_softc *sc);
void ath5k_led_enable(struct ath5k_softc *sc); void ath5k_led_enable(struct ath5k_softc *sc);
...@@ -1270,6 +1275,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); ...@@ -1270,6 +1275,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
struct ieee80211_channel *channel); struct ieee80211_channel *channel);
void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
/* Spur mitigation */ /* Spur mitigation */
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
struct ieee80211_channel *channel); struct ieee80211_channel *channel);
...@@ -1280,6 +1286,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); ...@@ -1280,6 +1286,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
int ath5k_hw_phy_disable(struct ath5k_hw *ah); int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Antenna control */ /* Antenna control */
void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
/* TX power setup */ /* TX power setup */
int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
u8 ee_mode, u8 txpower); u8 ee_mode, u8 txpower);
......
...@@ -351,8 +351,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ...@@ -351,8 +351,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
*/ */
void ath5k_hw_detach(struct ath5k_hw *ah) void ath5k_hw_detach(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
__set_bit(ATH_STAT_INVALID, ah->ah_sc->status); __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
if (ah->ah_rf_banks != NULL) if (ah->ah_rf_banks != NULL)
......
...@@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = { ...@@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = {
static int __devinit ath5k_pci_probe(struct pci_dev *pdev, static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id); const struct pci_device_id *id);
static void __devexit ath5k_pci_remove(struct pci_dev *pdev); static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int ath5k_pci_suspend(struct device *dev); static int ath5k_pci_suspend(struct device *dev);
static int ath5k_pci_resume(struct device *dev); static int ath5k_pci_resume(struct device *dev);
...@@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); ...@@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
#define ATH5K_PM_OPS (&ath5k_pm_ops) #define ATH5K_PM_OPS (&ath5k_pm_ops)
#else #else
#define ATH5K_PM_OPS NULL #define ATH5K_PM_OPS NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM_SLEEP */
static struct pci_driver ath5k_pci_driver = { static struct pci_driver ath5k_pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
...@@ -578,7 +578,7 @@ ath5k_pci_probe(struct pci_dev *pdev, ...@@ -578,7 +578,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
spin_lock_init(&sc->block); spin_lock_init(&sc->block);
/* Set private data */ /* Set private data */
pci_set_drvdata(pdev, hw); pci_set_drvdata(pdev, sc);
/* Setup interrupt handler */ /* Setup interrupt handler */
ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
...@@ -694,25 +694,23 @@ ath5k_pci_probe(struct pci_dev *pdev, ...@@ -694,25 +694,23 @@ ath5k_pci_probe(struct pci_dev *pdev,
static void __devexit static void __devexit
ath5k_pci_remove(struct pci_dev *pdev) ath5k_pci_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath5k_softc *sc = pci_get_drvdata(pdev);
struct ath5k_softc *sc = hw->priv;
ath5k_debug_finish_device(sc); ath5k_debug_finish_device(sc);
ath5k_detach(pdev, hw); ath5k_detach(pdev, sc->hw);
ath5k_hw_detach(sc->ah); ath5k_hw_detach(sc->ah);
kfree(sc->ah); kfree(sc->ah);
free_irq(pdev->irq, sc); free_irq(pdev->irq, sc);
pci_iounmap(pdev, sc->iobase); pci_iounmap(pdev, sc->iobase);
pci_release_region(pdev, 0); pci_release_region(pdev, 0);
pci_disable_device(pdev); pci_disable_device(pdev);
ieee80211_free_hw(hw); ieee80211_free_hw(sc->hw);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int ath5k_pci_suspend(struct device *dev) static int ath5k_pci_suspend(struct device *dev)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
struct ath5k_softc *sc = hw->priv;
ath5k_led_off(sc); ath5k_led_off(sc);
return 0; return 0;
...@@ -721,8 +719,7 @@ static int ath5k_pci_suspend(struct device *dev) ...@@ -721,8 +719,7 @@ static int ath5k_pci_suspend(struct device *dev)
static int ath5k_pci_resume(struct device *dev) static int ath5k_pci_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath5k_softc *sc = pci_get_drvdata(pdev);
struct ath5k_softc *sc = hw->priv;
/* /*
* Suspend/Resume resets the PCI configuration space, so we have to * Suspend/Resume resets the PCI configuration space, so we have to
...@@ -734,7 +731,7 @@ static int ath5k_pci_resume(struct device *dev) ...@@ -734,7 +731,7 @@ static int ath5k_pci_resume(struct device *dev)
ath5k_led_enable(sc); ath5k_led_enable(sc);
return 0; return 0;
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM_SLEEP */
/***********************\ /***********************\
...@@ -864,6 +861,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -864,6 +861,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_init_leds(sc); ath5k_init_leds(sc);
ath5k_sysfs_register(sc);
return 0; return 0;
err_queues: err_queues:
ath5k_txq_release(sc); ath5k_txq_release(sc);
...@@ -899,6 +898,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -899,6 +898,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
ath5k_unregister_leds(sc); ath5k_unregister_leds(sc);
ath5k_sysfs_unregister(sc);
/* /*
* NB: can't reclaim these until after ieee80211_ifdetach * NB: can't reclaim these until after ieee80211_ifdetach
* returns because we'll get called back to reclaim node * returns because we'll get called back to reclaim node
...@@ -2785,10 +2785,6 @@ ath5k_tasklet_calibrate(unsigned long data) ...@@ -2785,10 +2785,6 @@ ath5k_tasklet_calibrate(unsigned long data)
/* Only full calibration for now */ /* Only full calibration for now */
ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
/* Stop queues so that calibration
* doesn't interfere with tx */
ieee80211_stop_queues(sc->hw);
ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
ieee80211_frequency_to_channel(sc->curchan->center_freq), ieee80211_frequency_to_channel(sc->curchan->center_freq),
sc->curchan->hw_value); sc->curchan->hw_value);
...@@ -2806,8 +2802,16 @@ ath5k_tasklet_calibrate(unsigned long data) ...@@ -2806,8 +2802,16 @@ ath5k_tasklet_calibrate(unsigned long data)
ieee80211_frequency_to_channel( ieee80211_frequency_to_channel(
sc->curchan->center_freq)); sc->curchan->center_freq));
/* Wake queues */ /* Noise floor calibration interrupts rx/tx path while I/Q calibration
ieee80211_wake_queues(sc->hw); * doesn't. We stop the queues so that calibration doesn't interfere
* with TX and don't run it as often */
if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) {
ah->ah_cal_next_nf = jiffies +
msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF);
ieee80211_stop_queues(sc->hw);
ath5k_hw_update_noise_floor(ah);
ieee80211_wake_queues(sc->hw);
}
ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
} }
...@@ -2926,6 +2930,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ...@@ -2926,6 +2930,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
ah->ah_cal_next_full = jiffies;
ah->ah_cal_next_ani = jiffies;
ah->ah_cal_next_nf = jiffies;
/* /*
* Change channels and update the h/w rate map if we're switching; * Change channels and update the h/w rate map if we're switching;
* e.g. 11a to 11b/g. * e.g. 11a to 11b/g.
...@@ -3140,13 +3148,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, ...@@ -3140,13 +3148,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
if (*new_flags & FIF_PROMISC_IN_BSS) { if (*new_flags & FIF_PROMISC_IN_BSS) {
rfilt |= AR5K_RX_FILTER_PROM;
__set_bit(ATH_STAT_PROMISC, sc->status); __set_bit(ATH_STAT_PROMISC, sc->status);
} else { } else {
__clear_bit(ATH_STAT_PROMISC, sc->status); __clear_bit(ATH_STAT_PROMISC, sc->status);
} }
} }
if (test_bit(ATH_STAT_PROMISC, sc->status))
rfilt |= AR5K_RX_FILTER_PROM;
/* Note, AR5K_RX_FILTER_MCAST is already enabled */ /* Note, AR5K_RX_FILTER_MCAST is already enabled */
if (*new_flags & FIF_ALLMULTI) { if (*new_flags & FIF_ALLMULTI) {
mfilt[0] = ~0; mfilt[0] = ~0;
......
...@@ -34,7 +34,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) ...@@ -34,7 +34,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
{ {
u16 ee_header; u16 ee_header;
ATH5K_TRACE(ah->ah_sc);
/* Capabilities stored in the EEPROM */ /* Capabilities stored in the EEPROM */
ee_header = ah->ah_capabilities.cap_eeprom.ee_header; ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
...@@ -123,8 +122,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah, ...@@ -123,8 +122,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
enum ath5k_capability_type cap_type, enum ath5k_capability_type cap_type,
u32 capability, u32 *result) u32 capability, u32 *result)
{ {
ATH5K_TRACE(ah->ah_sc);
switch (cap_type) { switch (cap_type) {
case AR5K_CAP_NUM_TXQUEUES: case AR5K_CAP_NUM_TXQUEUES:
if (result) { if (result) {
...@@ -173,8 +170,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah, ...@@ -173,8 +170,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
u16 assoc_id) u16 assoc_id)
{ {
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_version == AR5K_AR5210) { if (ah->ah_version == AR5K_AR5210) {
AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
...@@ -186,8 +181,6 @@ int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, ...@@ -186,8 +181,6 @@ int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_version == AR5K_AR5210) { if (ah->ah_version == AR5K_AR5210) {
AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
......
...@@ -307,7 +307,6 @@ static const struct { ...@@ -307,7 +307,6 @@ static const struct {
{ ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
{ ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
}; };
...@@ -426,6 +425,13 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf, ...@@ -426,6 +425,13 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
"AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
(v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
len += snprintf(buf+len, sizeof(buf)-len,
"\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
len += snprintf(buf+len, sizeof(buf)-len,
"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -729,6 +735,66 @@ static const struct file_operations fops_ani = { ...@@ -729,6 +735,66 @@ static const struct file_operations fops_ani = {
}; };
/* debugfs: queues etc */
static ssize_t read_file_queue(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath5k_softc *sc = file->private_data;
char buf[700];
unsigned int len = 0;
struct ath5k_txq *txq;
struct ath5k_buf *bf, *bf0;
int i, n = 0;
len += snprintf(buf+len, sizeof(buf)-len,
"available txbuffers: %d\n", sc->txbuf_len);
for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
txq = &sc->txqs[i];
len += snprintf(buf+len, sizeof(buf)-len,
"%02d: %ssetup\n", i, txq->setup ? "" : "not ");
if (!txq->setup)
continue;
list_for_each_entry_safe(bf, bf0, &txq->q, list)
n++;
len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n);
}
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_queue(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ath5k_softc *sc = file->private_data;
char buf[20];
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
return -EFAULT;
if (strncmp(buf, "start", 5) == 0)
ieee80211_wake_queues(sc->hw);
else if (strncmp(buf, "stop", 4) == 0)
ieee80211_stop_queues(sc->hw);
return count;
}
static const struct file_operations fops_queue = {
.read = read_file_queue,
.write = write_file_queue,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
};
/* init */ /* init */
void void
...@@ -772,6 +838,11 @@ ath5k_debug_init_device(struct ath5k_softc *sc) ...@@ -772,6 +838,11 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
S_IWUSR | S_IRUSR, S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc, sc->debug.debugfs_phydir, sc,
&fops_ani); &fops_ani);
sc->debug.debugfs_queue = debugfs_create_file("queue",
S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc,
&fops_queue);
} }
void void
...@@ -790,6 +861,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) ...@@ -790,6 +861,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
debugfs_remove(sc->debug.debugfs_antenna); debugfs_remove(sc->debug.debugfs_antenna);
debugfs_remove(sc->debug.debugfs_frameerrors); debugfs_remove(sc->debug.debugfs_frameerrors);
debugfs_remove(sc->debug.debugfs_ani); debugfs_remove(sc->debug.debugfs_ani);
debugfs_remove(sc->debug.debugfs_queue);
debugfs_remove(sc->debug.debugfs_phydir); debugfs_remove(sc->debug.debugfs_phydir);
} }
......
...@@ -77,6 +77,7 @@ struct ath5k_dbg_info { ...@@ -77,6 +77,7 @@ struct ath5k_dbg_info {
struct dentry *debugfs_antenna; struct dentry *debugfs_antenna;
struct dentry *debugfs_frameerrors; struct dentry *debugfs_frameerrors;
struct dentry *debugfs_ani; struct dentry *debugfs_ani;
struct dentry *debugfs_queue;
}; };
/** /**
...@@ -115,18 +116,12 @@ enum ath5k_debug_level { ...@@ -115,18 +116,12 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_RX = 0x00000100, ATH5K_DEBUG_DUMP_RX = 0x00000100,
ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_DUMPBANDS = 0x00000400,
ATH5K_DEBUG_TRACE = 0x00001000,
ATH5K_DEBUG_ANI = 0x00002000, ATH5K_DEBUG_ANI = 0x00002000,
ATH5K_DEBUG_ANY = 0xffffffff ATH5K_DEBUG_ANY = 0xffffffff
}; };
#ifdef CONFIG_ATH5K_DEBUG #ifdef CONFIG_ATH5K_DEBUG
#define ATH5K_TRACE(_sc) do { \
if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
} while (0)
#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \ #define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \ if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \ ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
...@@ -168,8 +163,6 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); ...@@ -168,8 +163,6 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
#include <linux/compiler.h> #include <linux/compiler.h>
#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
static inline void __attribute__ ((format (printf, 3, 4))) static inline void __attribute__ ((format (printf, 3, 4)))
ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
......
...@@ -176,7 +176,6 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, ...@@ -176,7 +176,6 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_4w_tx_ctl *tx_ctl;
unsigned int frame_len; unsigned int frame_len;
ATH5K_TRACE(ah->ah_sc);
tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
/* /*
...@@ -342,8 +341,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, ...@@ -342,8 +341,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
struct ath5k_hw_2w_tx_ctl *tx_ctl; struct ath5k_hw_2w_tx_ctl *tx_ctl;
struct ath5k_hw_tx_status *tx_status; struct ath5k_hw_tx_status *tx_status;
ATH5K_TRACE(ah->ah_sc);
tx_ctl = &desc->ud.ds_tx5210.tx_ctl; tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
tx_status = &desc->ud.ds_tx5210.tx_stat; tx_status = &desc->ud.ds_tx5210.tx_stat;
...@@ -396,8 +393,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ...@@ -396,8 +393,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_4w_tx_ctl *tx_ctl;
struct ath5k_hw_tx_status *tx_status; struct ath5k_hw_tx_status *tx_status;
ATH5K_TRACE(ah->ah_sc);
tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
tx_status = &desc->ud.ds_tx5212.tx_stat; tx_status = &desc->ud.ds_tx5212.tx_stat;
...@@ -490,7 +485,6 @@ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, ...@@ -490,7 +485,6 @@ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
{ {
struct ath5k_hw_rx_ctl *rx_ctl; struct ath5k_hw_rx_ctl *rx_ctl;
ATH5K_TRACE(ah->ah_sc);
rx_ctl = &desc->ud.ds_rx.rx_ctl; rx_ctl = &desc->ud.ds_rx.rx_ctl;
/* /*
...@@ -593,7 +587,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, ...@@ -593,7 +587,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
struct ath5k_hw_rx_status *rx_status; struct ath5k_hw_rx_status *rx_status;
struct ath5k_hw_rx_error *rx_err; struct ath5k_hw_rx_error *rx_err;
ATH5K_TRACE(ah->ah_sc);
rx_status = &desc->ud.ds_rx.u.rx_stat; rx_status = &desc->ud.ds_rx.u.rx_stat;
/* Overlay on error */ /* Overlay on error */
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
*/ */
void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
ath5k_hw_reg_read(ah, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR);
} }
...@@ -62,7 +61,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) ...@@ -62,7 +61,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
{ {
unsigned int i; unsigned int i;
ATH5K_TRACE(ah->ah_sc);
ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
/* /*
...@@ -96,8 +94,6 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) ...@@ -96,8 +94,6 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
*/ */
void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
{ {
ATH5K_TRACE(ah->ah_sc);
ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
} }
...@@ -125,7 +121,6 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) ...@@ -125,7 +121,6 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
{ {
u32 tx_queue; u32 tx_queue;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
/* Return if queue is declared inactive */ /* Return if queue is declared inactive */
...@@ -186,7 +181,6 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) ...@@ -186,7 +181,6 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
unsigned int i = 40; unsigned int i = 40;
u32 tx_queue, pending; u32 tx_queue, pending;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
/* Return if queue is declared inactive */ /* Return if queue is declared inactive */
...@@ -297,7 +291,6 @@ u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue) ...@@ -297,7 +291,6 @@ u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
{ {
u16 tx_reg; u16 tx_reg;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
/* /*
...@@ -340,7 +333,6 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) ...@@ -340,7 +333,6 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
{ {
u16 tx_reg; u16 tx_reg;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
/* /*
...@@ -400,8 +392,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) ...@@ -400,8 +392,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
u32 trigger_level, imr; u32 trigger_level, imr;
int ret = -EIO; int ret = -EIO;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Disable interrupts by setting the mask * Disable interrupts by setting the mask
*/ */
...@@ -451,7 +441,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) ...@@ -451,7 +441,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
*/ */
bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
} }
...@@ -475,8 +464,6 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) ...@@ -475,8 +464,6 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
{ {
u32 data; u32 data;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Read interrupt status from the Interrupt Status register * Read interrupt status from the Interrupt Status register
* on 5210 * on 5210
......
...@@ -35,7 +35,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) ...@@ -35,7 +35,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
{ {
u32 status, timeout; u32 status, timeout;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Initialize EEPROM access * Initialize EEPROM access
*/ */
...@@ -715,7 +714,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, ...@@ -715,7 +714,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
/* Only one curve for RF5111 /* Only one curve for RF5111
* find out which one and place * find out which one and place
* in in pd_curves. * in pd_curves.
* Note: ee_x_gain is reversed here */ * Note: ee_x_gain is reversed here */
for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
......
...@@ -34,8 +34,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) ...@@ -34,8 +34,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
/*5210 has different led mode handling*/ /*5210 has different led mode handling*/
u32 led_5210; u32 led_5210;
ATH5K_TRACE(ah->ah_sc);
/*Reset led status*/ /*Reset led status*/
if (ah->ah_version != AR5K_AR5210) if (ah->ah_version != AR5K_AR5210)
AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
...@@ -82,7 +80,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) ...@@ -82,7 +80,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
*/ */
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
{ {
ATH5K_TRACE(ah->ah_sc);
if (gpio >= AR5K_NUM_GPIO) if (gpio >= AR5K_NUM_GPIO)
return -EINVAL; return -EINVAL;
...@@ -98,7 +95,6 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) ...@@ -98,7 +95,6 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
*/ */
int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
{ {
ATH5K_TRACE(ah->ah_sc);
if (gpio >= AR5K_NUM_GPIO) if (gpio >= AR5K_NUM_GPIO)
return -EINVAL; return -EINVAL;
...@@ -114,7 +110,6 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) ...@@ -114,7 +110,6 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
*/ */
u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
{ {
ATH5K_TRACE(ah->ah_sc);
if (gpio >= AR5K_NUM_GPIO) if (gpio >= AR5K_NUM_GPIO)
return 0xffffffff; return 0xffffffff;
...@@ -129,7 +124,6 @@ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) ...@@ -129,7 +124,6 @@ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
{ {
u32 data; u32 data;
ATH5K_TRACE(ah->ah_sc);
if (gpio >= AR5K_NUM_GPIO) if (gpio >= AR5K_NUM_GPIO)
return -EINVAL; return -EINVAL;
...@@ -153,7 +147,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, ...@@ -153,7 +147,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
{ {
u32 data; u32 data;
ATH5K_TRACE(ah->ah_sc);
if (gpio >= AR5K_NUM_GPIO) if (gpio >= AR5K_NUM_GPIO)
return; return;
......
...@@ -59,8 +59,6 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) ...@@ -59,8 +59,6 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
beacon_reg = 0; beacon_reg = 0;
ATH5K_TRACE(ah->ah_sc);
switch (op_mode) { switch (op_mode) {
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
...@@ -173,7 +171,6 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) ...@@ -173,7 +171,6 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
*/ */
static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
{ {
ATH5K_TRACE(ah->ah_sc);
if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
<= timeout) <= timeout)
return -EINVAL; return -EINVAL;
...@@ -192,7 +189,6 @@ static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) ...@@ -192,7 +189,6 @@ static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
*/ */
static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
{ {
ATH5K_TRACE(ah->ah_sc);
if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
<= timeout) <= timeout)
return -EINVAL; return -EINVAL;
...@@ -297,7 +293,6 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) ...@@ -297,7 +293,6 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
u32 low_id, high_id; u32 low_id, high_id;
u32 pcu_reg; u32 pcu_reg;
ATH5K_TRACE(ah->ah_sc);
/* Set new station ID */ /* Set new station ID */
memcpy(common->macaddr, mac, ETH_ALEN); memcpy(common->macaddr, mac, ETH_ALEN);
...@@ -357,7 +352,6 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah) ...@@ -357,7 +352,6 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah)
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
{ {
struct ath_common *common = ath5k_hw_common(ah); struct ath_common *common = ath5k_hw_common(ah);
ATH5K_TRACE(ah->ah_sc);
/* Cache bssid mask so that we can restore it /* Cache bssid mask so that we can restore it
* on reset */ * on reset */
...@@ -382,7 +376,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) ...@@ -382,7 +376,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
*/ */
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
} }
...@@ -397,7 +390,6 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) ...@@ -397,7 +390,6 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
*/ */
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
} }
...@@ -406,8 +398,6 @@ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) ...@@ -406,8 +398,6 @@ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
*/ */
void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
{ {
ATH5K_TRACE(ah->ah_sc);
/* Set the multicat filter */
ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
} }
...@@ -427,7 +417,6 @@ u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah) ...@@ -427,7 +417,6 @@ u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
{ {
u32 data, filter = 0; u32 data, filter = 0;
ATH5K_TRACE(ah->ah_sc);
filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
/*Radar detection for 5212*/ /*Radar detection for 5212*/
...@@ -457,8 +446,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) ...@@ -457,8 +446,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
{ {
u32 data = 0; u32 data = 0;
ATH5K_TRACE(ah->ah_sc);
/* Set PHY error filter register on 5212*/ /* Set PHY error filter register on 5212*/
if (ah->ah_version == AR5K_AR5212) { if (ah->ah_version == AR5K_AR5212) {
if (filter & AR5K_RX_FILTER_RADARERR) if (filter & AR5K_RX_FILTER_RADARERR)
...@@ -533,8 +520,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) ...@@ -533,8 +520,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
WARN_ON( i == ATH5K_MAX_TSF_READ ); WARN_ON( i == ATH5K_MAX_TSF_READ );
ATH5K_TRACE(ah->ah_sc);
return (((u64)tsf_upper1 << 32) | tsf_lower); return (((u64)tsf_upper1 << 32) | tsf_lower);
} }
...@@ -548,8 +533,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) ...@@ -548,8 +533,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
*/ */
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64) void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
{ {
ATH5K_TRACE(ah->ah_sc);
ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32); ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32); ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
} }
...@@ -565,8 +548,6 @@ void ath5k_hw_reset_tsf(struct ath5k_hw *ah) ...@@ -565,8 +548,6 @@ void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
{ {
u32 val; u32 val;
ATH5K_TRACE(ah->ah_sc);
val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
/* /*
...@@ -586,7 +567,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) ...@@ -586,7 +567,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
{ {
u32 timer1, timer2, timer3; u32 timer1, timer2, timer3;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Set the additional timers by mode * Set the additional timers by mode
*/ */
...@@ -674,7 +654,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) ...@@ -674,7 +654,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
unsigned int i, type; unsigned int i, type;
u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
...@@ -749,8 +728,6 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, ...@@ -749,8 +728,6 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
bool is_tkip; bool is_tkip;
const u8 *key_ptr; const u8 *key_ptr;
ATH5K_TRACE(ah->ah_sc);
is_tkip = (key->alg == ALG_TKIP); is_tkip = (key->alg == ALG_TKIP);
/* /*
...@@ -836,7 +813,6 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) ...@@ -836,7 +813,6 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
{ {
u32 low_id, high_id; u32 low_id, high_id;
ATH5K_TRACE(ah->ah_sc);
/* Invalid entry (key table overflow) */ /* Invalid entry (key table overflow) */
AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
......
...@@ -378,8 +378,6 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) ...@@ -378,8 +378,6 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
u32 data, type; u32 data, type;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_rf_banks == NULL || if (ah->ah_rf_banks == NULL ||
ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE) ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
return AR5K_RFGAIN_INACTIVE; return AR5K_RFGAIN_INACTIVE;
...@@ -1167,7 +1165,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) ...@@ -1167,7 +1165,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
* The median of the values in the history is then loaded into the * The median of the values in the history is then loaded into the
* hardware for its own use for RSSI and CCA measurements. * hardware for its own use for RSSI and CCA measurements.
*/ */
static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
{ {
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u32 val; u32 val;
...@@ -1248,7 +1246,6 @@ static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) ...@@ -1248,7 +1246,6 @@ static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
/* /*
* Perform a PHY calibration on RF5110 * Perform a PHY calibration on RF5110
* -Fix BPSK/QAM Constellation (I/Q correction) * -Fix BPSK/QAM Constellation (I/Q correction)
* -Calculate Noise Floor
*/ */
static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
struct ieee80211_channel *channel) struct ieee80211_channel *channel)
...@@ -1335,8 +1332,6 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, ...@@ -1335,8 +1332,6 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
return ret; return ret;
} }
ath5k_hw_update_noise_floor(ah);
/* /*
* Re-enable RX/TX and beacons * Re-enable RX/TX and beacons
*/ */
...@@ -1348,22 +1343,20 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, ...@@ -1348,22 +1343,20 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
} }
/* /*
* Perform a PHY calibration on RF5111/5112 and newer chips * Perform I/Q calibration on RF5111/5112 and newer chips
*/ */
static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, static int
struct ieee80211_channel *channel) ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
{ {
u32 i_pwr, q_pwr; u32 i_pwr, q_pwr;
s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
int i; int i;
ATH5K_TRACE(ah->ah_sc);
if (!ah->ah_calibration || if (!ah->ah_calibration ||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
goto done; return 0;
/* Calibration has finished, get the results and re-run */ /* Calibration has finished, get the results and re-run */
/* work around empty results which can apparently happen on 5212 */ /* work around empty results which can apparently happen on 5212 */
for (i = 0; i <= 10; i++) { for (i = 0; i <= 10; i++) {
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
...@@ -1384,7 +1377,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, ...@@ -1384,7 +1377,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
/* protect against divide by 0 and loss of sign bits */ /* protect against divide by 0 and loss of sign bits */
if (i_coffd == 0 || q_coffd < 2) if (i_coffd == 0 || q_coffd < 2)
goto done; return -1;
i_coff = (-iq_corr) / i_coffd; i_coff = (-iq_corr) / i_coffd;
i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
...@@ -1410,17 +1403,6 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, ...@@ -1410,17 +1403,6 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
done:
/* TODO: Separate noise floor calibration from I/Q calibration
* since noise floor calibration interrupts rx path while I/Q
* calibration doesn't. We don't need to run noise floor calibration
* as often as I/Q calibration.*/
ath5k_hw_update_noise_floor(ah);
/* Initiate a gain_F calibration */
ath5k_hw_request_rfgain_probe(ah);
return 0; return 0;
} }
...@@ -1434,8 +1416,10 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, ...@@ -1434,8 +1416,10 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
if (ah->ah_radio == AR5K_RF5110) if (ah->ah_radio == AR5K_RF5110)
ret = ath5k_hw_rf5110_calibrate(ah, channel); ret = ath5k_hw_rf5110_calibrate(ah, channel);
else else {
ret = ath5k_hw_rf511x_calibrate(ah, channel); ret = ath5k_hw_rf511x_iq_calibrate(ah);
ath5k_hw_request_rfgain_probe(ah);
}
return ret; return ret;
} }
...@@ -1693,7 +1677,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, ...@@ -1693,7 +1677,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
int ath5k_hw_phy_disable(struct ath5k_hw *ah) int ath5k_hw_phy_disable(struct ath5k_hw *ah)
{ {
ATH5K_TRACE(ah->ah_sc);
/*Just a try M.F.*/ /*Just a try M.F.*/
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
...@@ -1709,8 +1692,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) ...@@ -1709,8 +1692,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
u32 srev; u32 srev;
u16 ret; u16 ret;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Set the radio chip access register * Set the radio chip access register
*/ */
...@@ -1755,8 +1736,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) ...@@ -1755,8 +1736,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
static void /*TODO:Boundary check*/ static void /*TODO:Boundary check*/
ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
{ {
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_version != AR5K_AR5210) if (ah->ah_version != AR5K_AR5210)
ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
} }
...@@ -1789,19 +1768,50 @@ ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable) ...@@ -1789,19 +1768,50 @@ ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
if (enable) { if (enable) {
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
AR5K_PHY_RESTART_DIV_GC, 0xc); AR5K_PHY_RESTART_DIV_GC, 1);
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
AR5K_PHY_FAST_ANT_DIV_EN); AR5K_PHY_FAST_ANT_DIV_EN);
} else { } else {
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
AR5K_PHY_RESTART_DIV_GC, 0x8); AR5K_PHY_RESTART_DIV_GC, 0);
AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
AR5K_PHY_FAST_ANT_DIV_EN); AR5K_PHY_FAST_ANT_DIV_EN);
} }
} }
void
ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
{
u8 ant0, ant1;
/*
* In case a fixed antenna was set as default
* use the same switch table twice.
*/
if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
ant0 = ant1 = AR5K_ANT_SWTABLE_A;
else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
ant0 = ant1 = AR5K_ANT_SWTABLE_B;
else {
ant0 = AR5K_ANT_SWTABLE_A;
ant1 = AR5K_ANT_SWTABLE_B;
}
/* Set antenna idle switch table */
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
(ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] |
AR5K_PHY_ANT_CTL_TXRX_EN));
/* Set antenna switch tables */
ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
AR5K_PHY_ANT_SWITCH_TABLE_0);
ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
AR5K_PHY_ANT_SWITCH_TABLE_1);
}
/* /*
* Set antenna operating mode * Set antenna operating mode
*/ */
...@@ -1814,9 +1824,14 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) ...@@ -1814,9 +1824,14 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
u8 def_ant, tx_ant, ee_mode; u8 def_ant, tx_ant, ee_mode;
u32 sta_id1 = 0; u32 sta_id1 = 0;
def_ant = ah->ah_def_ant; /* if channel is not initialized yet we can't set the antennas
* so just store the mode. it will be set on the next reset */
if (channel == NULL) {
ah->ah_ant_mode = ant_mode;
return;
}
ATH5K_TRACE(ah->ah_sc); def_ant = ah->ah_def_ant;
switch (channel->hw_value & CHANNEL_MODES) { switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A: case CHANNEL_A:
...@@ -1916,6 +1931,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) ...@@ -1916,6 +1931,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
if (sta_id1) if (sta_id1)
AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1); AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
ath5k_hw_set_antenna_switch(ah, ee_mode);
/* Note: set diversity before default antenna /* Note: set diversity before default antenna
* because it won't work correctly */ * because it won't work correctly */
ath5k_hw_set_fast_div(ah, ee_mode, fast_div); ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
...@@ -2981,7 +2997,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, ...@@ -2981,7 +2997,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
u8 type; u8 type;
int ret; int ret;
ATH5K_TRACE(ah->ah_sc);
if (txpower > AR5K_TUNE_MAX_TXPOWER) { if (txpower > AR5K_TUNE_MAX_TXPOWER) {
ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
return -EINVAL; return -EINVAL;
...@@ -3077,8 +3092,6 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) ...@@ -3077,8 +3092,6 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
struct ieee80211_channel *channel = ah->ah_current_channel; struct ieee80211_channel *channel = ah->ah_current_channel;
u8 ee_mode; u8 ee_mode;
ATH5K_TRACE(ah->ah_sc);
switch (channel->hw_value & CHANNEL_MODES) { switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A: case CHANNEL_A:
case CHANNEL_T: case CHANNEL_T:
......
...@@ -31,7 +31,6 @@ Queue Control Unit, DFS Control Unit Functions ...@@ -31,7 +31,6 @@ Queue Control Unit, DFS Control Unit Functions
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
struct ath5k_txq_info *queue_info) struct ath5k_txq_info *queue_info)
{ {
ATH5K_TRACE(ah->ah_sc);
memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
return 0; return 0;
} }
...@@ -42,7 +41,6 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, ...@@ -42,7 +41,6 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
const struct ath5k_txq_info *queue_info) const struct ath5k_txq_info *queue_info)
{ {
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
...@@ -69,8 +67,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, ...@@ -69,8 +67,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
unsigned int queue; unsigned int queue;
int ret; int ret;
ATH5K_TRACE(ah->ah_sc);
/* /*
* Get queue by type * Get queue by type
*/ */
...@@ -149,7 +145,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, ...@@ -149,7 +145,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{ {
u32 pending; u32 pending;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
/* Return if queue is declared inactive */ /* Return if queue is declared inactive */
...@@ -177,7 +172,6 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) ...@@ -177,7 +172,6 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
*/ */
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
{ {
ATH5K_TRACE(ah->ah_sc);
if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
return; return;
...@@ -195,7 +189,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) ...@@ -195,7 +189,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
u32 cw_min, cw_max, retry_lg, retry_sh; u32 cw_min, cw_max, retry_lg, retry_sh;
struct ath5k_txq_info *tq = &ah->ah_txq[queue]; struct ath5k_txq_info *tq = &ah->ah_txq[queue];
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
tq = &ah->ah_txq[queue]; tq = &ah->ah_txq[queue];
...@@ -523,8 +516,6 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) ...@@ -523,8 +516,6 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
{ {
u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
ATH5K_TRACE(ah->ah_sc);
if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
return -EINVAL; return -EINVAL;
......
...@@ -201,8 +201,6 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) ...@@ -201,8 +201,6 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
int ret; int ret;
u32 mask = val ? val : ~0U; u32 mask = val ? val : ~0U;
ATH5K_TRACE(ah->ah_sc);
/* Read-and-clear RX Descriptor Pointer*/ /* Read-and-clear RX Descriptor Pointer*/
ath5k_hw_reg_read(ah, AR5K_RXDP); ath5k_hw_reg_read(ah, AR5K_RXDP);
...@@ -246,7 +244,6 @@ static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, ...@@ -246,7 +244,6 @@ static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
unsigned int i; unsigned int i;
u32 staid, data; u32 staid, data;
ATH5K_TRACE(ah->ah_sc);
staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
switch (mode) { switch (mode) {
...@@ -393,8 +390,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) ...@@ -393,8 +390,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode = 0; mode = 0;
clock = 0; clock = 0;
ATH5K_TRACE(ah->ah_sc);
/* Wakeup the device */ /* Wakeup the device */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) { if (ret) {
...@@ -734,7 +729,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, ...@@ -734,7 +729,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
} }
static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) struct ieee80211_channel *channel, u8 ee_mode)
{ {
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
s16 cck_ofdm_pwr_delta; s16 cck_ofdm_pwr_delta;
...@@ -768,17 +763,9 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, ...@@ -768,17 +763,9 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
ee->ee_cck_ofdm_gain_delta; ee->ee_cck_ofdm_gain_delta;
} }
/* Set antenna idle switch table */ /* XXX: necessary here? is called from ath5k_hw_set_antenna_mode()
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, * too */
AR5K_PHY_ANT_CTL_SWTABLE_IDLE, ath5k_hw_set_antenna_switch(ah, ee_mode);
(ah->ah_ant_ctl[ee_mode][0] |
AR5K_PHY_ANT_CTL_TXRX_EN));
/* Set antenna switch tables */
ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
AR5K_PHY_ANT_SWITCH_TABLE_0);
ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
AR5K_PHY_ANT_SWITCH_TABLE_1);
/* Noise floor threshold */ /* Noise floor threshold */
ath5k_hw_reg_write(ah, ath5k_hw_reg_write(ah,
...@@ -855,7 +842,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, ...@@ -855,7 +842,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_NF_THRESH62, AR5K_PHY_NF_THRESH62,
ee->ee_thr_62[ee_mode]); ee->ee_thr_62[ee_mode]);
/* False detect backoff for channels /* False detect backoff for channels
* that have spur noise. Write the new * that have spur noise. Write the new
* cyclic power RSSI threshold. */ * cyclic power RSSI threshold. */
...@@ -891,14 +877,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ...@@ -891,14 +877,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool change_channel) struct ieee80211_channel *channel, bool change_channel)
{ {
struct ath_common *common = ath5k_hw_common(ah); struct ath_common *common = ath5k_hw_common(ah);
u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;
u32 phy_tst1; u32 phy_tst1;
u8 mode, freq, ee_mode, ant[2]; u8 mode, freq, ee_mode;
int i, ret; int i, ret;
ATH5K_TRACE(ah->ah_sc);
s_ant = 0;
ee_mode = 0; ee_mode = 0;
staid1_flags = 0; staid1_flags = 0;
tsf_up = 0; tsf_up = 0;
...@@ -995,9 +978,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ...@@ -995,9 +978,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
} }
} }
/* Save default antenna */
s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
if (ah->ah_version == AR5K_AR5212) { if (ah->ah_version == AR5K_AR5212) {
/* Restore normal 32/40MHz clock operation /* Restore normal 32/40MHz clock operation
* to avoid register access delay on certain * to avoid register access delay on certain
...@@ -1094,22 +1074,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ...@@ -1094,22 +1074,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Write OFDM timings on 5212*/ /* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 && if (ah->ah_version == AR5K_AR5212 &&
channel->hw_value & CHANNEL_OFDM) { channel->hw_value & CHANNEL_OFDM) {
struct ath5k_eeprom_info *ee =
&ah->ah_capabilities.cap_eeprom;
ret = ath5k_hw_write_ofdm_timings(ah, channel); ret = ath5k_hw_write_ofdm_timings(ah, channel);
if (ret) if (ret)
return ret; return ret;
/* Note: According to docs we can have a newer /* Spur info is available only from EEPROM versions
* EEPROM on old hardware, so we need to verify * bigger than 5.3 but but the EEPOM routines will use
* that our hardware is new enough to have spur * static values for older versions */
* mitigation registers (delta phase etc) */ if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
(ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
ath5k_hw_set_spur_mitigation_filter(ah, ath5k_hw_set_spur_mitigation_filter(ah,
channel); channel);
} }
/*Enable/disable 802.11b mode on 5111 /*Enable/disable 802.11b mode on 5111
...@@ -1123,21 +1098,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ...@@ -1123,21 +1098,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_TXCFG_B_MODE); AR5K_TXCFG_B_MODE);
} }
/*
* In case a fixed antenna was set as default
* use the same switch table twice.
*/
if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
else {
ant[0] = AR5K_ANT_SWTABLE_A;
ant[1] = AR5K_ANT_SWTABLE_B;
}
/* Commit values from EEPROM */ /* Commit values from EEPROM */
ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
} else { } else {
/* /*
...@@ -1175,8 +1137,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ...@@ -1175,8 +1137,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
} }
} }
ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
} }
/* Ledstate */ /* Ledstate */
......
#include <linux/device.h>
#include <linux/pci.h>
#include "base.h"
#include "ath5k.h"
#include "reg.h"
#define SIMPLE_SHOW_STORE(name, get, set) \
static ssize_t ath5k_attr_show_##name(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct ath5k_softc *sc = dev_get_drvdata(dev); \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
} \
\
static ssize_t ath5k_attr_store_##name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct ath5k_softc *sc = dev_get_drvdata(dev); \
int val; \
\
val = (int)simple_strtoul(buf, NULL, 10); \
set(sc->ah, val); \
return count; \
} \
static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \
ath5k_attr_show_##name, ath5k_attr_store_##name)
#define SIMPLE_SHOW(name, get) \
static ssize_t ath5k_attr_show_##name(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct ath5k_softc *sc = dev_get_drvdata(dev); \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
} \
static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
/*** ANI ***/
SIMPLE_SHOW_STORE(ani_mode, sc->ani_state.ani_mode, ath5k_ani_init);
SIMPLE_SHOW_STORE(noise_immunity_level, sc->ani_state.noise_imm_level,
ath5k_ani_set_noise_immunity_level);
SIMPLE_SHOW_STORE(spur_level, sc->ani_state.spur_level,
ath5k_ani_set_spur_immunity_level);
SIMPLE_SHOW_STORE(firstep_level, sc->ani_state.firstep_level,
ath5k_ani_set_firstep_level);
SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, sc->ani_state.ofdm_weak_sig,
ath5k_ani_set_ofdm_weak_signal_detection);
SIMPLE_SHOW_STORE(cck_weak_signal_detection, sc->ani_state.cck_weak_sig,
ath5k_ani_set_cck_weak_signal_detection);
SIMPLE_SHOW(spur_level_max, sc->ani_state.max_spur_level);
static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL);
}
static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO,
ath5k_attr_show_noise_immunity_level_max, NULL);
static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL);
}
static DEVICE_ATTR(firstep_level_max, S_IRUGO,
ath5k_attr_show_firstep_level_max, NULL);
static struct attribute *ath5k_sysfs_entries_ani[] = {
&dev_attr_ani_mode.attr,
&dev_attr_noise_immunity_level.attr,
&dev_attr_spur_level.attr,
&dev_attr_firstep_level.attr,
&dev_attr_ofdm_weak_signal_detection.attr,
&dev_attr_cck_weak_signal_detection.attr,
&dev_attr_noise_immunity_level_max.attr,
&dev_attr_spur_level_max.attr,
&dev_attr_firstep_level_max.attr,
NULL
};
static struct attribute_group ath5k_attribute_group_ani = {
.name = "ani",
.attrs = ath5k_sysfs_entries_ani,
};
/*** register / unregister ***/
int
ath5k_sysfs_register(struct ath5k_softc *sc)
{
struct device *dev = &sc->pdev->dev;
int err;
err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
if (err) {
ATH5K_ERR(sc, "failed to create sysfs group\n");
return err;
}
return 0;
}
void
ath5k_sysfs_unregister(struct ath5k_softc *sc)
{
struct device *dev = &sc->pdev->dev;
sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
}
...@@ -495,6 +495,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) ...@@ -495,6 +495,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_OFDM, 0);
REG_WRITE(ah, AR_FILT_CCK, 0); REG_WRITE(ah, AR_FILT_CCK, 0);
} }
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
u32 *rxc_pcnt, u32 *rxc_pcnt,
......
...@@ -742,17 +742,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, ...@@ -742,17 +742,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
return -EINVAL; return -EINVAL;
} }
if (AR_SREV_9287_12_OR_LATER(ah)) {
/* Enable ASYNC FIFO */
REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
}
/* /*
* Set correct baseband to analog shift setting to * Set correct baseband to analog shift setting to
* access analog chips. * access analog chips.
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "ar5008_initvals.h" #include "ar5008_initvals.h"
#include "ar9001_initvals.h" #include "ar9001_initvals.h"
#include "ar9002_initvals.h" #include "ar9002_initvals.h"
#include "ar9002_phy.h"
/* General hardware code for the A5008/AR9001/AR9002 hadware families */ /* General hardware code for the A5008/AR9001/AR9002 hadware families */
...@@ -436,55 +437,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, ...@@ -436,55 +437,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
} }
udelay(1000); udelay(1000);
}
/* set bit 19 to allow forcing of pcie core into L1 state */ if (power_off) {
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); /* clear bit 19 to disable L1 */
REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
/* Several PCIe massages to ensure proper behaviour */ val = REG_READ(ah, AR_WA);
/*
* Set PCIe workaround bits
* In AR9280 and AR9285, bit 14 in WA register (disable L1)
* should only be set when device enters D3 and be
* cleared when device comes back to D0.
*/
if (ah->config.pcie_waen) {
if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
val |= AR_WA_D3_L1_DISABLE;
} else {
if (((AR_SREV_9285(ah) ||
AR_SREV_9271(ah) ||
AR_SREV_9287(ah)) &&
(AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
(AR_SREV_9280(ah) &&
(AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
val |= AR_WA_D3_L1_DISABLE;
}
}
if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
/*
* Disable bit 6 and 7 before entering D3 to
* prevent system hang.
*/
val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
}
if (AR_SREV_9285E_20(ah))
val |= AR_WA_BIT23;
REG_WRITE(ah, AR_WA, val);
} else {
if (ah->config.pcie_waen) { if (ah->config.pcie_waen) {
val = ah->config.pcie_waen; val = ah->config.pcie_waen;
if (!power_off) if (!power_off)
val &= (~AR_WA_D3_L1_DISABLE); val &= (~AR_WA_D3_L1_DISABLE);
} else { } else {
if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || if (AR_SREV_9285(ah) ||
AR_SREV_9271(ah) ||
AR_SREV_9287(ah)) { AR_SREV_9287(ah)) {
val = AR9285_WA_DEFAULT; val = AR9285_WA_DEFAULT;
if (!power_off) if (!power_off)
val &= (~AR_WA_D3_L1_DISABLE); val &= (~AR_WA_D3_L1_DISABLE);
} else if (AR_SREV_9280(ah)) { }
else if (AR_SREV_9280(ah)) {
/* /*
* On AR9280 chips bit 22 of 0x4004 needs to be * For AR9280 chips, bit 22 of 0x4004
* set otherwise card may disappear. * needs to be set.
*/ */
val = AR9280_WA_DEFAULT; val = AR9280_WA_DEFAULT;
if (!power_off) if (!power_off)
val &= (~AR_WA_D3_L1_DISABLE); val &= (~AR_WA_D3_L1_DISABLE);
} else } else {
val = AR_WA_DEFAULT; val = AR_WA_DEFAULT;
}
}
/* WAR for ASPM system hang */
if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
val |= (AR_WA_BIT6 | AR_WA_BIT7);
} }
if (AR_SREV_9285E_20(ah))
val |= AR_WA_BIT23;
REG_WRITE(ah, AR_WA, val); REG_WRITE(ah, AR_WA, val);
}
if (power_off) { /* set bit 19 to allow forcing of pcie core into L1 state */
/* REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
* Set PCIe workaround bits
* bit 14 in WA register (disable L1) should only
* be set when device enters D3 and be cleared
* when device comes back to D0.
*/
if (ah->config.pcie_waen) {
if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
} else {
if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
AR_SREV_9287(ah)) &&
(AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
(AR_SREV_9280(ah) &&
(AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
}
}
} }
} }
...@@ -536,18 +566,29 @@ int ar9002_hw_rf_claim(struct ath_hw *ah) ...@@ -536,18 +566,29 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
return 0; return 0;
} }
void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
{
if (AR_SREV_9287_13_OR_LATER(ah)) {
REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
}
}
/* /*
* Enable ASYNC FIFO
*
* If Async FIFO is enabled, the following counters change as MAC now runs * If Async FIFO is enabled, the following counters change as MAC now runs
* at 117 Mhz instead of 88/44MHz when async FIFO is disabled. * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
* *
* The values below tested for ht40 2 chain. * The values below tested for ht40 2 chain.
* Overwrite the delay/timeouts initialized in process ini. * Overwrite the delay/timeouts initialized in process ini.
*/ */
void ar9002_hw_enable_async_fifo(struct ath_hw *ah) void ar9002_hw_update_async_fifo(struct ath_hw *ah)
{ {
if (AR_SREV_9287_12_OR_LATER(ah)) { if (AR_SREV_9287_13_OR_LATER(ah)) {
REG_WRITE(ah, AR_D_GBL_IFS_SIFS, REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
REG_WRITE(ah, AR_D_GBL_IFS_SLOT, REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
...@@ -571,9 +612,9 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) ...@@ -571,9 +612,9 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
*/ */
void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
{ {
if (AR_SREV_9287_12_OR_LATER(ah)) { if (AR_SREV_9287_13_OR_LATER(ah)) {
REG_SET_BIT(ah, AR_PCU_MISC_MODE2, REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
AR_PCU_MISC_MODE2_ENABLE_AGGWEP); AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
} }
} }
......
...@@ -4492,7 +4492,7 @@ static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { ...@@ -4492,7 +4492,7 @@ static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
}; };
/* AR9271 initialization values automaticaly created: 06/04/09 */ /* AR9271 initialization values automaticaly created: 03/31/10 */
static const u32 ar9271Modes_9271[][6] = { static const u32 ar9271Modes_9271[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
...@@ -5011,7 +5011,7 @@ static const u32 ar9271Common_9271[][2] = { ...@@ -5011,7 +5011,7 @@ static const u32 ar9271Common_9271[][2] = {
{ 0x0000783c, 0x72ee0a72 }, { 0x0000783c, 0x72ee0a72 },
{ 0x00007840, 0xbbfffffc }, { 0x00007840, 0xbbfffffc },
{ 0x00007844, 0x000c0db6 }, { 0x00007844, 0x000c0db6 },
{ 0x00007848, 0x6db61b6f }, { 0x00007848, 0x6db6246f },
{ 0x0000784c, 0x6d9b66db }, { 0x0000784c, 0x6d9b66db },
{ 0x00007850, 0x6d8c6dba }, { 0x00007850, 0x6d8c6dba },
{ 0x00007854, 0x00040000 }, { 0x00007854, 0x00040000 },
...@@ -5218,7 +5218,7 @@ static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = { ...@@ -5218,7 +5218,7 @@ static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
{ 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff }, { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
{ 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 }, { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
{ 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
{ 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 }, { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652, 0x0a22a652 },
{ 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
{ 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 }, { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
{ 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef INITVALS_9003_H #ifndef INITVALS_9003_2P0_H
#define INITVALS_9003_H #define INITVALS_9003_2P0_H
/* AR9003 2.0 */ /* AR9003 2.0 */
...@@ -1781,4 +1781,4 @@ static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { ...@@ -1781,4 +1781,4 @@ static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
{0x00004044, 0x00000000}, {0x00004044, 0x00000000},
}; };
#endif /* INITVALS_9003_H */ #endif /* INITVALS_9003_2P0_H */
此差异已折叠。
...@@ -739,6 +739,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ...@@ -739,6 +739,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
*/ */
ar9003_hw_set_chain_masks(ah, 0x7, 0x7); ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
/* Do Tx IQ Calibration */
ar9003_hw_tx_iq_cal(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
udelay(5);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
/* Calibrate the AGC */ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
...@@ -753,10 +759,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ...@@ -753,10 +759,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
return false; return false;
} }
/* Do Tx IQ Calibration */
if (ah->config.tx_iq_calibration)
ar9003_hw_tx_iq_cal(ah);
/* Revert chainmasks to their original values before NF cal */ /* Revert chainmasks to their original values before NF cal */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
#include "hw.h" #include "hw.h"
#include "ar9003_mac.h" #include "ar9003_mac.h"
#include "ar9003_initvals.h" #include "ar9003_2p0_initvals.h"
#include "ar9003_2p2_initvals.h"
/* General hardware code for the AR9003 hadware family */ /* General hardware code for the AR9003 hadware family */
...@@ -31,12 +32,8 @@ static bool ar9003_hw_macversion_supported(u32 macversion) ...@@ -31,12 +32,8 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
return false; return false;
} }
/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */ /* AR9003 2.0 */
/* static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah)
* XXX: move TX/RX gain INI to its own init_mode_gain_regs after
* ensuring it does not affect hardware bring up
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{ {
/* mac */ /* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
...@@ -106,27 +103,128 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ...@@ -106,27 +103,128 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
3); 3);
} }
/* AR9003 2.2 */
static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
{
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
ar9300_2p2_mac_core,
ARRAY_SIZE(ar9300_2p2_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
ar9300_2p2_mac_postamble,
ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
/* bb */
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
ar9300_2p2_baseband_core,
ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
ar9300_2p2_baseband_postamble,
ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
ar9300_2p2_radio_core,
ARRAY_SIZE(ar9300_2p2_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
ar9300_2p2_radio_postamble,
ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
ar9300_2p2_soc_preamble,
ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
ar9300_2p2_soc_postamble,
ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
5);
/* Load PCIE SERDES settings from INI */
/* Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
2);
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9300PciePhy_clkreq_enable_L1_2p2,
ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
2);
/* Fast clock modal settings */
INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9300Modes_fast_clock_2p2,
ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
3);
}
/*
* The AR9003 family uses a new INI format (pre, core, post
* arrays per subsystem).
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
if (AR_SREV_9300_20(ah))
ar9003_2p0_hw_init_mode_regs(ah);
else
ar9003_2p2_hw_init_mode_regs(ah);
}
static void ar9003_tx_gain_table_apply(struct ath_hw *ah) static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
{ {
switch (ar9003_hw_get_tx_gain_idx(ah)) { switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0: case 0:
default: default:
INIT_INI_ARRAY(&ah->iniModesTxGain, if (AR_SREV_9300_20(ah))
ar9300Modes_lowest_ob_db_tx_gain_table_2p0, INIT_INI_ARRAY(&ah->iniModesTxGain,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
5); ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
5);
break; break;
case 1: case 1:
INIT_INI_ARRAY(&ah->iniModesTxGain, if (AR_SREV_9300_20(ah))
ar9300Modes_high_ob_db_tx_gain_table_2p0, INIT_INI_ARRAY(&ah->iniModesTxGain,
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), ar9300Modes_high_ob_db_tx_gain_table_2p0,
5); ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_high_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
5);
break; break;
case 2: case 2:
INIT_INI_ARRAY(&ah->iniModesTxGain, if (AR_SREV_9300_20(ah))
ar9300Modes_low_ob_db_tx_gain_table_2p0, INIT_INI_ARRAY(&ah->iniModesTxGain,
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), ar9300Modes_low_ob_db_tx_gain_table_2p0,
5); ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_low_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
5);
break; break;
} }
} }
...@@ -136,15 +234,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) ...@@ -136,15 +234,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) { switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0: case 0:
default: default:
INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0, if (AR_SREV_9300_20(ah))
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), INIT_INI_ARRAY(&ah->iniModesRxGain,
2); ar9300Common_rx_gain_table_2p0,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
2);
break; break;
case 1: case 1:
INIT_INI_ARRAY(&ah->iniModesRxGain, if (AR_SREV_9300_20(ah))
ar9300Common_wo_xlna_rx_gain_table_2p0, INIT_INI_ARRAY(&ah->iniModesRxGain,
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), ar9300Common_wo_xlna_rx_gain_table_2p0,
2); ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_wo_xlna_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
2);
break; break;
} }
} }
......
...@@ -90,6 +90,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ...@@ -90,6 +90,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
MAP_ISR_S2_CST); MAP_ISR_S2_CST);
mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
MAP_ISR_S2_TSFOOR); MAP_ISR_S2_TSFOOR);
mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
MAP_ISR_S2_BB_WATCHDOG);
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
REG_WRITE(ah, AR_ISR_S2, isr2); REG_WRITE(ah, AR_ISR_S2, isr2);
...@@ -167,6 +169,9 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ...@@ -167,6 +169,9 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
(void) REG_READ(ah, AR_ISR); (void) REG_READ(ah, AR_ISR);
} }
if (*masked & ATH9K_INT_BB_WATCHDOG)
ar9003_hw_bb_watchdog_read(ah);
} }
if (sync_cause) { if (sync_cause) {
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define MAP_ISR_S2_DTIMSYNC 7 #define MAP_ISR_S2_DTIMSYNC 7
#define MAP_ISR_S2_DTIM 7 #define MAP_ISR_S2_DTIM 7
#define MAP_ISR_S2_TSFOOR 4 #define MAP_ISR_S2_TSFOOR 4
#define MAP_ISR_S2_BB_WATCHDOG 6
#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds) #define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
......
...@@ -1132,3 +1132,122 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) ...@@ -1132,3 +1132,122 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->do_getnf = ar9003_hw_do_getnf; priv_ops->do_getnf = ar9003_hw_do_getnf;
priv_ops->loadnf = ar9003_hw_loadnf; priv_ops->loadnf = ar9003_hw_loadnf;
} }
void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
u32 idle_tmo_ms = ah->bb_watchdog_timeout_ms;
u32 val, idle_count;
if (!idle_tmo_ms) {
/* disable IRQ, disable chip-reset for BB panic */
REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) &
~(AR_PHY_WATCHDOG_RST_ENABLE |
AR_PHY_WATCHDOG_IRQ_ENABLE));
/* disable watchdog in non-IDLE mode, disable in IDLE mode */
REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
REG_READ(ah, AR_PHY_WATCHDOG_CTL_1) &
~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
AR_PHY_WATCHDOG_IDLE_ENABLE));
ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
return;
}
/* enable IRQ, disable chip-reset for BB watchdog */
val = REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & AR_PHY_WATCHDOG_CNTL2_MASK;
REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
(val | AR_PHY_WATCHDOG_IRQ_ENABLE) &
~AR_PHY_WATCHDOG_RST_ENABLE);
/* bound limit to 10 secs */
if (idle_tmo_ms > 10000)
idle_tmo_ms = 10000;
/*
* The time unit for watchdog event is 2^15 44/88MHz cycles.
*
* For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick
* For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick
*
* Given we use fast clock now in 5 GHz, these time units should
* be common for both 2 GHz and 5 GHz.
*/
idle_count = (100 * idle_tmo_ms) / 74;
if (ah->curchan && IS_CHAN_HT40(ah->curchan))
idle_count = (100 * idle_tmo_ms) / 37;
/*
* enable watchdog in non-IDLE mode, disable in IDLE mode,
* set idle time-out.
*/
REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
AR_PHY_WATCHDOG_IDLE_MASK |
(AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2)));
ath_print(common, ATH_DBG_RESET,
"Enabled BB Watchdog timeout (%u ms)\n",
idle_tmo_ms);
}
void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
{
/*
* we want to avoid printing in ISR context so we save the
* watchdog status to be printed later in bottom half context.
*/
ah->bb_watchdog_last_status = REG_READ(ah, AR_PHY_WATCHDOG_STATUS);
/*
* the watchdog timer should reset on status read but to be sure
* sure we write 0 to the watchdog status bit.
*/
REG_WRITE(ah, AR_PHY_WATCHDOG_STATUS,
ah->bb_watchdog_last_status & ~AR_PHY_WATCHDOG_STATUS_CLR);
}
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
if (likely(!(common->debug_mask & ATH_DBG_RESET)))
return;
status = ah->bb_watchdog_last_status;
ath_print(common, ATH_DBG_RESET,
"\n==== BB update: BB status=0x%08x ====\n", status);
ath_print(common, ATH_DBG_RESET,
"** BB state: wd=%u det=%u rdar=%u rOFDM=%d "
"rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
MS(status, AR_PHY_WATCHDOG_INFO),
MS(status, AR_PHY_WATCHDOG_DET_HANG),
MS(status, AR_PHY_WATCHDOG_RADAR_SM),
MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
MS(status, AR_PHY_WATCHDOG_AGC_SM),
MS(status,AR_PHY_WATCHDOG_SRCH_SM));
ath_print(common, ATH_DBG_RESET,
"** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
ath_print(common, ATH_DBG_RESET,
"** BB mode: BB_gen_controls=0x%08x **\n",
REG_READ(ah, AR_PHY_GEN_CTRL));
if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
ath_print(common, ATH_DBG_RESET,
"** BB busy times: rx_clear=%d%%, "
"rx_frame=%d%%, tx_frame=%d%% **\n",
rxc_pcnt, rxf_pcnt, txf_pcnt);
ath_print(common, ATH_DBG_RESET,
"==== BB update: done ====\n\n");
}
EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
...@@ -483,10 +483,10 @@ ...@@ -483,10 +483,10 @@
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450) #define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
#define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0) #define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
#define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4) #define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
#define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8) #define AR_PHY_WATCHDOG_CTL_2 (AR_SM_BASE + 0x5c8)
#define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc) #define AR_PHY_WATCHDOG_CTL (AR_SM_BASE + 0x5cc)
#define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0)
#define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4)
#define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc)
...@@ -812,35 +812,35 @@ ...@@ -812,35 +812,35 @@
#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) #define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) #define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001 #define AR_PHY_WATCHDOG_NON_IDLE_ENABLE 0x00000001
#define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002 #define AR_PHY_WATCHDOG_IDLE_ENABLE 0x00000002
#define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000 #define AR_PHY_WATCHDOG_IDLE_MASK 0xFFFF0000
#define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC #define AR_PHY_WATCHDOG_NON_IDLE_MASK 0x0000FFFC
#define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002 #define AR_PHY_WATCHDOG_RST_ENABLE 0x00000002
#define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004 #define AR_PHY_WATCHDOG_IRQ_ENABLE 0x00000004
#define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9 #define AR_PHY_WATCHDOG_CNTL2_MASK 0xFFFFFFF9
#define AR_PHY_BB_WD_STATUS 0x00000007 #define AR_PHY_WATCHDOG_INFO 0x00000007
#define AR_PHY_BB_WD_STATUS_S 0 #define AR_PHY_WATCHDOG_INFO_S 0
#define AR_PHY_BB_WD_DET_HANG 0x00000008 #define AR_PHY_WATCHDOG_DET_HANG 0x00000008
#define AR_PHY_BB_WD_DET_HANG_S 3 #define AR_PHY_WATCHDOG_DET_HANG_S 3
#define AR_PHY_BB_WD_RADAR_SM 0x000000F0 #define AR_PHY_WATCHDOG_RADAR_SM 0x000000F0
#define AR_PHY_BB_WD_RADAR_SM_S 4 #define AR_PHY_WATCHDOG_RADAR_SM_S 4
#define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00 #define AR_PHY_WATCHDOG_RX_OFDM_SM 0x00000F00
#define AR_PHY_BB_WD_RX_OFDM_SM_S 8 #define AR_PHY_WATCHDOG_RX_OFDM_SM_S 8
#define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000 #define AR_PHY_WATCHDOG_RX_CCK_SM 0x0000F000
#define AR_PHY_BB_WD_RX_CCK_SM_S 12 #define AR_PHY_WATCHDOG_RX_CCK_SM_S 12
#define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000 #define AR_PHY_WATCHDOG_TX_OFDM_SM 0x000F0000
#define AR_PHY_BB_WD_TX_OFDM_SM_S 16 #define AR_PHY_WATCHDOG_TX_OFDM_SM_S 16
#define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000 #define AR_PHY_WATCHDOG_TX_CCK_SM 0x00F00000
#define AR_PHY_BB_WD_TX_CCK_SM_S 20 #define AR_PHY_WATCHDOG_TX_CCK_SM_S 20
#define AR_PHY_BB_WD_AGC_SM 0x0F000000 #define AR_PHY_WATCHDOG_AGC_SM 0x0F000000
#define AR_PHY_BB_WD_AGC_SM_S 24 #define AR_PHY_WATCHDOG_AGC_SM_S 24
#define AR_PHY_BB_WD_SRCH_SM 0xF0000000 #define AR_PHY_WATCHDOG_SRCH_SM 0xF0000000
#define AR_PHY_BB_WD_SRCH_SM_S 28 #define AR_PHY_WATCHDOG_SRCH_SM_S 28
#define AR_PHY_BB_WD_STATUS_CLR 0x00000008 #define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
......
...@@ -136,6 +136,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, ...@@ -136,6 +136,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_MAX_ANTENNA 3 #define ATH_MAX_ANTENNA 3
#define ATH_RXBUF 512 #define ATH_RXBUF 512
#define ATH_TXBUF 512 #define ATH_TXBUF 512
#define ATH_TXBUF_RESERVE 5
#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
#define ATH_TXMAXTRY 13 #define ATH_TXMAXTRY 13
#define ATH_MGT_TXMAXTRY 4 #define ATH_MGT_TXMAXTRY 4
...@@ -204,6 +206,71 @@ struct ath_txq { ...@@ -204,6 +206,71 @@ struct ath_txq {
struct list_head txq_fifo_pending; struct list_head txq_fifo_pending;
u8 txq_headidx; u8 txq_headidx;
u8 txq_tailidx; u8 txq_tailidx;
int pending_frames;
};
struct ath_atx_ac {
int sched;
int qnum;
struct list_head list;
struct list_head tid_q;
};
struct ath_buf_state {
int bfs_nframes;
u16 bfs_al;
u16 bfs_frmlen;
int bfs_seqno;
int bfs_tidno;
int bfs_retries;
u8 bf_type;
u32 bfs_keyix;
enum ath9k_key_type bfs_keytype;
};
struct ath_buf {
struct list_head list;
struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
an aggregate) */
struct ath_buf *bf_next; /* next subframe in the aggregate */
struct sk_buff *bf_mpdu; /* enclosing frame structure */
void *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
bool bf_stale;
bool bf_isnullfunc;
bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
struct ath_wiphy *aphy;
struct ath_txq *txq;
};
struct ath_atx_tid {
struct list_head list;
struct list_head buf_q;
struct ath_node *an;
struct ath_atx_ac *ac;
struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
u16 seq_start;
u16 seq_next;
u16 baw_size;
int tidno;
int baw_head; /* first un-acked tx buffer */
int baw_tail; /* next unused tx buffer slot */
int sched;
int paused;
u8 state;
};
struct ath_node {
struct ath_common *common;
struct ath_atx_tid tid[WME_NUM_TID];
struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu;
u8 mpdudensity;
int last_rssi;
}; };
#define AGGR_CLEANUP BIT(1) #define AGGR_CLEANUP BIT(1)
...@@ -267,7 +334,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); ...@@ -267,7 +334,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_init(struct ath_softc *sc, int nbufs); int ath_tx_init(struct ath_softc *sc, int nbufs);
void ath_tx_cleanup(struct ath_softc *sc); void ath_tx_cleanup(struct ath_softc *sc);
struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
int ath_txq_update(struct ath_softc *sc, int qnum, int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *q); struct ath9k_tx_queue_info *q);
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
......
...@@ -27,270 +27,6 @@ MODULE_AUTHOR("Atheros Communications"); ...@@ -27,270 +27,6 @@ MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
/* Common RX processing */
/* Assumes you've already done the endian to CPU conversion */
static bool ath9k_rx_accept(struct ath_common *common,
struct sk_buff *skb,
struct ieee80211_rx_status *rxs,
struct ath_rx_status *rx_stats,
bool *decrypt_error)
{
struct ath_hw *ah = common->ah;
struct ieee80211_hdr *hdr;
__le16 fc;
hdr = (struct ieee80211_hdr *) skb->data;
fc = hdr->frame_control;
if (!rx_stats->rs_datalen)
return false;
/*
* rs_status follows rs_datalen so if rs_datalen is too large
* we can take a hint that hardware corrupted it, so ignore
* those frames.
*/
if (rx_stats->rs_datalen > common->rx_bufsize)
return false;
/*
* rs_more indicates chained descriptors which can be used
* to link buffers together for a sort of scatter-gather
* operation.
* reject the frame, we don't support scatter-gather yet and
* the frame is probably corrupt anyway
*/
if (rx_stats->rs_more)
return false;
/*
* The rx_stats->rs_status will not be set until the end of the
* chained descriptors so it can be ignored if rs_more is set. The
* rs_more will be false at the last element of the chained
* descriptors.
*/
if (rx_stats->rs_status != 0) {
if (rx_stats->rs_status & ATH9K_RXERR_CRC)
rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
if (rx_stats->rs_status & ATH9K_RXERR_PHY)
return false;
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
*decrypt_error = true;
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
if (ieee80211_is_ctl(fc))
/*
* Sometimes, we get invalid
* MIC failures on valid control frames.
* Remove these mic errors.
*/
rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
else
rxs->flag |= RX_FLAG_MMIC_ERROR;
}
/*
* Reject error frames with the exception of
* decryption and MIC failures. For monitor mode,
* we also ignore the CRC error.
*/
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
if (rx_stats->rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC))
return false;
} else {
if (rx_stats->rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
return false;
}
}
}
return true;
}
static int ath9k_process_rate(struct ath_common *common,
struct ieee80211_hw *hw,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rxs,
struct sk_buff *skb)
{
struct ieee80211_supported_band *sband;
enum ieee80211_band band;
unsigned int i = 0;
band = hw->conf.channel->band;
sband = hw->wiphy->bands[band];
if (rx_stats->rs_rate & 0x80) {
/* HT rate */
rxs->flag |= RX_FLAG_HT;
if (rx_stats->rs_flags & ATH9K_RX_2040)
rxs->flag |= RX_FLAG_40MHZ;
if (rx_stats->rs_flags & ATH9K_RX_GI)
rxs->flag |= RX_FLAG_SHORT_GI;
rxs->rate_idx = rx_stats->rs_rate & 0x7f;
return 0;
}
for (i = 0; i < sband->n_bitrates; i++) {
if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
rxs->rate_idx = i;
return 0;
}
if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
rxs->flag |= RX_FLAG_SHORTPRE;
rxs->rate_idx = i;
return 0;
}
}
/*
* No valid hardware bitrate found -- we should not get here
* because hardware has already validated this frame as OK.
*/
ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
"0x%02x using 1 Mbit\n", rx_stats->rs_rate);
if ((common->debug_mask & ATH_DBG_XMIT))
print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len);
return -EINVAL;
}
static void ath9k_process_rssi(struct ath_common *common,
struct ieee80211_hw *hw,
struct sk_buff *skb,
struct ath_rx_status *rx_stats)
{
struct ath_hw *ah = common->ah;
struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr;
struct ath_node *an;
int last_rssi = ATH_RSSI_DUMMY_MARKER;
__le16 fc;
hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
rcu_read_lock();
/*
* XXX: use ieee80211_find_sta! This requires quite a bit of work
* under the current ath9k virtual wiphy implementation as we have
* no way of tying a vif to wiphy. Typically vifs are attached to
* at least one sdata of a wiphy on mac80211 but with ath9k virtual
* wiphy you'd have to iterate over every wiphy and each sdata.
*/
sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
if (sta) {
an = (struct ath_node *) sta->drv_priv;
if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
!rx_stats->rs_moreaggr)
ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
last_rssi = an->last_rssi;
}
rcu_read_unlock();
if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
ATH_RSSI_EP_MULTIPLIER);
if (rx_stats->rs_rssi < 0)
rx_stats->rs_rssi = 0;
/* Update Beacon RSSI, this is used by ANI. */
if (ieee80211_is_beacon(fc))
ah->stats.avgbrssi = rx_stats->rs_rssi;
}
/*
* For Decrypt or Demic errors, we only mark packet status here and always push
* up the frame up to let mac80211 handle the actual error case, be it no
* decryption key or real decryption error. This let us keep statistics there.
*/
int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
struct ieee80211_hw *hw,
struct sk_buff *skb,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rx_status,
bool *decrypt_error)
{
struct ath_hw *ah = common->ah;
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
/*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
*/
if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error))
return -EINVAL;
ath9k_process_rssi(common, hw, skb, rx_stats);
if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb))
return -EINVAL;
rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp);
rx_status->band = hw->conf.channel->band;
rx_status->freq = hw->conf.channel->center_freq;
rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
rx_status->antenna = rx_stats->rs_antenna;
rx_status->flag |= RX_FLAG_TSFT;
return 0;
}
EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess);
void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
struct sk_buff *skb,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rxs,
bool decrypt_error)
{
struct ath_hw *ah = common->ah;
struct ieee80211_hdr *hdr;
int hdrlen, padpos, padsize;
u8 keyix;
__le16 fc;
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
fc = hdr->frame_control;
padpos = ath9k_cmn_padpos(hdr->frame_control);
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
* padsize would take into account odd header lengths:
* padsize = (4 - padpos % 4) % 4; However, since only
* even-length headers are used, padding can only be 0 or 2
* bytes and we can optimize this a bit. In addition, we must
* not try to remove padding from short control frames that do
* not have payload. */
padsize = padpos & 3;
if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize);
}
keyix = rx_stats->rs_keyix;
if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
ieee80211_has_protected(fc)) {
rxs->flag |= RX_FLAG_DECRYPTED;
} else if (ieee80211_has_protected(fc)
&& !decrypt_error && skb->len >= hdrlen + 4) {
keyix = skb->data[hdrlen + 3] >> 6;
if (test_bit(keyix, common->keymap))
rxs->flag |= RX_FLAG_DECRYPTED;
}
if (ah->sw_mgmt_crypto &&
(rxs->flag & RX_FLAG_DECRYPTED) &&
ieee80211_is_mgmt(fc))
/* Use software decrypt for management frames. */
rxs->flag &= ~RX_FLAG_DECRYPTED;
}
EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
int ath9k_cmn_padpos(__le16 frame_control) int ath9k_cmn_padpos(__le16 frame_control)
{ {
int padpos = 24; int padpos = 24;
...@@ -475,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) ...@@ -475,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
return -1; return -1;
} }
static int ath_reserve_key_cache_slot(struct ath_common *common) static int ath_reserve_key_cache_slot(struct ath_common *common,
enum ieee80211_key_alg alg)
{ {
int i; int i;
if (alg == ALG_TKIP)
return ath_reserve_key_cache_slot_tkip(common);
/* First, try to find slots that would not be available for TKIP. */ /* First, try to find slots that would not be available for TKIP. */
if (common->splitmic) { if (common->splitmic) {
for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
...@@ -547,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -547,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
struct ath_hw *ah = common->ah; struct ath_hw *ah = common->ah;
struct ath9k_keyval hk; struct ath9k_keyval hk;
const u8 *mac = NULL; const u8 *mac = NULL;
u8 gmac[ETH_ALEN];
int ret = 0; int ret = 0;
int idx; int idx;
...@@ -570,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -570,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common,
memcpy(hk.kv_val, key->key, key->keylen); memcpy(hk.kv_val, key->key, key->keylen);
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
/* For now, use the default keys for broadcast keys. This may switch (vif->type) {
* need to change with virtual interfaces. */ case NL80211_IFTYPE_AP:
idx = key->keyidx; memcpy(gmac, vif->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->alg);
break;
case NL80211_IFTYPE_ADHOC:
memcpy(gmac, sta->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->alg);
break;
default:
idx = key->keyidx;
break;
}
} else if (key->keyidx) { } else if (key->keyidx) {
if (WARN_ON(!sta)) if (WARN_ON(!sta))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -589,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -589,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common,
return -EOPNOTSUPP; return -EOPNOTSUPP;
mac = sta->addr; mac = sta->addr;
if (key->alg == ALG_TKIP) idx = ath_reserve_key_cache_slot(common, key->alg);
idx = ath_reserve_key_cache_slot_tkip(common);
else
idx = ath_reserve_key_cache_slot(common);
if (idx < 0)
return -ENOSPC; /* no free key cache entries */
} }
if (idx < 0)
return -ENOSPC; /* no free key cache entries */
if (key->alg == ALG_TKIP) if (key->alg == ALG_TKIP)
ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
vif->type == NL80211_IFTYPE_AP); vif->type == NL80211_IFTYPE_AP);
...@@ -644,6 +397,19 @@ void ath9k_cmn_key_delete(struct ath_common *common, ...@@ -644,6 +397,19 @@ void ath9k_cmn_key_delete(struct ath_common *common,
} }
EXPORT_SYMBOL(ath9k_cmn_key_delete); EXPORT_SYMBOL(ath9k_cmn_key_delete);
int ath9k_cmn_count_streams(unsigned int chainmask, int max)
{
int streams = 0;
do {
if (++streams == max)
break;
} while ((chainmask = chainmask & (chainmask - 1)));
return streams;
}
EXPORT_SYMBOL(ath9k_cmn_count_streams);
static int __init ath9k_cmn_init(void) static int __init ath9k_cmn_init(void)
{ {
return 0; return 0;
......
...@@ -52,82 +52,6 @@ ...@@ -52,82 +52,6 @@
#define ATH_EP_RND(x, mul) \ #define ATH_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
struct ath_atx_ac {
int sched;
int qnum;
struct list_head list;
struct list_head tid_q;
};
struct ath_buf_state {
int bfs_nframes;
u16 bfs_al;
u16 bfs_frmlen;
int bfs_seqno;
int bfs_tidno;
int bfs_retries;
u8 bf_type;
u32 bfs_keyix;
enum ath9k_key_type bfs_keytype;
};
struct ath_buf {
struct list_head list;
struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
an aggregate) */
struct ath_buf *bf_next; /* next subframe in the aggregate */
struct sk_buff *bf_mpdu; /* enclosing frame structure */
void *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
bool bf_stale;
bool bf_isnullfunc;
bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
struct ath_wiphy *aphy;
};
struct ath_atx_tid {
struct list_head list;
struct list_head buf_q;
struct ath_node *an;
struct ath_atx_ac *ac;
struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
u16 seq_start;
u16 seq_next;
u16 baw_size;
int tidno;
int baw_head; /* first un-acked tx buffer */
int baw_tail; /* next unused tx buffer slot */
int sched;
int paused;
u8 state;
};
struct ath_node {
struct ath_common *common;
struct ath_atx_tid tid[WME_NUM_TID];
struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu;
u8 mpdudensity;
int last_rssi;
};
int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
struct ieee80211_hw *hw,
struct sk_buff *skb,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rx_status,
bool *decrypt_error);
void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
struct sk_buff *skb,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rxs,
bool decrypt_error);
int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
...@@ -140,3 +64,4 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -140,3 +64,4 @@ int ath9k_cmn_key_config(struct ath_common *common,
struct ieee80211_key_conf *key); struct ieee80211_key_conf *key);
void ath9k_cmn_key_delete(struct ath_common *common, void ath9k_cmn_key_delete(struct ath_common *common,
struct ieee80211_key_conf *key); struct ieee80211_key_conf *key);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
...@@ -42,7 +42,7 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, ...@@ -42,7 +42,7 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
char buf[32]; char buf[32];
unsigned int len; unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", common->debug_mask); len = sprintf(buf, "0x%08x\n", common->debug_mask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -57,7 +57,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, ...@@ -57,7 +57,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
len = min(count, sizeof(buf) - 1); len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len)) if (copy_from_user(buf, user_buf, len))
return -EINVAL; return -EFAULT;
buf[len] = '\0'; buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask)) if (strict_strtoul(buf, 0, &mask))
...@@ -86,7 +86,7 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, ...@@ -86,7 +86,7 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
char buf[32]; char buf[32];
unsigned int len; unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); len = sprintf(buf, "0x%08x\n", common->tx_chainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -101,7 +101,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use ...@@ -101,7 +101,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use
len = min(count, sizeof(buf) - 1); len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len)) if (copy_from_user(buf, user_buf, len))
return -EINVAL; return -EFAULT;
buf[len] = '\0'; buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask)) if (strict_strtoul(buf, 0, &mask))
...@@ -128,7 +128,7 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, ...@@ -128,7 +128,7 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
char buf[32]; char buf[32];
unsigned int len; unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); len = sprintf(buf, "0x%08x\n", common->rx_chainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -143,7 +143,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use ...@@ -143,7 +143,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use
len = min(count, sizeof(buf) - 1); len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len)) if (copy_from_user(buf, user_buf, len))
return -EINVAL; return -EFAULT;
buf[len] = '\0'; buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask)) if (strict_strtoul(buf, 0, &mask))
...@@ -176,7 +176,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, ...@@ -176,7 +176,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
if (!buf) if (!buf)
return 0; return -ENOMEM;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
...@@ -248,6 +248,9 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, ...@@ -248,6 +248,9 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
if (len > DMA_BUF_LEN)
len = DMA_BUF_LEN;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf); kfree(buf);
return retval; return retval;
...@@ -269,6 +272,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) ...@@ -269,6 +272,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
sc->debug.stats.istats.rxlp++; sc->debug.stats.istats.rxlp++;
if (status & ATH9K_INT_RXHP) if (status & ATH9K_INT_RXHP)
sc->debug.stats.istats.rxhp++; sc->debug.stats.istats.rxhp++;
if (status & ATH9K_INT_BB_WATCHDOG)
sc->debug.stats.istats.bb_watchdog++;
} else { } else {
if (status & ATH9K_INT_RX) if (status & ATH9K_INT_RX)
sc->debug.stats.istats.rxok++; sc->debug.stats.istats.rxok++;
...@@ -319,6 +324,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, ...@@ -319,6 +324,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
"%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp); "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "WATCHDOG",
sc->debug.stats.istats.bb_watchdog);
} else { } else {
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
...@@ -358,6 +366,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, ...@@ -358,6 +366,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
if (len > sizeof(buf))
len = sizeof(buf);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -397,11 +408,10 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, ...@@ -397,11 +408,10 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
if (sc->cur_rate_table == NULL) if (sc->cur_rate_table == NULL)
return 0; return 0;
max = 80 + sc->cur_rate_table->rate_cnt * 1024; max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
buf = kmalloc(max + 1, GFP_KERNEL); buf = kmalloc(max, GFP_KERNEL);
if (buf == NULL) if (buf == NULL)
return 0; return -ENOMEM;
buf[max] = 0;
len += sprintf(buf, "%6s %6s %6s " len += sprintf(buf, "%6s %6s %6s "
"%10s %10s %10s %10s\n", "%10s %10s %10s %10s\n",
...@@ -443,6 +453,9 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, ...@@ -443,6 +453,9 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
stats->per); stats->per);
} }
if (len > max)
len = max;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf); kfree(buf);
return retval; return retval;
...@@ -505,6 +518,9 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, ...@@ -505,6 +518,9 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"addrmask: %pM\n", addr); "addrmask: %pM\n", addr);
if (len > sizeof(buf))
len = sizeof(buf);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -630,7 +646,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, ...@@ -630,7 +646,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
buf = kzalloc(size, GFP_KERNEL); buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL) if (buf == NULL)
return 0; return -ENOMEM;
len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
...@@ -648,6 +664,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, ...@@ -648,6 +664,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
PR("DATA Underrun: ", data_underrun); PR("DATA Underrun: ", data_underrun);
PR("DELIM Underrun: ", delim_underrun); PR("DELIM Underrun: ", delim_underrun);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf); kfree(buf);
...@@ -700,7 +719,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, ...@@ -700,7 +719,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
buf = kzalloc(size, GFP_KERNEL); buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL) if (buf == NULL)
return 0; return -ENOMEM;
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "CRC ERR", "%18s : %10u\n", "CRC ERR",
...@@ -751,6 +770,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, ...@@ -751,6 +770,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf); kfree(buf);
...@@ -802,7 +824,7 @@ static ssize_t read_file_regidx(struct file *file, char __user *user_buf, ...@@ -802,7 +824,7 @@ static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
char buf[32]; char buf[32];
unsigned int len; unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); len = sprintf(buf, "0x%08x\n", sc->debug.regidx);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -816,7 +838,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, ...@@ -816,7 +838,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
len = min(count, sizeof(buf) - 1); len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len)) if (copy_from_user(buf, user_buf, len))
return -EINVAL; return -EFAULT;
buf[len] = '\0'; buf[len] = '\0';
if (strict_strtoul(buf, 0, &regidx)) if (strict_strtoul(buf, 0, &regidx))
...@@ -843,7 +865,7 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf, ...@@ -843,7 +865,7 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf,
u32 regval; u32 regval;
regval = REG_READ_D(ah, sc->debug.regidx); regval = REG_READ_D(ah, sc->debug.regidx);
len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); len = sprintf(buf, "0x%08x\n", regval);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }
...@@ -858,7 +880,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, ...@@ -858,7 +880,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
len = min(count, sizeof(buf) - 1); len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len)) if (copy_from_user(buf, user_buf, len))
return -EINVAL; return -EFAULT;
buf[len] = '\0'; buf[len] = '\0';
if (strict_strtoul(buf, 0, &regval)) if (strict_strtoul(buf, 0, &regval))
......
...@@ -53,6 +53,7 @@ struct ath_buf; ...@@ -53,6 +53,7 @@ struct ath_buf;
* @cabend: RX End of CAB traffic * @cabend: RX End of CAB traffic
* @dtimsync: DTIM sync lossage * @dtimsync: DTIM sync lossage
* @dtim: RX Beacon with DTIM * @dtim: RX Beacon with DTIM
* @bb_watchdog: Baseband watchdog
*/ */
struct ath_interrupt_stats { struct ath_interrupt_stats {
u32 total; u32 total;
...@@ -76,6 +77,7 @@ struct ath_interrupt_stats { ...@@ -76,6 +77,7 @@ struct ath_interrupt_stats {
u32 cabend; u32 cabend;
u32 dtimsync; u32 dtimsync;
u32 dtim; u32 dtim;
u32 bb_watchdog;
}; };
struct ath_rc_stats { struct ath_rc_stats {
......
...@@ -24,6 +24,14 @@ static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) ...@@ -24,6 +24,14 @@ static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
} }
void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
{
REG_WRITE(ah, reg, val);
if (ah->config.analog_shiftreg)
udelay(100);
}
void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
u32 shift, u32 val) u32 shift, u32 val)
{ {
...@@ -250,6 +258,27 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, ...@@ -250,6 +258,27 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
return twiceMaxEdgePower; return twiceMaxEdgePower;
} }
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
switch (ar5416_get_ntxchains(ah->txchainmask)) {
case 1:
break;
case 2:
regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
break;
case 3:
regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
break;
default:
ath_print(common, ATH_DBG_EEPROM,
"Invalid chainmask configuration\n");
break;
}
}
int ath9k_hw_eeprom_init(struct ath_hw *ah) int ath9k_hw_eeprom_init(struct ath_hw *ah)
{ {
int status; int status;
......
...@@ -679,6 +679,7 @@ struct eeprom_ops { ...@@ -679,6 +679,7 @@ struct eeprom_ops {
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
}; };
void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val);
void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
u32 shift, u32 val); u32 shift, u32 val);
int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
...@@ -704,6 +705,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah, ...@@ -704,6 +705,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
u16 numRates, bool isHt40Target); u16 numRates, bool isHt40Target);
u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
bool is2GHz, int num_band_edges); bool is2GHz, int num_band_edges);
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
int ath9k_hw_eeprom_init(struct ath_hw *ah); int ath9k_hw_eeprom_init(struct ath_hw *ah);
#define ar5416_get_ntxchains(_txchainmask) \ #define ar5416_get_ntxchains(_txchainmask) \
......
...@@ -249,6 +249,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, ...@@ -249,6 +249,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
struct chan_centers centers; struct chan_centers centers;
#define PD_GAIN_BOUNDARY_DEFAULT 58; #define PD_GAIN_BOUNDARY_DEFAULT 58;
memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
ath9k_hw_get_channel_centers(ah, chan, &centers); ath9k_hw_get_channel_centers(ah, chan, &centers);
for (numPiers = 0; numPiers < availPiers; numPiers++) { for (numPiers = 0; numPiers < availPiers; numPiers++) {
......
...@@ -617,6 +617,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, ...@@ -617,6 +617,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
int16_t minDelta = 0; int16_t minDelta = 0;
struct chan_centers centers; struct chan_centers centers;
memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
ath9k_hw_get_channel_centers(ah, chan, &centers); ath9k_hw_get_channel_centers(ah, chan, &centers);
for (numPiers = 0; numPiers < availPiers; numPiers++) { for (numPiers = 0; numPiers < availPiers; numPiers++) {
......
...@@ -16,12 +16,10 @@ ...@@ -16,12 +16,10 @@
#include "htc.h" #include "htc.h"
#define ATH9K_FW_USB_DEV(devid, fw) \
{ USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
static struct usb_device_id ath9k_hif_usb_ids[] = { static struct usb_device_id ath9k_hif_usb_ids[] = {
ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"), { USB_DEVICE(0x0cf3, 0x9271) },
ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"), { USB_DEVICE(0x0cf3, 0x1006) },
{ USB_DEVICE(0x0cf3, 0x7010) },
{ }, { },
}; };
...@@ -756,6 +754,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) ...@@ -756,6 +754,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
size_t len = hif_dev->firmware->size; size_t len = hif_dev->firmware->size;
u32 addr = AR9271_FIRMWARE; u32 addr = AR9271_FIRMWARE;
u8 *buf = kzalloc(4096, GFP_KERNEL); u8 *buf = kzalloc(4096, GFP_KERNEL);
u32 firm_offset;
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
...@@ -779,32 +778,37 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) ...@@ -779,32 +778,37 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
} }
kfree(buf); kfree(buf);
if (hif_dev->device_id == 0x7010)
firm_offset = AR7010_FIRMWARE_TEXT;
else
firm_offset = AR9271_FIRMWARE_TEXT;
/* /*
* Issue FW download complete command to firmware. * Issue FW download complete command to firmware.
*/ */
err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0), err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
FIRMWARE_DOWNLOAD_COMP, FIRMWARE_DOWNLOAD_COMP,
0x40 | USB_DIR_OUT, 0x40 | USB_DIR_OUT,
AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ); firm_offset >> 8, 0, NULL, 0, HZ);
if (err) if (err)
return -EIO; return -EIO;
dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n", dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
"ar9271.fw", (unsigned long) hif_dev->firmware->size); hif_dev->fw_name, (unsigned long) hif_dev->firmware->size);
return 0; return 0;
} }
static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
const char *fw_name)
{ {
int ret; int ret;
/* Request firmware */ /* Request firmware */
ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev); ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
&hif_dev->udev->dev);
if (ret) { if (ret) {
dev_err(&hif_dev->udev->dev, dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s not found\n", fw_name); "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name);
goto err_fw_req; goto err_fw_req;
} }
...@@ -820,7 +824,8 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, ...@@ -820,7 +824,8 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
ret = ath9k_hif_usb_download_fw(hif_dev); ret = ath9k_hif_usb_download_fw(hif_dev);
if (ret) { if (ret) {
dev_err(&hif_dev->udev->dev, dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s download failed\n", fw_name); "ath9k_htc: Firmware - %s download failed\n",
hif_dev->fw_name);
goto err_fw_download; goto err_fw_download;
} }
...@@ -847,7 +852,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, ...@@ -847,7 +852,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
{ {
struct usb_device *udev = interface_to_usbdev(interface); struct usb_device *udev = interface_to_usbdev(interface);
struct hif_device_usb *hif_dev; struct hif_device_usb *hif_dev;
const char *fw_name = (const char *) id->driver_info;
int ret = 0; int ret = 0;
hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
...@@ -872,7 +876,29 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, ...@@ -872,7 +876,29 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
goto err_htc_hw_alloc; goto err_htc_hw_alloc;
} }
ret = ath9k_hif_usb_dev_init(hif_dev, fw_name); /* Find out which firmware to load */
switch(hif_dev->device_id) {
case 0x9271:
case 0x1006:
hif_dev->fw_name = "ar9271.fw";
break;
case 0x7010:
if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
hif_dev->fw_name = "ar7010_1_1.fw";
else
hif_dev->fw_name = "ar7010.fw";
break;
default:
break;
}
if (!hif_dev->fw_name) {
dev_err(&udev->dev, "Can't determine firmware !\n");
goto err_htc_hw_alloc;
}
ret = ath9k_hif_usb_dev_init(hif_dev);
if (ret) { if (ret) {
ret = -EINVAL; ret = -EINVAL;
goto err_hif_init_usb; goto err_hif_init_usb;
...@@ -907,12 +933,10 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) ...@@ -907,12 +933,10 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
void *buf; void *buf;
int ret; int ret;
buf = kmalloc(4, GFP_KERNEL); buf = kmemdup(&reboot_cmd, 4, GFP_KERNEL);
if (!buf) if (!buf)
return; return;
memcpy(buf, &reboot_cmd, 4);
ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE),
buf, 4, NULL, HZ); buf, 4, NULL, HZ);
if (ret) if (ret)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define AR9271_FIRMWARE 0x501000 #define AR9271_FIRMWARE 0x501000
#define AR9271_FIRMWARE_TEXT 0x903000 #define AR9271_FIRMWARE_TEXT 0x903000
#define AR7010_FIRMWARE_TEXT 0x906000
#define FIRMWARE_DOWNLOAD 0x30 #define FIRMWARE_DOWNLOAD 0x30
#define FIRMWARE_DOWNLOAD_COMP 0x31 #define FIRMWARE_DOWNLOAD_COMP 0x31
...@@ -90,6 +91,7 @@ struct hif_device_usb { ...@@ -90,6 +91,7 @@ struct hif_device_usb {
struct usb_anchor regout_submitted; struct usb_anchor regout_submitted;
struct usb_anchor rx_submitted; struct usb_anchor rx_submitted;
struct sk_buff *remain_skb; struct sk_buff *remain_skb;
const char *fw_name;
int rx_remain_len; int rx_remain_len;
int rx_pkt_len; int rx_pkt_len;
int rx_transfer_len; int rx_transfer_len;
......
...@@ -257,12 +257,15 @@ struct ath9k_htc_tx_ctl { ...@@ -257,12 +257,15 @@ struct ath9k_htc_tx_ctl {
#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
struct ath_tx_stats { struct ath_tx_stats {
u32 buf_queued; u32 buf_queued;
u32 buf_completed; u32 buf_completed;
u32 skb_queued; u32 skb_queued;
u32 skb_completed; u32 skb_completed;
u32 skb_dropped; u32 skb_dropped;
u32 queue_stats[WME_NUM_AC];
}; };
struct ath_rx_stats { struct ath_rx_stats {
...@@ -286,6 +289,8 @@ struct ath9k_debug { ...@@ -286,6 +289,8 @@ struct ath9k_debug {
#define TX_STAT_INC(c) do { } while (0) #define TX_STAT_INC(c) do { } while (0)
#define RX_STAT_INC(c) do { } while (0) #define RX_STAT_INC(c) do { } while (0)
#define TX_QSTAT_INC(c) do { } while (0)
#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
#define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_DEF 1
...@@ -390,13 +395,14 @@ struct ath9k_htc_priv { ...@@ -390,13 +395,14 @@ struct ath9k_htc_priv {
int led_off_duration; int led_off_duration;
int led_on_cnt; int led_on_cnt;
int led_off_cnt; int led_off_cnt;
int beaconq;
int cabq;
int hwq_map[ATH9K_WME_AC_VO+1]; int hwq_map[ATH9K_WME_AC_VO+1];
#ifdef CONFIG_ATH9K_HTC_DEBUGFS #ifdef CONFIG_ATH9K_HTC_DEBUGFS
struct ath9k_debug debug; struct ath9k_debug debug;
#endif #endif
struct ath9k_htc_target_rate tgt_rate;
struct mutex mutex; struct mutex mutex;
}; };
...@@ -405,6 +411,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) ...@@ -405,6 +411,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
common->bus_ops->read_cachesize(common, csz); common->bus_ops->read_cachesize(common, csz);
} }
void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
...@@ -426,6 +433,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); ...@@ -426,6 +433,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
enum ath9k_tx_queue_subtype qtype); enum ath9k_tx_queue_subtype qtype);
int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
int get_hw_qnum(u16 queue, int *hwq_map); int get_hw_qnum(u16 queue, int *hwq_map);
int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
struct ath9k_tx_queue_info *qinfo); struct ath9k_tx_queue_info *qinfo);
......
...@@ -89,7 +89,6 @@ static void htc_process_target_rdy(struct htc_target *target, ...@@ -89,7 +89,6 @@ static void htc_process_target_rdy(struct htc_target *target,
struct htc_endpoint *endpoint; struct htc_endpoint *endpoint;
struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf; struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
target->credits = be16_to_cpu(htc_ready_msg->credits);
target->credit_size = be16_to_cpu(htc_ready_msg->credit_size); target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
endpoint = &target->endpoint[ENDPOINT0]; endpoint = &target->endpoint[ENDPOINT0];
...@@ -159,7 +158,7 @@ static int htc_config_pipe_credits(struct htc_target *target) ...@@ -159,7 +158,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID); cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
cp_msg->pipe_id = USB_WLAN_TX_PIPE; cp_msg->pipe_id = USB_WLAN_TX_PIPE;
cp_msg->credits = 28; cp_msg->credits = target->credits;
target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -279,9 +279,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, ...@@ -279,9 +279,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
if (wmi->drv_priv->op_flags & OP_UNPLUGGED) if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
return 0; return 0;
if (!wmi)
return -EINVAL;
skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册