提交 28f49d8f 编写于 作者: D David S. Miller

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

此差异已折叠。
...@@ -3854,10 +3854,6 @@ P: Ion Badulescu ...@@ -3854,10 +3854,6 @@ P: Ion Badulescu
M: ionut@cs.columbia.edu M: ionut@cs.columbia.edu
S: Maintained S: Maintained
STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
W: http://mosquitonet.Stanford.EDU/strip.html
S: Unsupported ?
STRADIS MPEG-2 DECODER DRIVER STRADIS MPEG-2 DECODER DRIVER
P: Nathan Laredo P: Nathan Laredo
M: laredo@gnu.org M: laredo@gnu.org
......
...@@ -148,9 +148,9 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev, ...@@ -148,9 +148,9 @@ 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)
{ {
dma_sync_single_range_for_device(sdev->dma_dev, dma_base, ssb_dma_sync_single_range_for_device(sdev, dma_base,
offset & dma_desc_align_mask, 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,
...@@ -158,9 +158,9 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, ...@@ -158,9 +158,9 @@ 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)
{ {
dma_sync_single_range_for_cpu(sdev->dma_dev, dma_base, ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
offset & dma_desc_align_mask, 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)
...@@ -613,10 +613,10 @@ static void b44_tx(struct b44 *bp) ...@@ -613,10 +613,10 @@ static void b44_tx(struct b44 *bp)
BUG_ON(skb == NULL); BUG_ON(skb == NULL);
dma_unmap_single(bp->sdev->dma_dev, ssb_dma_unmap_single(bp->sdev,
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);
} }
...@@ -653,29 +653,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -653,29 +653,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 = dma_map_single(bp->sdev->dma_dev, skb->data, mapping = ssb_dma_map_single(bp->sdev, 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 (dma_mapping_error(mapping) || if (ssb_dma_mapping_error(bp->sdev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
/* Sigh... */ /* Sigh... */
if (!dma_mapping_error(mapping)) if (!ssb_dma_mapping_error(bp->sdev, mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, ssb_dma_unmap_single(bp->sdev, 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 = dma_map_single(bp->sdev->dma_dev, skb->data, mapping = ssb_dma_map_single(bp->sdev, skb->data,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
if (dma_mapping_error(mapping) || if (ssb_dma_mapping_error(bp->sdev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
if (!dma_mapping_error(mapping)) if (!ssb_dma_mapping_error(bp->sdev, mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE); ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -ENOMEM; return -ENOMEM;
} }
...@@ -750,9 +750,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -750,9 +750,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);
dma_sync_single_for_device(bp->sdev->dma_dev, le32_to_cpu(src_desc->addr), ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
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)
...@@ -772,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget) ...@@ -772,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget)
struct rx_header *rh; struct rx_header *rh;
u16 len; u16 len;
dma_sync_single_for_cpu(bp->sdev->dma_dev, map, ssb_dma_sync_single_for_cpu(bp->sdev, 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;
...@@ -806,8 +806,8 @@ static int b44_rx(struct b44 *bp, int budget) ...@@ -806,8 +806,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;
dma_unmap_single(bp->sdev->dma_dev, map, ssb_dma_unmap_single(bp->sdev, 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);
...@@ -966,25 +966,25 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -966,25 +966,25 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto err_out; goto err_out;
} }
mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE); mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
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 (!dma_mapping_error(mapping)) if (!ssb_dma_mapping_error(bp->sdev, mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, len, ssb_dma_unmap_single(bp->sdev, mapping, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA); bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) if (!bounce_skb)
goto err_out; goto err_out;
mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data, mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
len, DMA_TO_DEVICE); len, DMA_TO_DEVICE);
if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
if (!dma_mapping_error(mapping)) if (!ssb_dma_mapping_error(bp->sdev, mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, ssb_dma_unmap_single(bp->sdev, 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;
} }
...@@ -1082,8 +1082,8 @@ static void b44_free_rings(struct b44 *bp) ...@@ -1082,8 +1082,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL) if (rp->skb == NULL)
continue; continue;
dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ, ssb_dma_unmap_single(bp->sdev, 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;
} }
...@@ -1094,8 +1094,8 @@ static void b44_free_rings(struct b44 *bp) ...@@ -1094,8 +1094,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL) if (rp->skb == NULL)
continue; continue;
dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len, ssb_dma_unmap_single(bp->sdev, 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;
} }
...@@ -1117,14 +1117,14 @@ static void b44_init_rings(struct b44 *bp) ...@@ -1117,14 +1117,14 @@ 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)
dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma, ssb_dma_sync_single_for_device(bp->sdev, 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)
dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma, ssb_dma_sync_single_for_device(bp->sdev, 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)
...@@ -1144,25 +1144,27 @@ static void b44_free_consistent(struct b44 *bp) ...@@ -1144,25 +1144,27 @@ 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) {
dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma, ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
kfree(bp->rx_ring); kfree(bp->rx_ring);
} else } else
dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES, ssb_dma_free_consistent(bp->sdev, 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) {
dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma, ssb_dma_unmap_single(bp->sdev, 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
dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES, ssb_dma_free_consistent(bp->sdev, 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;
} }
...@@ -1187,7 +1189,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1187,7 +1189,7 @@ 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 = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->rx_ring_dma, gfp); bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, 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
...@@ -1199,11 +1201,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1199,11 +1201,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 = dma_map_single(bp->sdev->dma_dev, rx_ring, rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
if (dma_mapping_error(rx_ring_dma) || if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
rx_ring_dma + size > DMA_30BIT_MASK) { rx_ring_dma + size > DMA_30BIT_MASK) {
kfree(rx_ring); kfree(rx_ring);
goto out_err; goto out_err;
...@@ -1214,9 +1216,9 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1214,9 +1216,9 @@ 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 = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->tx_ring_dma, gfp); bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp);
if (!bp->tx_ring) { if (!bp->tx_ring) {
/* Allocation may have failed due to dma_alloc_coherent /* 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
than necessary... */ than necessary... */
struct dma_desc *tx_ring; struct dma_desc *tx_ring;
...@@ -1226,11 +1228,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) ...@@ -1226,11 +1228,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 = dma_map_single(bp->sdev->dma_dev, tx_ring, tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (dma_mapping_error(tx_ring_dma) || if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
tx_ring_dma + size > DMA_30BIT_MASK) { tx_ring_dma + size > DMA_30BIT_MASK) {
kfree(tx_ring); kfree(tx_ring);
goto out_err; goto out_err;
......
...@@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len, ...@@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
* independent format * independent format
*/ */
static char *gelic_wl_translate_scan(struct net_device *netdev, static char *gelic_wl_translate_scan(struct net_device *netdev,
struct iw_request_info *info,
char *ev, char *ev,
char *stop, char *stop,
struct gelic_wl_scan_info *network) struct gelic_wl_scan_info *network)
...@@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN); ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_ADDR_LEN);
/* ESSID */ /* ESSID */
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
iwe.u.data.length = strnlen(scan->essid, 32); iwe.u.data.length = strnlen(scan->essid, 32);
ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
/* FREQUENCY */ /* FREQUENCY */
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = be16_to_cpu(scan->channel); iwe.u.freq.m = be16_to_cpu(scan->channel);
iwe.u.freq.e = 0; /* table value in MHz */ iwe.u.freq.e = 0; /* table value in MHz */
iwe.u.freq.i = 0; iwe.u.freq.i = 0;
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN); ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_FREQ_LEN);
/* RATES */ /* RATES */
iwe.cmd = SIOCGIWRATE; iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
/* to stuff multiple values in one event */ /* to stuff multiple values in one event */
tmp = ev + IW_EV_LCP_LEN; tmp = ev + iwe_stream_lcp_len(info);
/* put them in ascendant order (older is first) */ /* put them in ascendant order (older is first) */
i = 0; i = 0;
j = 0; j = 0;
...@@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else else
rate = scan->rate[i++] & 0x7f; rate = scan->rate[i++] & 0x7f;
iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */ iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
IW_EV_PARAM_LEN); IW_EV_PARAM_LEN);
} }
while (j < network->rate_ext_len) { while (j < network->rate_ext_len) {
iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000; iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
IW_EV_PARAM_LEN); IW_EV_PARAM_LEN);
} }
/* Check if we added any rate */ /* Check if we added any rate */
if (IW_EV_LCP_LEN < (tmp - ev)) if (iwe_stream_lcp_len(info) < (tmp - ev))
ev = tmp; ev = tmp;
/* ENCODE */ /* ENCODE */
...@@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
/* MODE */ /* MODE */
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
...@@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.u.mode = IW_MODE_MASTER; iwe.u.mode = IW_MODE_MASTER;
else else
iwe.u.mode = IW_MODE_ADHOC; iwe.u.mode = IW_MODE_ADHOC;
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN); ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_UINT_LEN);
} }
/* QUAL */ /* QUAL */
...@@ -659,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -659,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.u.qual.level = be16_to_cpu(scan->rssi); iwe.u.qual.level = be16_to_cpu(scan->rssi);
iwe.u.qual.qual = be16_to_cpu(scan->rssi); iwe.u.qual.qual = be16_to_cpu(scan->rssi);
iwe.u.qual.noise = 0; iwe.u.qual.noise = 0;
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN); ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_QUAL_LEN);
/* RSN */ /* RSN */
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
if (len) { if (len) {
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = len; iwe.u.data.length = len;
ev = iwe_stream_add_point(ev, stop, &iwe, buf); ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
} }
} else { } else {
/* this scan info has IE data */ /* this scan info has IE data */
...@@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.wpa.data, ie_info.wpa.len); memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = ie_info.wpa.len; iwe.u.data.length = ie_info.wpa.len;
ev = iwe_stream_add_point(ev, stop, &iwe, buf); ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
} }
if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) { if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
...@@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, ...@@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.rsn.data, ie_info.rsn.len); memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = ie_info.rsn.len; iwe.u.data.length = ie_info.rsn.len;
ev = iwe_stream_add_point(ev, stop, &iwe, buf); ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
} }
} }
...@@ -737,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev, ...@@ -737,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev,
if (wl->scan_age == 0 || if (wl->scan_age == 0 ||
time_after(scan_info->last_scanned + wl->scan_age, time_after(scan_info->last_scanned + wl->scan_age,
this_time)) this_time))
ev = gelic_wl_translate_scan(netdev, ev, stop, ev = gelic_wl_translate_scan(netdev, info,
ev, stop,
scan_info); scan_info);
else else
pr_debug("%s:entry too old\n", __func__); pr_debug("%s:entry too old\n", __func__);
......
...@@ -14,30 +14,6 @@ config WLAN_PRE80211 ...@@ -14,30 +14,6 @@ config WLAN_PRE80211
This option does not affect the kernel build, it only This option does not affect the kernel build, it only
lets you choose drivers. lets you choose drivers.
config STRIP
tristate "STRIP (Metricom starmode radio IP)"
depends on INET && WLAN_PRE80211
select WIRELESS_EXT
---help---
Say Y if you have a Metricom radio and intend to use Starmode Radio
IP. STRIP is a radio protocol developed for the MosquitoNet project
(on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet
traffic using Metricom radios. Metricom radios are small, battery
powered, 100kbit/sec packet radio transceivers, about the size and
weight of a cellular telephone. (You may also have heard them called
"Metricom modems" but we avoid the term "modem" because it misleads
many people into thinking that you can plug a Metricom modem into a
phone line and use it as a modem.)
You can use STRIP on any Linux machine with a serial port, although
it is obviously most useful for people with laptop computers. If you
think you might get a Metricom radio in the future, there is no harm
in saying Y to STRIP now, except that it makes the kernel a bit
bigger.
To compile this as a module, choose M here: the module will be
called strip.
config ARLAN config ARLAN
tristate "Aironet Arlan 655 & IC2200 DS support" tristate "Aironet Arlan 655 & IC2200 DS support"
depends on ISA && !64BIT && WLAN_PRE80211 depends on ISA && !64BIT && WLAN_PRE80211
......
...@@ -6,7 +6,6 @@ obj-$(CONFIG_IPW2100) += ipw2100.o ...@@ -6,7 +6,6 @@ obj-$(CONFIG_IPW2100) += ipw2100.o
obj-$(CONFIG_IPW2200) += ipw2200.o obj-$(CONFIG_IPW2200) += ipw2200.o
obj-$(CONFIG_STRIP) += strip.o
obj-$(CONFIG_ARLAN) += arlan.o obj-$(CONFIG_ARLAN) += arlan.o
arlan-objs := arlan-main.o arlan-proc.o arlan-objs := arlan-main.o arlan-proc.o
......
...@@ -1685,7 +1685,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1685,7 +1685,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{ {
struct adm8211_tx_hdr *txhdr; struct adm8211_tx_hdr *txhdr;
u16 fc;
size_t payload_len, hdrlen; size_t payload_len, hdrlen;
int plcp, dur, len, plcp_signal, short_preamble; int plcp, dur, len, plcp_signal, short_preamble;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
...@@ -1696,8 +1695,7 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ...@@ -1696,8 +1695,7 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
plcp_signal = txrate->bitrate; plcp_signal = txrate->bitrate;
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; hdrlen = ieee80211_hdrlen(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);
memcpy(skb->cb, skb->data, hdrlen); memcpy(skb->cb, skb->data, hdrlen);
hdr = (struct ieee80211_hdr *)skb->cb; hdr = (struct ieee80211_hdr *)skb->cb;
skb_pull(skb, hdrlen); skb_pull(skb, hdrlen);
...@@ -1711,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ...@@ -1711,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
txhdr->frame_control = hdr->frame_control; txhdr->frame_control = hdr->frame_control;
len = hdrlen + payload_len + FCS_LEN; len = hdrlen + payload_len + FCS_LEN;
if (fc & IEEE80211_FCTL_PROTECTED)
len += 8;
txhdr->frag = cpu_to_le16(0x0FFF); txhdr->frag = cpu_to_le16(0x0FFF);
adm8211_calc_durations(&dur, &plcp, payload_len, adm8211_calc_durations(&dur, &plcp, payload_len,
...@@ -1730,9 +1726,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ...@@ -1730,9 +1726,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
if (fc & IEEE80211_FCTL_PROTECTED)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE);
txhdr->retry_limit = info->control.retry_limit; txhdr->retry_limit = info->control.retry_limit;
adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
......
...@@ -85,10 +85,10 @@ static struct pci_driver airo_driver = { ...@@ -85,10 +85,10 @@ static struct pci_driver airo_driver = {
/* Include Wireless Extension definition and check version - Jean II */ /* Include Wireless Extension definition and check version - Jean II */
#include <linux/wireless.h> #include <linux/wireless.h>
#define WIRELESS_SPY // enable iwspy support #define WIRELESS_SPY /* enable iwspy support */
#include <net/iw_handler.h> // New driver API #include <net/iw_handler.h> /* New driver API */
#define CISCO_EXT // enable Cisco extensions #define CISCO_EXT /* enable Cisco extensions */
#ifdef CISCO_EXT #ifdef CISCO_EXT
#include <linux/delay.h> #include <linux/delay.h>
#endif #endif
...@@ -281,7 +281,7 @@ MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc"); ...@@ -281,7 +281,7 @@ MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
/* This is a kind of sloppy hack to get this information to OUT4500 and /* This is a kind of sloppy hack to get this information to OUT4500 and
IN4500. I would be extremely interested in the situation where this IN4500. I would be extremely interested in the situation where this
doesn't work though!!! */ doesn't work though!!! */
static int do8bitIO = 0; static int do8bitIO /* = 0 */;
/* Return codes */ /* Return codes */
#define SUCCESS 0 #define SUCCESS 0
...@@ -398,8 +398,8 @@ static int do8bitIO = 0; ...@@ -398,8 +398,8 @@ static int do8bitIO = 0;
#define MAXTXQ 64 #define MAXTXQ 64
/* BAP selectors */ /* BAP selectors */
#define BAP0 0 // Used for receiving packets #define BAP0 0 /* Used for receiving packets */
#define BAP1 2 // Used for xmiting packets and working with RIDS #define BAP1 2 /* Used for xmiting packets and working with RIDS */
/* Flags */ /* Flags */
#define COMMAND_BUSY 0x8000 #define COMMAND_BUSY 0x8000
...@@ -5522,11 +5522,13 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -5522,11 +5522,13 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
Cmd cmd; Cmd cmd;
Resp rsp; Resp rsp;
if ((ai->APList == NULL) && if (!ai->APList)
(ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL) ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL);
if (!ai->APList)
return -ENOMEM; return -ENOMEM;
if ((ai->SSID == NULL) && if (!ai->SSID)
(ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL) ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
if (!ai->SSID)
return -ENOMEM; return -ENOMEM;
readAPListRid(ai, ai->APList); readAPListRid(ai, ai->APList);
readSsidRid(ai, ai->SSID); readSsidRid(ai, ai->SSID);
...@@ -5537,7 +5539,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -5537,7 +5539,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
disable_MAC(ai, 0); disable_MAC(ai, 0);
netif_device_detach(dev); netif_device_detach(dev);
ai->power = state; ai->power = state;
cmd.cmd=HOSTSLEEP; cmd.cmd = HOSTSLEEP;
issuecommand(ai, &cmd, &rsp); issuecommand(ai, &cmd, &rsp);
pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
...@@ -5567,7 +5569,7 @@ static int airo_pci_resume(struct pci_dev *pdev) ...@@ -5567,7 +5569,7 @@ static int airo_pci_resume(struct pci_dev *pdev)
msleep(100); msleep(100);
} }
set_bit (FLAG_COMMIT, &ai->flags); set_bit(FLAG_COMMIT, &ai->flags);
disable_MAC(ai, 0); disable_MAC(ai, 0);
msleep(200); msleep(200);
if (ai->SSID) { if (ai->SSID) {
...@@ -5594,9 +5596,6 @@ static int airo_pci_resume(struct pci_dev *pdev) ...@@ -5594,9 +5596,6 @@ static int airo_pci_resume(struct pci_dev *pdev)
static int __init airo_init_module( void ) static int __init airo_init_module( void )
{ {
int i; int i;
#if 0
int have_isa_dev = 0;
#endif
airo_entry = create_proc_entry("driver/aironet", airo_entry = create_proc_entry("driver/aironet",
S_IFDIR | airo_perm, S_IFDIR | airo_perm,
...@@ -5607,15 +5606,11 @@ static int __init airo_init_module( void ) ...@@ -5607,15 +5606,11 @@ static int __init airo_init_module( void )
airo_entry->gid = proc_gid; airo_entry->gid = proc_gid;
} }
for( i = 0; i < 4 && io[i] && irq[i]; i++ ) { for (i = 0; i < 4 && io[i] && irq[i]; i++) {
airo_print_info("", "Trying to configure ISA adapter at irq=%d " airo_print_info("", "Trying to configure ISA adapter at irq=%d "
"io=0x%x", irq[i], io[i] ); "io=0x%x", irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL )) if (init_airo_card( irq[i], io[i], 0, NULL ))
#if 0
have_isa_dev = 1;
#else
/* do nothing */ ; /* do nothing */ ;
#endif
} }
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -5661,7 +5656,7 @@ static void __exit airo_cleanup_module( void ) ...@@ -5661,7 +5656,7 @@ static void __exit airo_cleanup_module( void )
static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi) static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
{ {
if( !rssi_rid ) if (!rssi_rid)
return 0; return 0;
return (0x100 - rssi_rid[rssi].rssidBm); return (0x100 - rssi_rid[rssi].rssidBm);
...@@ -5671,10 +5666,10 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm) ...@@ -5671,10 +5666,10 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
{ {
int i; int i;
if( !rssi_rid ) if (!rssi_rid)
return 0; return 0;
for( i = 0; i < 256; i++ ) for (i = 0; i < 256; i++)
if (rssi_rid[i].rssidBm == dbm) if (rssi_rid[i].rssidBm == dbm)
return rssi_rid[i].rssipct; return rssi_rid[i].rssipct;
...@@ -7156,6 +7151,7 @@ static int airo_set_scan(struct net_device *dev, ...@@ -7156,6 +7151,7 @@ static int airo_set_scan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II * format that the Wireless Tools will understand - Jean II
*/ */
static inline char *airo_translate_scan(struct net_device *dev, static inline char *airo_translate_scan(struct net_device *dev,
struct iw_request_info *info,
char *current_ev, char *current_ev,
char *end_buf, char *end_buf,
BSSListRid *bss) BSSListRid *bss)
...@@ -7172,7 +7168,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7172,7 +7168,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */ /* Other entries will be displayed in the order we give them */
...@@ -7182,7 +7179,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7182,7 +7179,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.data.length = 32; iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid);
/* Add mode */ /* Add mode */
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
...@@ -7192,7 +7190,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7192,7 +7190,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER; iwe.u.mode = IW_MODE_MASTER;
else else
iwe.u.mode = IW_MODE_ADHOC; iwe.u.mode = IW_MODE_ADHOC;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_UINT_LEN);
} }
/* Add frequency */ /* Add frequency */
...@@ -7203,7 +7202,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7203,7 +7202,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
*/ */
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000; iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
iwe.u.freq.e = 1; iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_FREQ_LEN);
dBm = le16_to_cpu(bss->dBm); dBm = le16_to_cpu(bss->dBm);
...@@ -7223,7 +7223,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7223,7 +7223,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
| IW_QUAL_DBM; | IW_QUAL_DBM;
} }
iwe.u.qual.noise = ai->wstats.qual.noise; iwe.u.qual.noise = ai->wstats.qual.noise;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */ /* Add encryption capability */
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
...@@ -7232,11 +7233,12 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7232,11 +7233,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit /* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */ * more of magic - Jean II */
current_val = current_ev + IW_EV_LCP_LEN; current_val = current_ev + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE; iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */ /* Those two flags are ignored... */
...@@ -7249,10 +7251,12 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7249,10 +7251,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Bit rate given in 500 kb/s units (+ 0x80) */ /* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000); iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */ /* Add new value to event */
current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); current_val = iwe_stream_add_value(info, current_ev,
current_val, end_buf,
&iwe, IW_EV_PARAM_LEN);
} }
/* Check if we added any event */ /* Check if we added any event */
if((current_val - current_ev) > IW_EV_LCP_LEN) if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val; current_ev = current_val;
/* Beacon interval */ /* Beacon interval */
...@@ -7261,7 +7265,8 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7261,7 +7265,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval); sprintf(buf, "bcn_int=%d", bss->beaconInterval);
iwe.u.data.length = strlen(buf); iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, buf);
kfree(buf); kfree(buf);
} }
...@@ -7295,8 +7300,10 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7295,8 +7300,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2, iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN); MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(
&iwe, (char *) info_element); info, current_ev,
end_buf, &iwe,
(char *) info_element);
} }
break; break;
...@@ -7304,8 +7311,9 @@ static inline char *airo_translate_scan(struct net_device *dev, ...@@ -7304,8 +7311,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2, iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN); MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(
&iwe, (char *) info_element); info, current_ev, end_buf,
&iwe, (char *) info_element);
break; break;
default: default:
...@@ -7344,7 +7352,7 @@ static int airo_get_scan(struct net_device *dev, ...@@ -7344,7 +7352,7 @@ static int airo_get_scan(struct net_device *dev,
list_for_each_entry (net, &ai->network_list, list) { list_for_each_entry (net, &ai->network_list, list) {
/* Translate to WE format this entry */ /* Translate to WE format this entry */
current_ev = airo_translate_scan(dev, current_ev, current_ev = airo_translate_scan(dev, info, current_ev,
extra + dwrq->length, extra + dwrq->length,
&net->bss); &net->bss);
......
config ATH5K config ATH5K
tristate "Atheros 5xxx wireless cards support" tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros 5xxx chipset. Atheros 5xxx chipset.
......
...@@ -58,11 +58,6 @@ ...@@ -58,11 +58,6 @@
#include "reg.h" #include "reg.h"
#include "debug.h" #include "debug.h"
enum {
ATH_LED_TX,
ATH_LED_RX,
};
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
...@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data); ...@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data); static void ath5k_calibrate(unsigned long data);
/* LED functions */ /* LED functions */
static void ath5k_led_off(unsigned long data); static int ath5k_init_leds(struct ath5k_softc *sc);
static void ath5k_led_blink(struct ath5k_softc *sc, static void ath5k_led_enable(struct ath5k_softc *sc);
unsigned int on, static void ath5k_led_off(struct ath5k_softc *sc);
unsigned int off); static void ath5k_unregister_leds(struct ath5k_softc *sc);
static void ath5k_led_event(struct ath5k_softc *sc,
int event);
/* /*
* Module init/exit functions * Module init/exit functions
...@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath5k_softc *sc = hw->priv; struct ath5k_softc *sc = hw->priv;
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) ath5k_led_off(sc);
ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
ath5k_stop_hw(sc); ath5k_stop_hw(sc);
pci_save_state(pdev); pci_save_state(pdev);
...@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev) ...@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0); pci_write_config_byte(pdev, 0x41, 0);
ath5k_init(sc); ath5k_init(sc);
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { ath5k_led_enable(sc);
ath5k_hw_set_gpio_output(ah, sc->led_pin);
ath5k_hw_set_gpio(ah, sc->led_pin, 0);
}
/* /*
* Reset the key cache since some parts do not * Reset the key cache since some parts do not
...@@ -742,27 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -742,27 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc); setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc);
sc->led_on = 0; /* low true */
/*
* Auto-enable soft led processing for IBM cards and for
* 5211 minipci cards.
*/
if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 0;
}
/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 0;
}
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
ath5k_hw_set_gpio_output(ah, sc->led_pin);
ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
}
ath5k_hw_get_lladdr(ah, mac); ath5k_hw_get_lladdr(ah, mac);
SET_IEEE80211_PERM_ADDR(hw, mac); SET_IEEE80211_PERM_ADDR(hw, mac);
...@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
goto err_queues; goto err_queues;
} }
ath5k_init_leds(sc);
return 0; return 0;
err_queues: err_queues:
ath5k_txq_release(sc); ath5k_txq_release(sc);
...@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_desc_free(sc, pdev); ath5k_desc_free(sc, pdev);
ath5k_txq_release(sc); ath5k_txq_release(sc);
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
ath5k_unregister_leds(sc);
/* /*
* NB: can't reclaim these until after ieee80211_ifdetach * NB: can't reclaim these until after ieee80211_ifdetach
...@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) ...@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
return 0; return 0;
} }
/*
* TODO: CLEAN THIS !!!
*/
static void static void
ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
{ {
if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) {
/* from Atheros NDIS driver, w/ permission */
static const struct {
u16 rate; /* tx/rx 802.11 rate */
u16 timeOn; /* LED on time (ms) */
u16 timeOff; /* LED off time (ms) */
} blinkrates[] = {
{ 108, 40, 10 },
{ 96, 44, 11 },
{ 72, 50, 13 },
{ 48, 57, 14 },
{ 36, 67, 16 },
{ 24, 80, 20 },
{ 22, 100, 25 },
{ 18, 133, 34 },
{ 12, 160, 40 },
{ 10, 200, 50 },
{ 6, 240, 58 },
{ 4, 267, 66 },
{ 2, 400, 100 },
{ 0, 500, 130 }
};
const struct ath5k_rate_table *rt =
ath5k_hw_get_rate_table(sc->ah, mode);
unsigned int i, j;
BUG_ON(rt == NULL);
memset(sc->hwmap, 0, sizeof(sc->hwmap));
for (i = 0; i < 32; i++) {
u8 ix = rt->rate_code_to_index[i];
if (ix == 0xff) {
sc->hwmap[i].ledon = msecs_to_jiffies(500);
sc->hwmap[i].ledoff = msecs_to_jiffies(130);
continue;
}
sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
/* receive frames include FCS */
sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
IEEE80211_RADIOTAP_F_FCS;
/* setup blink rate table to avoid per-packet lookup */
for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++)
if (blinkrates[j].rate == /* XXX why 7f? */
(rt->rates[ix].dot11_rate&0x7f))
break;
sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].
timeOn);
sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].
timeOff);
}
}
sc->curmode = mode; sc->curmode = mode;
if (mode == AR5K_MODE_11A) { if (mode == AR5K_MODE_11A) {
...@@ -1691,9 +1605,9 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, ...@@ -1691,9 +1605,9 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
/* Apparently when a default key is used to decrypt the packet /* Apparently when a default key is used to decrypt the packet
the hw does not set the index used to decrypt. In such cases the hw does not set the index used to decrypt. In such cases
get the index from the packet. */ get the index from the packet. */
if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && if (ieee80211_has_protected(hdr->frame_control) &&
!(rs->rs_status & AR5K_RXERR_DECRYPT) && !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
skb->len >= hlen + 4) { skb->len >= hlen + 4) {
keyix = skb->data[hlen + 3] >> 6; keyix = skb->data[hlen + 3] >> 6;
if (test_bit(keyix, sc->keymap)) if (test_bit(keyix, sc->keymap))
...@@ -1712,10 +1626,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, ...@@ -1712,10 +1626,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
u32 hw_tu; u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) == if (ieee80211_is_beacon(mgmt->frame_control) &&
IEEE80211_FTYPE_MGMT &&
(le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) ==
IEEE80211_STYPE_BEACON &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
/* /*
...@@ -1903,8 +1814,6 @@ ath5k_tasklet_rx(unsigned long data) ...@@ -1903,8 +1814,6 @@ ath5k_tasklet_rx(unsigned long data)
ath5k_check_ibss_tsf(sc, skb, &rxs); ath5k_check_ibss_tsf(sc, skb, &rxs);
__ieee80211_rx(sc->hw, skb, &rxs); __ieee80211_rx(sc->hw, skb, &rxs);
sc->led_rxrate = rs.rs_rate;
ath5k_led_event(sc, ATH_LED_RX);
next: next:
list_move_tail(&bf->list, &sc->rxbuf); list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0); } while (ath5k_rxbuf_setup(sc, bf) == 0);
...@@ -1985,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data) ...@@ -1985,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data)
struct ath5k_softc *sc = (void *)data; struct ath5k_softc *sc = (void *)data;
ath5k_tx_processq(sc, sc->txq); ath5k_tx_processq(sc, sc->txq);
ath5k_led_event(sc, ATH_LED_TX);
} }
/*****************\ /*****************\
* Beacon handling * * Beacon handling *
\*****************/ \*****************/
...@@ -2366,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) ...@@ -2366,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
ieee80211_stop_queues(sc->hw); ieee80211_stop_queues(sc->hw);
if (!test_bit(ATH_STAT_INVALID, sc->status)) { if (!test_bit(ATH_STAT_INVALID, sc->status)) {
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { ath5k_led_off(sc);
del_timer_sync(&sc->led_tim);
ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
__clear_bit(ATH_STAT_LEDBLINKING, sc->status);
}
ath5k_hw_set_intr(ah, 0); ath5k_hw_set_intr(ah, 0);
} }
ath5k_txq_cleanup(sc); ath5k_txq_cleanup(sc);
...@@ -2566,55 +2467,124 @@ ath5k_calibrate(unsigned long data) ...@@ -2566,55 +2467,124 @@ ath5k_calibrate(unsigned long data)
\***************/ \***************/
static void static void
ath5k_led_off(unsigned long data) ath5k_led_enable(struct ath5k_softc *sc)
{ {
struct ath5k_softc *sc = (void *)data; if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
if (test_bit(ATH_STAT_LEDENDBLINK, sc->status)) ath5k_led_off(sc);
__clear_bit(ATH_STAT_LEDBLINKING, sc->status);
else {
__set_bit(ATH_STAT_LEDENDBLINK, sc->status);
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
mod_timer(&sc->led_tim, jiffies + sc->led_off);
} }
} }
/*
* Blink the LED according to the specified on/off times.
*/
static void static void
ath5k_led_blink(struct ath5k_softc *sc, unsigned int on, ath5k_led_on(struct ath5k_softc *sc)
unsigned int off)
{ {
ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off); if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on); ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
__set_bit(ATH_STAT_LEDBLINKING, sc->status);
__clear_bit(ATH_STAT_LEDENDBLINK, sc->status);
sc->led_off = off;
mod_timer(&sc->led_tim, jiffies + on);
} }
static void static void
ath5k_led_event(struct ath5k_softc *sc, int event) ath5k_led_off(struct ath5k_softc *sc)
{ {
if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status))) if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return; return;
if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status))) ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
return; /* don't interrupt active blink */ }
switch (event) {
case ATH_LED_TX: static void
ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon, ath5k_led_brightness_set(struct led_classdev *led_dev,
sc->hwmap[sc->led_txrate].ledoff); enum led_brightness brightness)
break; {
case ATH_LED_RX: struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon, led_dev);
sc->hwmap[sc->led_rxrate].ledoff);
break; if (brightness == LED_OFF)
ath5k_led_off(led->sc);
else
ath5k_led_on(led->sc);
}
static int
ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
const char *name, char *trigger)
{
int err;
led->sc = sc;
strncpy(led->name, name, sizeof(led->name));
led->led_dev.name = led->name;
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = ath5k_led_brightness_set;
err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
if (err)
{
ATH5K_WARN(sc, "could not register LED %s\n", name);
led->sc = NULL;
} }
return err;
}
static void
ath5k_unregister_led(struct ath5k_led *led)
{
if (!led->sc)
return;
led_classdev_unregister(&led->led_dev);
ath5k_led_off(led->sc);
led->sc = NULL;
} }
static void
ath5k_unregister_leds(struct ath5k_softc *sc)
{
ath5k_unregister_led(&sc->rx_led);
ath5k_unregister_led(&sc->tx_led);
}
static int
ath5k_init_leds(struct ath5k_softc *sc)
{
int ret = 0;
struct ieee80211_hw *hw = sc->hw;
struct pci_dev *pdev = sc->pdev;
char name[ATH5K_LED_MAX_NAME_LEN + 1];
sc->led_on = 0; /* active low */
/*
* Auto-enable soft led processing for IBM cards and for
* 5211 minipci cards.
*/
if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 0;
}
/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 1;
}
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
goto out;
ath5k_led_enable(sc);
snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->rx_led, name,
ieee80211_get_rx_led_name(hw));
if (ret)
goto out;
snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->tx_led, name,
ieee80211_get_tx_led_name(hw));
out:
return ret;
}
/********************\ /********************\
* Mac80211 functions * * Mac80211 functions *
...@@ -2625,7 +2595,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -2625,7 +2595,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct ath5k_softc *sc = hw->priv; struct ath5k_softc *sc = hw->priv;
struct ath5k_buf *bf; struct ath5k_buf *bf;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned long flags; unsigned long flags;
int hdrlen; int hdrlen;
int pad; int pad;
...@@ -2651,8 +2620,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -2651,8 +2620,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
memmove(skb->data, skb->data+pad, hdrlen); memmove(skb->data, skb->data+pad, hdrlen);
} }
sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value;
spin_lock_irqsave(&sc->txbuflock, flags); spin_lock_irqsave(&sc->txbuflock, flags);
if (list_empty(&sc->txbuf)) { if (list_empty(&sc->txbuf)) {
ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/leds.h>
#include "ath5k.h" #include "ath5k.h"
#include "debug.h" #include "debug.h"
...@@ -79,6 +80,19 @@ struct ath5k_txq { ...@@ -79,6 +80,19 @@ struct ath5k_txq {
bool setup; bool setup;
}; };
#define ATH5K_LED_MAX_NAME_LEN 31
/*
* State for LED triggers
*/
struct ath5k_led
{
char name[ATH5K_LED_MAX_NAME_LEN + 1]; /* name of the LED in sysfs */
struct ath5k_softc *sc; /* driver state */
struct led_classdev led_dev; /* led classdev */
};
#if CHAN_DEBUG #if CHAN_DEBUG
#define ATH_CHAN_MAX (26+26+26+200+200) #define ATH_CHAN_MAX (26+26+26+200+200)
#else #else
...@@ -118,13 +132,11 @@ struct ath5k_softc { ...@@ -118,13 +132,11 @@ struct ath5k_softc {
size_t desc_len; /* size of TX/RX descriptors */ size_t desc_len; /* size of TX/RX descriptors */
u16 cachelsz; /* cache line size */ u16 cachelsz; /* cache line size */
DECLARE_BITMAP(status, 6); DECLARE_BITMAP(status, 4);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */ #define ATH_STAT_INVALID 0 /* disable hardware accesses */
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
#define ATH_STAT_PROMISC 2 #define ATH_STAT_PROMISC 2
#define ATH_STAT_LEDBLINKING 3 /* LED blink operation active */ #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
#define ATH_STAT_LEDENDBLINK 4 /* finish LED blink operation */
#define ATH_STAT_LEDSOFT 5 /* enable LED gpio status */
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
unsigned int curmode; /* current phy mode */ unsigned int curmode; /* current phy mode */
...@@ -132,13 +144,6 @@ struct ath5k_softc { ...@@ -132,13 +144,6 @@ struct ath5k_softc {
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct {
u8 rxflags; /* radiotap rx flags */
u8 txflags; /* radiotap tx flags */
u16 ledon; /* softled on time */
u16 ledoff; /* softled off time */
} hwmap[32]; /* h/w rate ix mappings */
enum ath5k_int imask; /* interrupt mask copy */ enum ath5k_int imask; /* interrupt mask copy */
DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */ DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
...@@ -148,9 +153,6 @@ struct ath5k_softc { ...@@ -148,9 +153,6 @@ struct ath5k_softc {
unsigned int led_pin, /* GPIO pin for driving LED */ unsigned int led_pin, /* GPIO pin for driving LED */
led_on, /* pin setting for LED on */ led_on, /* pin setting for LED on */
led_off; /* off time for current blink */ led_off; /* off time for current blink */
struct timer_list led_tim; /* led off timer */
u8 led_rxrate; /* current rx rate for LED */
u8 led_txrate; /* current tx rate for LED */
struct tasklet_struct restq; /* reset tasklet */ struct tasklet_struct restq; /* reset tasklet */
...@@ -159,6 +161,7 @@ struct ath5k_softc { ...@@ -159,6 +161,7 @@ struct ath5k_softc {
spinlock_t rxbuflock; spinlock_t rxbuflock;
u32 *rxlink; /* link ptr in last RX desc */ u32 *rxlink; /* link ptr in last RX desc */
struct tasklet_struct rxtq; /* rx intr tasklet */ struct tasklet_struct rxtq; /* rx intr tasklet */
struct ath5k_led rx_led; /* rx led */
struct list_head txbuf; /* transmit buffer */ struct list_head txbuf; /* transmit buffer */
spinlock_t txbuflock; spinlock_t txbuflock;
...@@ -167,6 +170,7 @@ struct ath5k_softc { ...@@ -167,6 +170,7 @@ struct ath5k_softc {
struct ath5k_txq *txq; /* beacon and tx*/ struct ath5k_txq *txq; /* beacon and tx*/
struct tasklet_struct txtq; /* tx intr tasklet */ struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */
struct ath5k_buf *bbuf; /* beacon buffer */ struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */ unsigned int bhalq, /* SW q for outgoing beacons */
......
...@@ -31,14 +31,14 @@ ...@@ -31,14 +31,14 @@
#include "base.h" #include "base.h"
#include "debug.h" #include "debug.h"
/*Rate tables*/ /* Rate tables */
static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A; static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B; static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B;
static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G; static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G;
static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO; static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO;
static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR; static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR;
/*Prototypes*/ /* Prototypes */
static int ath5k_hw_nic_reset(struct ath5k_hw *, u32); static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool); static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
......
...@@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev, ...@@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.u.data.length = priv->BSSinfo[i].SSIDsize; iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
if (iwe.u.data.length > 32) if (iwe.u.data.length > 32)
iwe.u.data.length = 32; iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID); current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, priv->BSSinfo[i].SSID);
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
iwe.u.mode = priv->BSSinfo[i].BSStype; iwe.u.mode = priv->BSSinfo[i].BSStype;
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN); current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = priv->BSSinfo[i].channel; iwe.u.freq.m = priv->BSSinfo[i].channel;
iwe.u.freq.e = 0; iwe.u.freq.e = 0;
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN); current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */ /* Add quality statistics */
iwe.cmd = IWEVQUAL; iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI; iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level; iwe.u.qual.qual = iwe.u.qual.level;
/* iwe.u.qual.noise = SOMETHING */ /* iwe.u.qual.noise = SOMETHING */
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN); current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_QUAL_LEN);
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
...@@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev, ...@@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev,
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL); current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
} }
/* Length of data */ /* Length of data */
......
...@@ -441,6 +441,8 @@ enum { ...@@ -441,6 +441,8 @@ enum {
#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */ #define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */ #define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
/* The firmware register that contains the watchdog counter. */
#define B43_WATCHDOG_REG 1
/* Device specific rate values. /* Device specific rate values.
* The actual values defined here are (rate_in_mbps * 2). * The actual values defined here are (rate_in_mbps * 2).
......
...@@ -74,70 +74,327 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev, ...@@ -74,70 +74,327 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
} while (0) } while (0)
/* wl->irq_lock is locked */ /* The biggest address values for SHM access from the debugfs files. */
static ssize_t tsf_read_file(struct b43_wldev *dev, #define B43_MAX_SHM_ROUTING 4
char *buf, size_t bufsize) #define B43_MAX_SHM_ADDR 0xFFFF
static ssize_t shm16read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{ {
ssize_t count = 0; ssize_t count = 0;
u64 tsf; unsigned int routing, addr;
u16 val;
b43_tsf_read(dev, &tsf); routing = dev->dfsentry->shm16read_routing_next;
fappend("0x%08x%08x\n", addr = dev->dfsentry->shm16read_addr_next;
(unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), if ((routing > B43_MAX_SHM_ROUTING) ||
(unsigned int)(tsf & 0xFFFFFFFFULL)); (addr > B43_MAX_SHM_ADDR))
return -EDESTADDRREQ;
val = b43_shm_read16(dev, routing, addr);
fappend("0x%04X\n", val);
return count; return count;
} }
/* wl->irq_lock is locked */ static int shm16read__write_file(struct b43_wldev *dev,
static int tsf_write_file(struct b43_wldev *dev, const char *buf, size_t count)
const char *buf, size_t count)
{ {
u64 tsf; unsigned int routing, addr;
int res;
if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
if (res != 2)
return -EINVAL; return -EINVAL;
b43_tsf_write(dev, tsf); if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
dev->dfsentry->shm16read_routing_next = routing;
dev->dfsentry->shm16read_addr_next = addr;
return 0; return 0;
} }
/* wl->irq_lock is locked */ static int shm16write__write_file(struct b43_wldev *dev,
static ssize_t ucode_regs_read_file(struct b43_wldev *dev, const char *buf, size_t count)
{
unsigned int routing, addr, mask, set;
u16 val;
int res;
unsigned long flags;
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
&routing, &addr, &mask, &set);
if (res != 4)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
if ((mask > 0xFFFF) || (set > 0xFFFF))
return -E2BIG;
spin_lock_irqsave(&dev->wl->shm_lock, flags);
if (mask == 0)
val = 0;
else
val = __b43_shm_read16(dev, routing, addr);
val &= mask;
val |= set;
__b43_shm_write16(dev, routing, addr, val);
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
return 0;
}
static ssize_t shm32read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize) char *buf, size_t bufsize)
{ {
ssize_t count = 0; ssize_t count = 0;
int i; unsigned int routing, addr;
u32 val;
routing = dev->dfsentry->shm32read_routing_next;
addr = dev->dfsentry->shm32read_addr_next;
if ((routing > B43_MAX_SHM_ROUTING) ||
(addr > B43_MAX_SHM_ADDR))
return -EDESTADDRREQ;
for (i = 0; i < 64; i++) { val = b43_shm_read32(dev, routing, addr);
fappend("r%d = 0x%04x\n", i, fappend("0x%08X\n", val);
b43_shm_read16(dev, B43_SHM_SCRATCH, i));
return count;
}
static int shm32read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int routing, addr;
int res;
res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
if (res != 2)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
dev->dfsentry->shm32read_routing_next = routing;
dev->dfsentry->shm32read_addr_next = addr;
return 0;
}
static int shm32write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int routing, addr, mask, set;
u32 val;
int res;
unsigned long flags;
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
&routing, &addr, &mask, &set);
if (res != 4)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
} }
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
return -E2BIG;
spin_lock_irqsave(&dev->wl->shm_lock, flags);
if (mask == 0)
val = 0;
else
val = __b43_shm_read32(dev, routing, addr);
val &= mask;
val |= set;
__b43_shm_write32(dev, routing, addr, val);
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
return 0;
}
/* The biggest MMIO address that we allow access to from the debugfs files. */
#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
static ssize_t mmio16read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
unsigned int addr;
u16 val;
addr = dev->dfsentry->mmio16read_next;
if (addr > B43_MAX_MMIO_ACCESS)
return -EDESTADDRREQ;
val = b43_read16(dev, addr);
fappend("0x%04X\n", val);
return count;
}
static int mmio16read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr;
int res;
res = sscanf(buf, "0x%X", &addr);
if (res != 1)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((addr % 2) != 0)
return -EINVAL;
dev->dfsentry->mmio16read_next = addr;
return 0;
}
static int mmio16write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr, mask, set;
int res;
u16 val;
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
if (res != 3)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((mask > 0xFFFF) || (set > 0xFFFF))
return -E2BIG;
if ((addr % 2) != 0)
return -EINVAL;
if (mask == 0)
val = 0;
else
val = b43_read16(dev, addr);
val &= mask;
val |= set;
b43_write16(dev, addr, val);
return 0;
}
static ssize_t mmio32read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
unsigned int addr;
u32 val;
addr = dev->dfsentry->mmio32read_next;
if (addr > B43_MAX_MMIO_ACCESS)
return -EDESTADDRREQ;
val = b43_read32(dev, addr);
fappend("0x%08X\n", val);
return count; return count;
} }
static int mmio32read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr;
int res;
res = sscanf(buf, "0x%X", &addr);
if (res != 1)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((addr % 4) != 0)
return -EINVAL;
dev->dfsentry->mmio32read_next = addr;
return 0;
}
static int mmio32write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr, mask, set;
int res;
u32 val;
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
if (res != 3)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
return -E2BIG;
if ((addr % 4) != 0)
return -EINVAL;
if (mask == 0)
val = 0;
else
val = b43_read32(dev, addr);
val &= mask;
val |= set;
b43_write32(dev, addr, val);
return 0;
}
/* wl->irq_lock is locked */ /* wl->irq_lock is locked */
static ssize_t shm_read_file(struct b43_wldev *dev, static ssize_t tsf_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize) char *buf, size_t bufsize)
{ {
ssize_t count = 0; ssize_t count = 0;
int i; u64 tsf;
u16 tmp;
__le16 *le16buf = (__le16 *)buf;
for (i = 0; i < 0x1000; i++) { b43_tsf_read(dev, &tsf);
if (bufsize < sizeof(tmp)) fappend("0x%08x%08x\n",
break; (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i); (unsigned int)(tsf & 0xFFFFFFFFULL));
le16buf[i] = cpu_to_le16(tmp);
count += sizeof(tmp);
bufsize -= sizeof(tmp);
}
return count; return count;
} }
/* wl->irq_lock is locked */
static int tsf_write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
u64 tsf;
if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
return -EINVAL;
b43_tsf_write(dev, tsf);
return 0;
}
static ssize_t txstat_read_file(struct b43_wldev *dev, static ssize_t txstat_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize) char *buf, size_t bufsize)
{ {
...@@ -496,9 +753,15 @@ static ssize_t b43_debugfs_write(struct file *file, ...@@ -496,9 +753,15 @@ static ssize_t b43_debugfs_write(struct file *file,
.take_irqlock = _take_irqlock, \ .take_irqlock = _take_irqlock, \
} }
B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0); B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
...@@ -538,6 +801,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev) ...@@ -538,6 +801,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0); add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0);
add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0);
add_dyn_dbg("debug_lo", B43_DBG_LO, 0); add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
#undef add_dyn_dbg #undef add_dyn_dbg
} }
...@@ -584,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev) ...@@ -584,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
return; return;
} }
e->mmio16read_next = 0xFFFF; /* invalid address */
e->mmio32read_next = 0xFFFF; /* invalid address */
e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
#define ADD_FILE(name, mode) \ #define ADD_FILE(name, mode) \
do { \ do { \
struct dentry *d; \ struct dentry *d; \
...@@ -596,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev) ...@@ -596,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
} while (0) } while (0)
ADD_FILE(shm16read, 0600);
ADD_FILE(shm16write, 0200);
ADD_FILE(shm32read, 0600);
ADD_FILE(shm32write, 0200);
ADD_FILE(mmio16read, 0600);
ADD_FILE(mmio16write, 0200);
ADD_FILE(mmio32read, 0600);
ADD_FILE(mmio32write, 0200);
ADD_FILE(tsf, 0600); ADD_FILE(tsf, 0600);
ADD_FILE(ucode_regs, 0400);
ADD_FILE(shm, 0400);
ADD_FILE(txstat, 0400); ADD_FILE(txstat, 0400);
ADD_FILE(txpower_g, 0600); ADD_FILE(txpower_g, 0600);
ADD_FILE(restart, 0200); ADD_FILE(restart, 0200);
...@@ -620,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev) ...@@ -620,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
return; return;
b43_remove_dynamic_debug(dev); b43_remove_dynamic_debug(dev);
debugfs_remove(e->file_shm16read.dentry);
debugfs_remove(e->file_shm16write.dentry);
debugfs_remove(e->file_shm32read.dentry);
debugfs_remove(e->file_shm32write.dentry);
debugfs_remove(e->file_mmio16read.dentry);
debugfs_remove(e->file_mmio16write.dentry);
debugfs_remove(e->file_mmio32read.dentry);
debugfs_remove(e->file_mmio32write.dentry);
debugfs_remove(e->file_tsf.dentry); debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_ucode_regs.dentry);
debugfs_remove(e->file_shm.dentry);
debugfs_remove(e->file_txstat.dentry); debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_txpower_g.dentry); debugfs_remove(e->file_txpower_g.dentry);
debugfs_remove(e->file_restart.dentry); debugfs_remove(e->file_restart.dentry);
......
...@@ -11,6 +11,7 @@ enum b43_dyndbg { /* Dynamic debugging features */ ...@@ -11,6 +11,7 @@ enum b43_dyndbg { /* Dynamic debugging features */
B43_DBG_PWORK_FAST, B43_DBG_PWORK_FAST,
B43_DBG_PWORK_STOP, B43_DBG_PWORK_STOP,
B43_DBG_LO, B43_DBG_LO,
B43_DBG_FIRMWARE,
__B43_NR_DYNDBG, __B43_NR_DYNDBG,
}; };
...@@ -36,9 +37,15 @@ struct b43_dfsentry { ...@@ -36,9 +37,15 @@ struct b43_dfsentry {
struct b43_wldev *dev; struct b43_wldev *dev;
struct dentry *subdir; struct dentry *subdir;
struct b43_dfs_file file_shm16read;
struct b43_dfs_file file_shm16write;
struct b43_dfs_file file_shm32read;
struct b43_dfs_file file_shm32write;
struct b43_dfs_file file_mmio16read;
struct b43_dfs_file file_mmio16write;
struct b43_dfs_file file_mmio32read;
struct b43_dfs_file file_mmio32write;
struct b43_dfs_file file_tsf; struct b43_dfs_file file_tsf;
struct b43_dfs_file file_ucode_regs;
struct b43_dfs_file file_shm;
struct b43_dfs_file file_txstat; struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g; struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart; struct b43_dfs_file file_restart;
...@@ -46,6 +53,18 @@ struct b43_dfsentry { ...@@ -46,6 +53,18 @@ struct b43_dfsentry {
struct b43_txstatus_log txstatlog; struct b43_txstatus_log txstatlog;
/* The cached address for the next mmio16read file read */
u16 mmio16read_next;
/* The cached address for the next mmio32read file read */
u16 mmio32read_next;
/* The cached address for the next shm16read file read */
u32 shm16read_routing_next;
u32 shm16read_addr_next;
/* The cached address for the next shm32read file read */
u32 shm32read_routing_next;
u32 shm32read_addr_next;
/* Enabled/Disabled list for the dynamic debugging features. */ /* Enabled/Disabled list for the dynamic debugging features. */
u32 dyn_debug[__B43_NR_DYNDBG]; u32 dyn_debug[__B43_NR_DYNDBG];
/* Dentries for the dynamic debugging entries. */ /* Dentries for the dynamic debugging entries. */
......
...@@ -328,11 +328,11 @@ static inline ...@@ -328,11 +328,11 @@ static inline
dma_addr_t dmaaddr; dma_addr_t dmaaddr;
if (tx) { if (tx) {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_TO_DEVICE); buf, len, DMA_TO_DEVICE);
} else { } else {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_FROM_DEVICE); buf, len, DMA_FROM_DEVICE);
} }
return dmaaddr; return dmaaddr;
...@@ -343,11 +343,11 @@ static inline ...@@ -343,11 +343,11 @@ static inline
dma_addr_t addr, size_t len, int tx) dma_addr_t addr, size_t len, int tx)
{ {
if (tx) { if (tx) {
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_TO_DEVICE); addr, len, DMA_TO_DEVICE);
} else { } else {
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
} }
...@@ -356,8 +356,8 @@ static inline ...@@ -356,8 +356,8 @@ static inline
dma_addr_t addr, size_t len) dma_addr_t addr, size_t len)
{ {
B43_WARN_ON(ring->tx); B43_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -365,8 +365,8 @@ static inline ...@@ -365,8 +365,8 @@ static inline
dma_addr_t addr, size_t len) dma_addr_t addr, size_t len)
{ {
B43_WARN_ON(ring->tx); B43_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -381,7 +381,6 @@ static inline ...@@ -381,7 +381,6 @@ static inline
static int alloc_ringmemory(struct b43_dmaring *ring) static int alloc_ringmemory(struct b43_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev;
gfp_t flags = GFP_KERNEL; gfp_t flags = GFP_KERNEL;
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
...@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring) ...@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
* For unknown reasons - possibly a hardware error - the BCM4311 rev * For unknown reasons - possibly a hardware error - the BCM4311 rev
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory, * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
* which accounts for the GFP_DMA flag below. * which accounts for the GFP_DMA flag below.
*
* The flags here must match the flags in free_ringmemory below!
*/ */
if (ring->type == B43_DMA_64BIT) if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA; flags |= GFP_DMA;
ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
&(ring->dmabase), flags); B43_DMA_RINGMEMSIZE,
&(ring->dmabase), flags);
if (!ring->descbase) { if (!ring->descbase) {
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring) ...@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; gfp_t flags = GFP_KERNEL;
if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA;
dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE, ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase); ring->descbase, ring->dmabase, flags);
} }
/* Reset the RX DMA channel */ /* Reset the RX DMA channel */
...@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, ...@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
dma_addr_t addr, dma_addr_t addr,
size_t buffersize, bool dma_to_device) size_t buffersize, bool dma_to_device)
{ {
if (unlikely(dma_mapping_error(addr))) if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1; return 1;
switch (ring->type) { switch (ring->type) {
...@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
goto err_kfree_meta; goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */ /* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
b43_txhdr_size(dev), b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test, if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) { b43_txhdr_size(dev), 1)) {
...@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (!ring->txhdr_cache) if (!ring->txhdr_cache)
goto err_kfree_meta; goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
b43_txhdr_size(dev), b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test, if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) { b43_txhdr_size(dev), 1)) {
...@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
} }
} }
dma_unmap_single(dev->dev->dma_dev, ssb_dma_unmap_single(dev->dev,
dma_test, b43_txhdr_size(dev), dma_test, b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
err = alloc_ringmemory(ring); err = alloc_ringmemory(ring);
......
...@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev, ...@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
b43_write32(dev, B43_MMIO_SHM_CONTROL, control); b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
} }
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{ {
struct b43_wl *wl = dev->wl;
unsigned long flags;
u32 ret; u32 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) { if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001); B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) { if (offset & 0x0003) {
...@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) ...@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset); b43_shm_control_word(dev, routing, offset);
ret = b43_read32(dev, B43_MMIO_SHM_DATA); ret = b43_read32(dev, B43_MMIO_SHM_DATA);
out: out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret; return ret;
} }
u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{ {
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
unsigned long flags; unsigned long flags;
u16 ret; u32 ret;
spin_lock_irqsave(&wl->shm_lock, flags); spin_lock_irqsave(&wl->shm_lock, flags);
ret = __b43_shm_read32(dev, routing, offset);
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret;
}
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
{
u16 ret;
if (routing == B43_SHM_SHARED) { if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001); B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) { if (offset & 0x0003) {
...@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) ...@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset); b43_shm_control_word(dev, routing, offset);
ret = b43_read16(dev, B43_MMIO_SHM_DATA); ret = b43_read16(dev, B43_MMIO_SHM_DATA);
out: out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret; return ret;
} }
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
{ {
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
unsigned long flags; unsigned long flags;
u16 ret;
spin_lock_irqsave(&wl->shm_lock, flags); spin_lock_irqsave(&wl->shm_lock, flags);
ret = __b43_shm_read16(dev, routing, offset);
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret;
}
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{
if (routing == B43_SHM_SHARED) { if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001); B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) { if (offset & 0x0003) {
...@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) ...@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
(value >> 16) & 0xffff); (value >> 16) & 0xffff);
b43_shm_control_word(dev, routing, (offset >> 2) + 1); b43_shm_control_word(dev, routing, (offset >> 2) + 1);
b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
goto out; return;
} }
offset >>= 2; offset >>= 2;
} }
b43_shm_control_word(dev, routing, offset); b43_shm_control_word(dev, routing, offset);
b43_write32(dev, B43_MMIO_SHM_DATA, value); b43_write32(dev, B43_MMIO_SHM_DATA, value);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
} }
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{ {
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&wl->shm_lock, flags); spin_lock_irqsave(&wl->shm_lock, flags);
__b43_shm_write32(dev, routing, offset, value);
spin_unlock_irqrestore(&wl->shm_lock, flags);
}
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
{
if (routing == B43_SHM_SHARED) { if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001); B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) { if (offset & 0x0003) {
/* Unaligned access */ /* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2); b43_shm_control_word(dev, routing, offset >> 2);
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
goto out; return;
} }
offset >>= 2; offset >>= 2;
} }
b43_shm_control_word(dev, routing, offset); b43_shm_control_word(dev, routing, offset);
b43_write16(dev, B43_MMIO_SHM_DATA, value); b43_write16(dev, B43_MMIO_SHM_DATA, value);
out: }
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
spin_lock_irqsave(&wl->shm_lock, flags);
__b43_shm_write16(dev, routing, offset, value);
spin_unlock_irqrestore(&wl->shm_lock, flags); spin_unlock_irqrestore(&wl->shm_lock, flags);
} }
...@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) ...@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
/* http://bcm-specs.sipsolutions.net/EnableMac */ /* http://bcm-specs.sipsolutions.net/EnableMac */
void b43_mac_enable(struct b43_wldev *dev) void b43_mac_enable(struct b43_wldev *dev)
{ {
if (b43_debug(dev, B43_DBG_FIRMWARE)) {
u16 fwstate;
fwstate = b43_shm_read16(dev, B43_SHM_SHARED,
B43_SHM_SH_UCODESTAT);
if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) &&
(fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) {
b43err(dev->wl, "b43_mac_enable(): The firmware "
"should be suspended, but current state is %u\n",
fwstate);
}
}
dev->mac_suspended--; dev->mac_suspended--;
B43_WARN_ON(dev->mac_suspended < 0); B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) { if (dev->mac_suspended == 0) {
...@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev) ...@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev)
static void b43_periodic_every15sec(struct b43_wldev *dev) static void b43_periodic_every15sec(struct b43_wldev *dev)
{ {
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
u16 wdr;
if (dev->fw.opensource) {
/* Check if the firmware is still alive.
* It will reset the watchdog counter to 0 in its idle loop. */
wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
if (unlikely(wdr)) {
b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
b43_controller_restart(dev, "Firmware watchdog");
return;
} else {
b43_shm_write16(dev, B43_SHM_SCRATCH,
B43_WATCHDOG_REG, 1);
}
}
if (phy->type == B43_PHYTYPE_G) { if (phy->type == B43_PHYTYPE_G) {
//TODO: update_aci_moving_average //TODO: update_aci_moving_average
......
...@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf); ...@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
void b43_tsf_write(struct b43_wldev *dev, u64 tsf); void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
u64 b43_hf_read(struct b43_wldev *dev); u64 b43_hf_read(struct b43_wldev *dev);
void b43_hf_write(struct b43_wldev *dev, u64 value); void b43_hf_write(struct b43_wldev *dev, u64 value);
......
...@@ -586,7 +586,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, ...@@ -586,7 +586,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
spin_lock(&q->lock); /* IRQs are already disabled. */ spin_lock(&q->lock); /* IRQs are already disabled. */
info = (void *)pack->skb; info = IEEE80211_SKB_CB(pack->skb);
memset(&info->status, 0, sizeof(info->status)); memset(&info->status, 0, sizeof(info->status));
b43_fill_txstatus_report(info, status); b43_fill_txstatus_report(info, status);
......
...@@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) ...@@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock; goto out_unlock;
err = 0; err = 0;
switch (state) { switch (state) {
case RFKILL_STATE_ON: case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) { if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill /* No luck. We can't toggle the hardware RF-kill
* button from software. */ * button from software. */
...@@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) ...@@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on) if (!dev->phy.radio_on)
b43_radio_turn_on(dev); b43_radio_turn_on(dev);
break; break;
case RFKILL_STATE_OFF: case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on) if (dev->phy.radio_on)
b43_radio_turn_off(dev, 0); b43_radio_turn_off(dev, 0);
break; break;
default:
b43warn(wl, "Received unexpected rfkill state %d.\n", state);
break;
} }
out_unlock: out_unlock:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
......
...@@ -193,7 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -193,7 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
const struct ieee80211_hdr *wlhdr = const struct ieee80211_hdr *wlhdr =
(const struct ieee80211_hdr *)fragment_data; (const struct ieee80211_hdr *)fragment_data;
int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
u16 fctl = le16_to_cpu(wlhdr->frame_control); __le16 fctl = wlhdr->frame_control;
struct ieee80211_rate *fbrate; struct ieee80211_rate *fbrate;
u8 rate, rate_fb; u8 rate, rate_fb;
int rate_ofdm, rate_fb_ofdm; int rate_ofdm, rate_fb_ofdm;
...@@ -259,7 +259,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -259,7 +259,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
B43_TXH_MAC_KEYIDX; B43_TXH_MAC_KEYIDX;
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG; B43_TXH_MAC_KEYALG;
wlhdr_len = ieee80211_get_hdrlen(fctl); wlhdr_len = ieee80211_hdrlen(fctl);
iv_len = min((size_t) info->control.iv_len, iv_len = min((size_t) info->control.iv_len,
ARRAY_SIZE(txhdr->iv)); ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
...@@ -317,8 +317,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -317,8 +317,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
/* MAC control */ /* MAC control */
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK; mac_ctl |= B43_TXH_MAC_ACK;
if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && if (!ieee80211_is_pspoll(fctl))
((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
mac_ctl |= B43_TXH_MAC_HWSEQ; mac_ctl |= B43_TXH_MAC_HWSEQ;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43_TXH_MAC_STMSDU; mac_ctl |= B43_TXH_MAC_STMSDU;
...@@ -509,7 +508,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -509,7 +508,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
struct b43_plcp_hdr6 *plcp; struct b43_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr; struct ieee80211_hdr *wlhdr;
const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
u16 fctl; __le16 fctl;
u16 phystat0, phystat3, chanstat, mactime; u16 phystat0, phystat3, chanstat, mactime;
u32 macstat; u32 macstat;
u16 chanid; u16 chanid;
...@@ -549,7 +548,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -549,7 +548,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop; goto drop;
} }
wlhdr = (struct ieee80211_hdr *)(skb->data); wlhdr = (struct ieee80211_hdr *)(skb->data);
fctl = le16_to_cpu(wlhdr->frame_control); fctl = wlhdr->frame_control;
if (macstat & B43_RX_MAC_DEC) { if (macstat & B43_RX_MAC_DEC) {
unsigned int keyidx; unsigned int keyidx;
...@@ -564,7 +563,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -564,7 +563,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
B43_WARN_ON(keyidx >= dev->max_nr_keys); B43_WARN_ON(keyidx >= dev->max_nr_keys);
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) { if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
wlhdr_len = ieee80211_get_hdrlen(fctl); wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) { if (unlikely(skb->len < (wlhdr_len + 3))) {
b43dbg(dev->wl, b43dbg(dev->wl,
"RX: Packet size underrun (3)\n"); "RX: Packet size underrun (3)\n");
...@@ -604,9 +603,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -604,9 +603,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
* of timestamp, i.e. about 65 milliseconds after the PHY received * of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol. * the first symbol.
*/ */
if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
== (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
dev->wl->radiotap_enabled) {
u16 low_mactime_now; u16 low_mactime_now;
b43_tsf_read(dev, &status.mactime); b43_tsf_read(dev, &status.mactime);
......
...@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring, ...@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
dma_addr_t dmaaddr; dma_addr_t dmaaddr;
if (tx) if (tx)
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, buf, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
else else
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, buf, len,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
return dmaaddr; return dmaaddr;
} }
...@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring, ...@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
int tx) int tx)
{ {
if (tx) if (tx)
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, addr, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
else else
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, addr, len,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring, ...@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
{ {
B43legacy_WARN_ON(ring->tx); B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring, ...@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
{ {
B43legacy_WARN_ON(ring->tx); B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, ...@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
static int alloc_ringmemory(struct b43legacy_dmaring *ring) static int alloc_ringmemory(struct b43legacy_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; /* GFP flags must match the flags in free_ringmemory()! */
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, B43legacy_DMA_RINGMEMSIZE,
&(ring->dmabase), GFP_KERNEL); &(ring->dmabase),
GFP_KERNEL);
if (!ring->descbase) { if (!ring->descbase) {
b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
" failed\n"); " failed\n");
...@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) ...@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
static void free_ringmemory(struct b43legacy_dmaring *ring) static void free_ringmemory(struct b43legacy_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase, GFP_KERNEL);
dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
} }
/* Reset the RX DMA channel */ /* Reset the RX DMA channel */
...@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, ...@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
size_t buffersize, size_t buffersize,
bool dma_to_device) bool dma_to_device)
{ {
if (unlikely(dma_mapping_error(addr))) if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1; return 1;
switch (ring->type) { switch (ring->type) {
...@@ -894,9 +893,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -894,9 +893,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_meta; goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */ /* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43legacy_dma_mapping_error(ring, dma_test, if (b43legacy_dma_mapping_error(ring, dma_test,
sizeof(struct b43legacy_txhdr_fw3), 1)) { sizeof(struct b43legacy_txhdr_fw3), 1)) {
...@@ -908,7 +907,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -908,7 +907,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
if (!ring->txhdr_cache) if (!ring->txhdr_cache)
goto err_kfree_meta; goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
...@@ -918,9 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -918,9 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_txhdr_cache; goto err_kfree_txhdr_cache;
} }
dma_unmap_single(dev->dev->dma_dev, ssb_dma_unmap_single(dev->dev, dma_test,
dma_test, sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
ring->nr_slots = nr_slots; ring->nr_slots = nr_slots;
......
...@@ -90,7 +90,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) ...@@ -90,7 +90,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock; goto out_unlock;
err = 0; err = 0;
switch (state) { switch (state) {
case RFKILL_STATE_ON: case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) { if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill /* No luck. We can't toggle the hardware RF-kill
* button from software. */ * button from software. */
...@@ -100,10 +100,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) ...@@ -100,10 +100,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on) if (!dev->phy.radio_on)
b43legacy_radio_turn_on(dev); b43legacy_radio_turn_on(dev);
break; break;
case RFKILL_STATE_OFF: case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on) if (dev->phy.radio_on)
b43legacy_radio_turn_off(dev, 0); b43legacy_radio_turn_off(dev, 0);
break; break;
default:
b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
state);
break;
} }
out_unlock: out_unlock:
......
...@@ -442,7 +442,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -442,7 +442,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
struct b43legacy_plcp_hdr6 *plcp; struct b43legacy_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr; struct ieee80211_hdr *wlhdr;
const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr; const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr;
u16 fctl; __le16 fctl;
u16 phystat0; u16 phystat0;
u16 phystat3; u16 phystat3;
u16 chanstat; u16 chanstat;
...@@ -480,7 +480,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -480,7 +480,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
goto drop; goto drop;
} }
wlhdr = (struct ieee80211_hdr *)(skb->data); wlhdr = (struct ieee80211_hdr *)(skb->data);
fctl = le16_to_cpu(wlhdr->frame_control); fctl = wlhdr->frame_control;
if ((macstat & B43legacy_RX_MAC_DEC) && if ((macstat & B43legacy_RX_MAC_DEC) &&
!(macstat & B43legacy_RX_MAC_DECERR)) { !(macstat & B43legacy_RX_MAC_DECERR)) {
...@@ -499,11 +499,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -499,11 +499,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) { if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
/* Remove PROTECTED flag to mark it as decrypted. */ /* Remove PROTECTED flag to mark it as decrypted. */
B43legacy_WARN_ON(!(fctl & IEEE80211_FCTL_PROTECTED)); B43legacy_WARN_ON(!ieee80211_has_protected(fctl));
fctl &= ~IEEE80211_FCTL_PROTECTED; fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
wlhdr->frame_control = cpu_to_le16(fctl); wlhdr->frame_control = fctl;
wlhdr_len = ieee80211_get_hdrlen(fctl); wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) { if (unlikely(skb->len < (wlhdr_len + 3))) {
b43legacydbg(dev->wl, "RX: Packet size" b43legacydbg(dev->wl, "RX: Packet size"
" underrun3\n"); " underrun3\n");
...@@ -556,9 +556,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -556,9 +556,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
* of timestamp, i.e. about 65 milliseconds after the PHY received * of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol. * the first symbol.
*/ */
if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
== (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
dev->wl->radiotap_enabled) {
u16 low_mactime_now; u16 low_mactime_now;
b43legacy_tsf_read(dev, &status.mactime); b43legacy_tsf_read(dev, &status.mactime);
......
...@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, ...@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size, struct iw_quality qual[], int buf_size,
int aplist); int aplist);
int prism2_ap_translate_scan(struct net_device *dev, char *buffer); int prism2_ap_translate_scan(struct net_device *dev,
struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
......
...@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], ...@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
/* Translate our list of Access Points & Stations to a card independant /* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */ * format that the Wireless Tools will understand - Jean II */
int prism2_ap_translate_scan(struct net_device *dev, char *buffer) int prism2_ap_translate_scan(struct net_device *dev,
struct iw_request_info *info, char *buffer)
{ {
struct hostap_interface *iface; struct hostap_interface *iface;
local_info_t *local; local_info_t *local;
...@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN; iwe.len = IW_EV_ADDR_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_ADDR_LEN); &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or /* Use the mode to indicate if it's a station or
* an Access Point */ * an Access Point */
...@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
else else
iwe.u.mode = IW_MODE_INFRA; iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN; iwe.len = IW_EV_UINT_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_UINT_LEN); &iwe, IW_EV_UINT_LEN);
/* Some quality */ /* Some quality */
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
iwe.u.qual.updated = sta->last_rx_updated; iwe.u.qual.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN; iwe.len = IW_EV_QUAL_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_QUAL_LEN); &iwe, IW_EV_QUAL_LEN);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) { if (sta->ap) {
...@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len; iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev,
&iwe, end_buf, &iwe,
sta->u.ap.ssid); sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev,
&iwe, end_buf, &iwe,
sta->u.ap.ssid sta->u.ap.ssid);
/* 0 byte memcpy */);
if (sta->u.ap.channel > 0 && if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) { sta->u.ap.channel <= FREQ_COUNT) {
...@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
* 100000; * 100000;
iwe.u.freq.e = 1; iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event( current_ev = iwe_stream_add_event(
current_ev, end_buf, &iwe, info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN); IW_EV_FREQ_LEN);
} }
...@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) ...@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
sprintf(buf, "beacon_interval=%d", sprintf(buf, "beacon_interval=%d",
sta->listen_interval); sta->listen_interval);
iwe.u.data.length = strlen(buf); iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev,
&iwe, buf); end_buf, &iwe, buf);
} }
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
......
...@@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev, ...@@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
#ifndef PRISM2_NO_STATION_MODES #ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local, static char * __prism2_translate_scan(local_info_t *local,
struct iw_request_info *info,
struct hfa384x_hostscan_result *scan, struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss, struct hostap_bss_info *bss,
char *current_ev, char *end_buf) char *current_ev, char *end_buf)
...@@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN); IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */ /* Other entries will be displayed in the order we give them */
...@@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len; iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, ssid);
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
...@@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER; iwe.u.mode = IW_MODE_MASTER;
else else
iwe.u.mode = IW_MODE_ADHOC; iwe.u.mode = IW_MODE_ADHOC;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_UINT_LEN); &iwe, IW_EV_UINT_LEN);
} }
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) { if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000; iwe.u.freq.m = freq_list[chan - 1] * 100000;
iwe.u.freq.e = 1; iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_FREQ_LEN); &iwe, IW_EV_FREQ_LEN);
} }
if (scan) { if (scan) {
...@@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local,
| IW_QUAL_NOISE_UPDATED | IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID | IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM; | IW_QUAL_DBM;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
IW_EV_QUAL_LEN); &iwe, IW_EV_QUAL_LEN);
} }
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local,
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */ /* TODO: add SuppRates into BSS table */
if (scan) { if (scan) {
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE; iwe.cmd = SIOCGIWRATE;
current_val = current_ev + IW_EV_LCP_LEN; current_val = current_ev + iwe_stream_lcp_len(info);
pos = scan->sup_rates; pos = scan->sup_rates;
for (i = 0; i < sizeof(scan->sup_rates); i++) { for (i = 0; i < sizeof(scan->sup_rates); i++) {
if (pos[i] == 0) if (pos[i] == 0)
...@@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Bit rate given in 500 kb/s units (+ 0x80) */ /* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value( current_val = iwe_stream_add_value(
current_ev, current_val, end_buf, &iwe, info, current_ev, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN); IW_EV_PARAM_LEN);
} }
/* Check if we added any event */ /* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN) if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val; current_ev = current_val;
} }
...@@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
iwe.u.data.length = strlen(buf); iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_point(info, current_ev, end_buf,
buf); &iwe, buf);
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
iwe.u.data.length = strlen(buf); iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, current_ev = iwe_stream_add_point(info, current_ev, end_buf,
buf); &iwe, buf);
if (local->last_scan_type == PRISM2_HOSTSCAN && if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) { (capabilities & WLAN_CAPABILITY_IBSS)) {
...@@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
iwe.u.data.length = strlen(buf); iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev,
&iwe, buf); end_buf, &iwe, buf);
} }
} }
kfree(buf); kfree(buf);
...@@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local,
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len; iwe.u.data.length = bss->wpa_ie_len;
current_ev = iwe_stream_add_point( current_ev = iwe_stream_add_point(info, current_ev, end_buf,
current_ev, end_buf, &iwe, bss->wpa_ie); &iwe, bss->wpa_ie);
} }
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len; iwe.u.data.length = bss->rsn_ie_len;
current_ev = iwe_stream_add_point( current_ev = iwe_stream_add_point(info, current_ev, end_buf,
current_ev, end_buf, &iwe, bss->rsn_ie); &iwe, bss->rsn_ie);
} }
return current_ev; return current_ev;
...@@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local, ...@@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Translate scan data returned from the card to a card independant /* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */ * format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local, static inline int prism2_translate_scan(local_info_t *local,
struct iw_request_info *info,
char *buffer, int buflen) char *buffer, int buflen)
{ {
struct hfa384x_hostscan_result *scan; struct hfa384x_hostscan_result *scan;
...@@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local, ...@@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local,
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1; bss->included = 1;
current_ev = __prism2_translate_scan( current_ev = __prism2_translate_scan(
local, scan, bss, current_ev, end_buf); local, info, scan, bss, current_ev,
end_buf);
found++; found++;
} }
} }
if (!found) { if (!found) {
current_ev = __prism2_translate_scan( current_ev = __prism2_translate_scan(
local, scan, NULL, current_ev, end_buf); local, info, scan, NULL, current_ev, end_buf);
} }
/* Check if there is space for one more entry */ /* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
...@@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local, ...@@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local,
bss = list_entry(ptr, struct hostap_bss_info, list); bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included) if (bss->included)
continue; continue;
current_ev = __prism2_translate_scan(local, NULL, bss, current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf); current_ev, end_buf);
/* Check if there is space for one more entry */ /* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
...@@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev, ...@@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
} }
local->scan_timestamp = 0; local->scan_timestamp = 0;
res = prism2_translate_scan(local, extra, data->length); res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) { if (res >= 0) {
data->length = res; data->length = res;
...@@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev, ...@@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
* Jean II */ * Jean II */
/* Translate to WE format */ /* Translate to WE format */
res = prism2_ap_translate_scan(dev, extra); res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) { if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded " printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res); "(length=%d)\n", res);
......
...@@ -8,7 +8,7 @@ config IWLCORE ...@@ -8,7 +8,7 @@ config IWLCORE
select MAC80211_LEDS if IWLWIFI_LEDS select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL select RFKILL if IWLWIFI_RFKILL
select RFKILL_INPUT if IWLWIFI_RFKILL select RFKILL_INPUT if (IWLWIFI_RFKILL && INPUT)
config IWLWIFI_LEDS config IWLWIFI_LEDS
bool bool
......
...@@ -54,17 +54,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) ...@@ -54,17 +54,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
switch (state) { switch (state) {
case RFKILL_STATE_ON: case RFKILL_STATE_UNBLOCKED:
iwl_radio_kill_sw_enable_radio(priv); iwl_radio_kill_sw_enable_radio(priv);
/* if HW rf-kill is set dont allow ON state */ /* if HW rf-kill is set dont allow ON state */
if (iwl_is_rfkill(priv)) if (iwl_is_rfkill(priv))
err = -EBUSY; err = -EBUSY;
break; break;
case RFKILL_STATE_OFF: case RFKILL_STATE_SOFT_BLOCKED:
iwl_radio_kill_sw_disable_radio(priv); iwl_radio_kill_sw_disable_radio(priv);
if (!iwl_is_rfkill(priv)) if (!iwl_is_rfkill(priv))
err = -EBUSY; err = -EBUSY;
break; break;
default:
IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
} }
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
...@@ -95,6 +98,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) ...@@ -95,6 +98,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
priv->rfkill_mngr.rfkill->dev.class->resume = NULL; priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
priv->rfkill_mngr.input_dev = input_allocate_device(); priv->rfkill_mngr.input_dev = input_allocate_device();
if (!priv->rfkill_mngr.input_dev) { if (!priv->rfkill_mngr.input_dev) {
IWL_ERROR("Unable to allocate rfkill input device.\n"); IWL_ERROR("Unable to allocate rfkill input device.\n");
...@@ -109,6 +113,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) ...@@ -109,6 +113,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
priv->rfkill_mngr.input_dev->dev.parent = device; priv->rfkill_mngr.input_dev->dev.parent = device;
priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
#endif
ret = rfkill_register(priv->rfkill_mngr.rfkill); ret = rfkill_register(priv->rfkill_mngr.rfkill);
if (ret) { if (ret) {
...@@ -116,11 +121,13 @@ int iwl_rfkill_init(struct iwl_priv *priv) ...@@ -116,11 +121,13 @@ int iwl_rfkill_init(struct iwl_priv *priv)
goto free_input_dev; goto free_input_dev;
} }
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
ret = input_register_device(priv->rfkill_mngr.input_dev); ret = input_register_device(priv->rfkill_mngr.input_dev);
if (ret) { if (ret) {
IWL_ERROR("Unable to register rfkill input device: %d\n", ret); IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
goto unregister_rfkill; goto unregister_rfkill;
} }
#endif
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret; return ret;
...@@ -130,8 +137,10 @@ int iwl_rfkill_init(struct iwl_priv *priv) ...@@ -130,8 +137,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
priv->rfkill_mngr.rfkill = NULL; priv->rfkill_mngr.rfkill = NULL;
free_input_dev: free_input_dev:
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
input_free_device(priv->rfkill_mngr.input_dev); input_free_device(priv->rfkill_mngr.input_dev);
priv->rfkill_mngr.input_dev = NULL; priv->rfkill_mngr.input_dev = NULL;
#endif
freed_rfkill: freed_rfkill:
if (priv->rfkill_mngr.rfkill != NULL) if (priv->rfkill_mngr.rfkill != NULL)
...@@ -147,13 +156,16 @@ EXPORT_SYMBOL(iwl_rfkill_init); ...@@ -147,13 +156,16 @@ EXPORT_SYMBOL(iwl_rfkill_init);
void iwl_rfkill_unregister(struct iwl_priv *priv) void iwl_rfkill_unregister(struct iwl_priv *priv)
{ {
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
if (priv->rfkill_mngr.input_dev) if (priv->rfkill_mngr.input_dev)
input_unregister_device(priv->rfkill_mngr.input_dev); input_unregister_device(priv->rfkill_mngr.input_dev);
input_free_device(priv->rfkill_mngr.input_dev);
priv->rfkill_mngr.input_dev = NULL;
#endif
if (priv->rfkill_mngr.rfkill) if (priv->rfkill_mngr.rfkill)
rfkill_unregister(priv->rfkill_mngr.rfkill); rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.input_dev = NULL;
priv->rfkill_mngr.rfkill = NULL; priv->rfkill_mngr.rfkill = NULL;
} }
EXPORT_SYMBOL(iwl_rfkill_unregister); EXPORT_SYMBOL(iwl_rfkill_unregister);
......
...@@ -776,8 +776,9 @@ int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, ...@@ -776,8 +776,9 @@ int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
#define MAX_CUSTOM_LEN 64 #define MAX_CUSTOM_LEN 64
static inline char *lbs_translate_scan(struct lbs_private *priv, static inline char *lbs_translate_scan(struct lbs_private *priv,
char *start, char *stop, struct iw_request_info *info,
struct bss_descriptor *bss) char *start, char *stop,
struct bss_descriptor *bss)
{ {
struct chan_freq_power *cfp; struct chan_freq_power *cfp;
char *current_val; /* For rates */ char *current_val; /* For rates */
...@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */ /* SSID */
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE); iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
/* Mode */ /* Mode */
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
iwe.u.mode = bss->mode; iwe.u.mode = bss->mode;
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
/* Frequency */ /* Frequency */
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000; iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1; iwe.u.freq.e = 1;
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */ /* Add quality statistics */
iwe.cmd = IWEVQUAL; iwe.cmd = IWEVQUAL;
...@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf); iwe.u.qual.level = CAL_RSSI(snr, nf);
} }
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */ /* Add encryption capability */
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
...@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
} }
iwe.u.data.length = 0; iwe.u.data.length = 0;
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
current_val = start + IW_EV_LCP_LEN; current_val = start + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE; iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0; iwe.u.bitrate.fixed = 0;
...@@ -874,19 +875,19 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -874,19 +875,19 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
/* Bit rate given in 500 kb/s units */ /* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000; iwe.u.bitrate.value = bss->rates[j] * 500000;
current_val = iwe_stream_add_value(start, current_val, current_val = iwe_stream_add_value(info, start, current_val,
stop, &iwe, IW_EV_PARAM_LEN); stop, &iwe, IW_EV_PARAM_LEN);
} }
if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
&& !lbs_ssid_cmp(priv->curbssparams.ssid, && !lbs_ssid_cmp(priv->curbssparams.ssid,
priv->curbssparams.ssid_len, priv->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)) { bss->ssid, bss->ssid_len)) {
iwe.u.bitrate.value = 22 * 500000; iwe.u.bitrate.value = 22 * 500000;
current_val = iwe_stream_add_value(start, current_val, current_val = iwe_stream_add_value(info, start, current_val,
stop, &iwe, IW_EV_PARAM_LEN); stop, &iwe, IW_EV_PARAM_LEN);
} }
/* Check if we added any event */ /* Check if we added any event */
if((current_val - start) > IW_EV_LCP_LEN) if ((current_val - start) > iwe_stream_lcp_len(info))
start = current_val; start = current_val;
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len; iwe.u.data.length = bss->wpa_ie_len;
start = iwe_stream_add_point(start, stop, &iwe, buf); start = iwe_stream_add_point(info, start, stop, &iwe, buf);
} }
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
...@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len; iwe.u.data.length = bss->rsn_ie_len;
start = iwe_stream_add_point(start, stop, &iwe, buf); start = iwe_stream_add_point(info, start, stop, &iwe, buf);
} }
if (bss->mesh) { if (bss->mesh) {
...@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, ...@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
iwe.u.data.length = p - custom; iwe.u.data.length = p - custom;
if (iwe.u.data.length) if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom); start = iwe_stream_add_point(info, start, stop,
&iwe, custom);
} }
out: out:
...@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, ...@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
} }
/* Translate to WE format this entry */ /* Translate to WE format this entry */
next_ev = lbs_translate_scan(priv, ev, stop, iter_bss); next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss);
if (next_ev == NULL) if (next_ev == NULL)
continue; continue;
ev = next_ev; ev = next_ev;
......
...@@ -430,15 +430,16 @@ static int __init init_mac80211_hwsim(void) ...@@ -430,15 +430,16 @@ static int __init init_mac80211_hwsim(void)
hwsim_radios[i] = hw; hwsim_radios[i] = hw;
data = hw->priv; data = hw->priv;
data->dev = device_create(hwsim_class, NULL, 0, "hwsim%d", i); data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
"hwsim%d", i);
if (IS_ERR(data->dev)) { if (IS_ERR(data->dev)) {
printk(KERN_DEBUG "mac80211_hwsim: device_create " printk(KERN_DEBUG
"mac80211_hwsim: device_create_drvdata "
"failed (%ld)\n", PTR_ERR(data->dev)); "failed (%ld)\n", PTR_ERR(data->dev));
err = -ENOMEM; err = -ENOMEM;
goto failed; goto failed;
} }
data->dev->driver = &mac80211_hwsim_driver; data->dev->driver = &mac80211_hwsim_driver;
dev_set_drvdata(data->dev, hw);
SET_IEEE80211_DEV(hw, data->dev); SET_IEEE80211_DEV(hw, data->dev);
addr[3] = i >> 8; addr[3] = i >> 8;
......
...@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev, ...@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II * format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */ * Return message length or -errno for fatal errors */
static inline char *orinoco_translate_scan(struct net_device *dev, static inline char *orinoco_translate_scan(struct net_device *dev,
struct iw_request_info *info,
char *current_ev, char *current_ev,
char *end_buf, char *end_buf,
union hermes_scan_info *bss, union hermes_scan_info *bss,
...@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */ /* Other entries will be displayed in the order we give them */
...@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.data.length = 32; iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->a.essid);
/* Add mode */ /* Add mode */
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
...@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER; iwe.u.mode = IW_MODE_MASTER;
else else
iwe.u.mode = IW_MODE_ADHOC; iwe.u.mode = IW_MODE_ADHOC;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_UINT_LEN);
} }
channel = bss->s.channel; channel = bss->s.channel;
...@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000; iwe.u.freq.m = channel_frequency[channel-1] * 100000;
iwe.u.freq.e = 1; iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev, end_buf, current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_FREQ_LEN); &iwe, IW_EV_FREQ_LEN);
} }
...@@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
else else
iwe.u.qual.qual = 0; iwe.u.qual.qual = 0;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */ /* Add encryption capability */
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
...@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
else else
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->a.essid);
/* Add EXTRA: Age to display seconds since last beacon/probe response /* Add EXTRA: Age to display seconds since last beacon/probe response
* for given network. */ * for given network. */
...@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
jiffies_to_msecs(jiffies - last_scanned)); jiffies_to_msecs(jiffies - last_scanned));
iwe.u.data.length = p - custom; iwe.u.data.length = p - custom;
if (iwe.u.data.length) if (iwe.u.data.length)
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, custom);
/* Bit rate is not available in Lucent/Agere firmwares */ /* Bit rate is not available in Lucent/Agere firmwares */
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
char *current_val = current_ev + IW_EV_LCP_LEN; char *current_val = current_ev + iwe_stream_lcp_len(info);
int i; int i;
int step; int step;
...@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev, ...@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
break; break;
/* Bit rate given in 500 kb/s units (+ 0x80) */ /* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value(current_ev, current_val, current_val = iwe_stream_add_value(info, current_ev,
current_val,
end_buf, &iwe, end_buf, &iwe,
IW_EV_PARAM_LEN); IW_EV_PARAM_LEN);
} }
/* Check if we added any event */ /* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN) if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val; current_ev = current_val;
} }
...@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev, ...@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
list_for_each_entry(bss, &priv->bss_list, list) { list_for_each_entry(bss, &priv->bss_list, list) {
/* Translate to WE format this entry */ /* Translate to WE format this entry */
current_ev = orinoco_translate_scan(dev, current_ev, current_ev = orinoco_translate_scan(dev, info, current_ev,
extra + srq->length, extra + srq->length,
&bss->bss, &bss->bss,
bss->last_scanned); bss->last_scanned);
......
...@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info, ...@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/ */
static char * static char *
prism54_translate_bss(struct net_device *ndev, char *current_ev, prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
char *end_buf, struct obj_bss *bss, char noise) char *current_ev, char *end_buf, struct obj_bss *bss,
char noise)
{ {
struct iw_event iwe; /* Temporary buffer */ struct iw_event iwe; /* Temporary buffer */
short cap; short cap;
...@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
current_ev = current_ev = iwe_stream_add_event(info, current_ev, end_buf,
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */ /* The following entries will be displayed in the same order we give them */
...@@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.length = bss->ssid.length; iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1; iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets); &iwe, bss->ssid.octets);
/* Capabilities */ /* Capabilities */
...@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC; iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode) if (iwe.u.mode)
current_ev = current_ev = iwe_stream_add_event(info, current_ev, end_buf,
iwe_stream_add_event(current_ev, end_buf, &iwe, &iwe, IW_EV_UINT_LEN);
IW_EV_UINT_LEN);
/* Encryption capability */ /* Encryption capability */
if (cap & CAP_CRYPT) if (cap & CAP_CRYPT)
...@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0; iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */ /* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel; iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6; iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
current_ev = current_ev = iwe_stream_add_event(info, current_ev, end_buf,
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */ /* Add quality statistics */
iwe.u.qual.level = bss->rssi; iwe.u.qual.level = bss->rssi;
...@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */ /* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise; iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL; iwe.cmd = IWEVQUAL;
current_ev = current_ev = iwe_stream_add_event(info, current_ev, end_buf,
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); &iwe, IW_EV_QUAL_LEN);
/* Add WPA/RSN Information Element, if any */ /* Add WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) { if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf, current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, wpa_ie); &iwe, wpa_ie);
} }
/* Do the bitrates */ /* Do the bitrates */
{ {
char * current_val = current_ev + IW_EV_LCP_LEN; char *current_val = current_ev + iwe_stream_lcp_len(info);
int i; int i;
int mask; int mask;
...@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, ...@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
for(i = 0; i < sizeof(scan_rate_list); i++) { for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) { if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000); iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
current_val = iwe_stream_add_value(current_ev, current_val, current_val = iwe_stream_add_value(
end_buf, &iwe, info, current_ev, current_val,
IW_EV_PARAM_LEN); end_buf, &iwe, IW_EV_PARAM_LEN);
} }
mask <<= 1; mask <<= 1;
} }
/* Check if we added any event */ /* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN) if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val; current_ev = current_val;
} }
...@@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info, ...@@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
/* ok now, scan the list and translate its info */ /* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) { for (i = 0; i < (int) bsslist->nr; i++) {
current_ev = prism54_translate_bss(ndev, current_ev, current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length, extra + dwrq->length,
&(bsslist->bsslist[i]), &(bsslist->bsslist[i]),
noise); noise);
...@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev, ...@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
struct prism2_hostapd_param *param) struct prism2_hostapd_param *param)
{ {
islpci_private *priv = netdev_priv(ndev); islpci_private *priv = netdev_priv(ndev);
struct iw_request_info info;
int i, rvalue; int i, rvalue;
struct obj_bsslist *bsslist; struct obj_bsslist *bsslist;
u32 noise = 0; u32 noise = 0;
...@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev, ...@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr; bsslist = r.ptr;
info.cmd = PRISM54_HOSTAPD;
info.flags = 0;
/* ok now, scan the list and translate its info */ /* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++) for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
current_ev = prism54_translate_bss(ndev, current_ev, current_ev = prism54_translate_bss(ndev, &info, current_ev,
extra + IW_SCAN_MAX_DATA, extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]), &(bsslist->bsslist[i]),
noise); noise);
......
...@@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev, ...@@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev,
static char *rndis_translate_scan(struct net_device *dev, static char *rndis_translate_scan(struct net_device *dev,
char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid) struct iw_request_info *info, char *cev,
char *end_buf,
struct ndis_80211_bssid_ex *bssid)
{ {
#ifdef DEBUG #ifdef DEBUG
struct usbnet *usbdev = dev->priv; struct usbnet *usbdev = dev->priv;
...@@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP; iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
bssid->ssid.essid); bssid->ssid.essid);
iwe.cmd = SIOCGIWESSID; iwe.cmd = SIOCGIWESSID;
iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
iwe.u.essid.flags = 1; iwe.u.essid.flags = 1;
cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid); cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
iwe.cmd = SIOCGIWMODE; iwe.cmd = SIOCGIWMODE;
...@@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_AUTO; iwe.u.mode = IW_MODE_AUTO;
break; break;
} }
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
iwe.cmd = SIOCGIWFREQ; iwe.cmd = SIOCGIWFREQ;
dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
iwe.cmd = IWEVQUAL; iwe.cmd = IWEVQUAL;
...@@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED | IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID; | IW_QUAL_NOISE_INVALID;
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
iwe.cmd = SIOCGIWENCODE; iwe.cmd = SIOCGIWENCODE;
...@@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev,
else else
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
devdbg(usbdev, "RATES:"); devdbg(usbdev, "RATES:");
current_val = cev + IW_EV_LCP_LEN; current_val = cev + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE; iwe.cmd = SIOCGIWRATE;
for (i = 0; i < sizeof(bssid->rates); i++) { for (i = 0; i < sizeof(bssid->rates); i++) {
if (bssid->rates[i] & 0x7f) { if (bssid->rates[i] & 0x7f) {
...@@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev,
((bssid->rates[i] & 0x7f) * ((bssid->rates[i] & 0x7f) *
500000); 500000);
devdbg(usbdev, " %d", iwe.u.bitrate.value); devdbg(usbdev, " %d", iwe.u.bitrate.value);
current_val = iwe_stream_add_value(cev, current_val = iwe_stream_add_value(info, cev,
current_val, end_buf, &iwe, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN); IW_EV_PARAM_LEN);
} }
} }
if ((current_val - cev) > IW_EV_LCP_LEN) if ((current_val - cev) > iwe_stream_lcp_len(info))
cev = current_val; cev = current_val;
beacon = le32_to_cpu(bssid->config.beacon_period); beacon = le32_to_cpu(bssid->config.beacon_period);
...@@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
iwe.u.data.length = strlen(sbuf); iwe.u.data.length = strlen(sbuf);
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
atim = le32_to_cpu(bssid->config.atim_window); atim = le32_to_cpu(bssid->config.atim_window);
devdbg(usbdev, "ATIM %d", atim); devdbg(usbdev, "ATIM %d", atim);
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
iwe.u.data.length = strlen(sbuf); iwe.u.data.length = strlen(sbuf);
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
ie_len = min(bssid_len - (int)sizeof(*bssid), ie_len = min(bssid_len - (int)sizeof(*bssid),
...@@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev, ...@@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev,
(ie->id == MFIE_TYPE_RSN) ? 2 : 1); (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
iwe.cmd = IWEVGENIE; iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN); iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
cev = iwe_stream_add_point(cev, end_buf, &iwe, cev = iwe_stream_add_point(info, cev, end_buf, &iwe,
(u8 *)ie); (u8 *)ie);
} }
...@@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev, ...@@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) { while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA, cev = rndis_translate_scan(dev, info, cev,
bssid); extra + IW_SCAN_MAX_DATA, bssid);
bssid = (void *)bssid + bssid_len; bssid = (void *)bssid + bssid_len;
bssid_len = le32_to_cpu(bssid->length); bssid_len = le32_to_cpu(bssid->length);
count--; count--;
......
...@@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, ...@@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry) struct queue_entry *entry)
{ {
struct queue_entry_priv_pci *entry_priv = entry->priv_data; struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word; u32 word;
rt2x00_desc_read(entry_priv->desc, 2, &word); rt2x00_desc_read(entry_priv->desc, 2, &word);
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
entry->queue->data_size);
rt2x00_desc_write(entry_priv->desc, 2, word); rt2x00_desc_write(entry_priv->desc, 2, word);
rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(entry_priv->desc, 0, &word); rt2x00_desc_read(entry_priv->desc, 0, &word);
...@@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words. * Start writing the descriptor words.
*/ */
rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(txd, 2, &word); rt2x00_desc_read(txd, 2, &word);
...@@ -1154,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, ...@@ -1154,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
} }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
rt2x00pci_txdone(rt2x00dev, entry, &txdesc); rt2x00lib_txdone(entry, &txdesc);
} }
} }
...@@ -1366,7 +1366,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1366,7 +1366,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM; IEEE80211_HW_SIGNAL_DBM;
rt2x00dev->hw->extra_tx_headroom = 0; rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev, rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0)); EEPROM_MAC_ADDR_0));
...@@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2400pci_probe_hw_mode(rt2x00dev); rt2400pci_probe_hw_mode(rt2x00dev);
/* /*
* This device requires the atim queue * This device requires the atim queue and DMA-mapped skbs.
*/ */
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
/* /*
* Set the rssi offset. * Set the rssi offset.
...@@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
* Write entire beacon with descriptor to register, * Write entire beacon with descriptor to register,
* and kick the beacon generator. * and kick the beacon generator.
*/ */
memcpy(entry_priv->data, skb->data, skb->len); rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb);
rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
......
...@@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, ...@@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry) struct queue_entry *entry)
{ {
struct queue_entry_priv_pci *entry_priv = entry->priv_data; struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word; u32 word;
rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(entry_priv->desc, 0, &word); rt2x00_desc_read(entry_priv->desc, 0, &word);
...@@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words. * Start writing the descriptor words.
*/ */
rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(txd, 2, &word); rt2x00_desc_read(txd, 2, &word);
...@@ -1311,7 +1312,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, ...@@ -1311,7 +1312,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
} }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
rt2x00pci_txdone(rt2x00dev, entry, &txdesc); rt2x00lib_txdone(entry, &txdesc);
} }
} }
...@@ -1688,7 +1689,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1688,7 +1689,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->extra_tx_headroom = 0; rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev, rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0)); EEPROM_MAC_ADDR_0));
...@@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2500pci_probe_hw_mode(rt2x00dev); rt2500pci_probe_hw_mode(rt2x00dev);
/* /*
* This device requires the atim queue * This device requires the atim queue and DMA-mapped skbs.
*/ */
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
/* /*
* Set the rssi offset. * Set the rssi offset.
...@@ -1842,7 +1844,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1842,7 +1844,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
* Write entire beacon with descriptor to register, * Write entire beacon with descriptor to register,
* and kick the beacon generator. * and kick the beacon generator.
*/ */
memcpy(entry_priv->data, skb->data, skb->len); rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb);
rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
......
...@@ -1594,7 +1594,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1594,7 +1594,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev, rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0)); EEPROM_MAC_ADDR_0));
...@@ -1678,7 +1678,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1678,7 +1678,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_dev *rt2x00dev = hw->priv;
struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
struct queue_entry_priv_usb_bcn *bcn_priv; struct queue_entry_priv_usb_bcn *bcn_priv;
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
/* /*
* Module information. * Module information.
*/ */
#define DRV_VERSION "2.1.7" #define DRV_VERSION "2.1.8"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com" #define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/* /*
...@@ -110,33 +110,6 @@ ...@@ -110,33 +110,6 @@
#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) #define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
#define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) )
/*
* IEEE802.11 header defines
*/
static inline int is_rts_frame(u16 fc)
{
return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
}
static inline int is_cts_frame(u16 fc)
{
return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
}
static inline int is_probe_resp(u16 fc)
{
return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
}
static inline int is_beacon(u16 fc)
{
return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON));
}
/* /*
* Chipset identification * Chipset identification
* The chipset on the device is composed of a RT and RF chip. * The chipset on the device is composed of a RT and RF chip.
...@@ -628,6 +601,7 @@ enum rt2x00_flags { ...@@ -628,6 +601,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_BEACON_GUARD, DRIVER_REQUIRE_BEACON_GUARD,
DRIVER_REQUIRE_ATIM_QUEUE, DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED, DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
/* /*
* Driver configuration * Driver configuration
...@@ -652,11 +626,7 @@ struct rt2x00_dev { ...@@ -652,11 +626,7 @@ struct rt2x00_dev {
* When accessing this variable, the rt2x00dev_{pci,usb} * When accessing this variable, the rt2x00dev_{pci,usb}
* macro's should be used for correct typecasting. * macro's should be used for correct typecasting.
*/ */
void *dev; struct device *dev;
#define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev )
#define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev )
#define rt2x00dev_usb_dev(__dev)\
( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) )
/* /*
* Callback functions. * Callback functions.
...@@ -931,10 +901,11 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) ...@@ -931,10 +901,11 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
} }
/** /**
* rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
* @queue: The queue for which the skb will be applicable. * @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to map.
*/ */
struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/** /**
* rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
...@@ -985,26 +956,14 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, ...@@ -985,26 +956,14 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
enum queue_index index); enum queue_index index);
/**
* rt2x00queue_index_inc - Index incrementation function
* @queue: Queue (&struct data_queue) to perform the action on.
* @index: Index type (&enum queue_index) to perform the action on.
*
* This function will increase the requested index on the queue,
* it will grab the appropriate locks and handle queue overflow events by
* resetting the index to the start of the queue.
*/
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
/* /*
* Interrupt context handlers. * Interrupt context handlers.
*/ */
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_txdone(struct queue_entry *entry, void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc); struct txdone_entry_desc *txdesc);
void rt2x00lib_rxdone(struct queue_entry *entry, void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc); struct queue_entry *entry);
/* /*
* mac80211 handlers. * mac80211 handlers.
......
...@@ -469,12 +469,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) ...@@ -469,12 +469,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
static void rt2x00lib_beacondone_iter(void *data, u8 *mac, static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct rt2x00_dev *rt2x00dev = data;
struct rt2x00_intf *intf = vif_to_intf(vif); struct rt2x00_intf *intf = vif_to_intf(vif);
if (vif->type != IEEE80211_IF_TYPE_AP && if (vif->type != IEEE80211_IF_TYPE_AP &&
vif->type != IEEE80211_IF_TYPE_IBSS) vif->type != IEEE80211_IF_TYPE_IBSS)
return; return;
/*
* Clean up the beacon skb.
*/
rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
intf->beacon->skb = NULL;
spin_lock(&intf->lock); spin_lock(&intf->lock);
intf->delayed_flags |= DELAYED_UPDATE_BEACON; intf->delayed_flags |= DELAYED_UPDATE_BEACON;
spin_unlock(&intf->lock); spin_unlock(&intf->lock);
...@@ -498,6 +505,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -498,6 +505,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
{ {
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
/*
* Unmap the skb.
*/
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/* /*
* Send frame to debugfs immediately, after this call is completed * Send frame to debugfs immediately, after this call is completed
...@@ -546,39 +559,77 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -546,39 +559,77 @@ void rt2x00lib_txdone(struct queue_entry *entry,
ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
else else
dev_kfree_skb_irq(entry->skb); dev_kfree_skb_irq(entry->skb);
/*
* Make this entry available for reuse.
*/
entry->skb = NULL; entry->skb = NULL;
entry->flags = 0;
rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
__clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
*/
if (!rt2x00queue_threshold(entry->queue))
ieee80211_wake_queue(rt2x00dev->hw, qid);
} }
EXPORT_SYMBOL_GPL(rt2x00lib_txdone); EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
void rt2x00lib_rxdone(struct queue_entry *entry, void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc) struct queue_entry *entry)
{ {
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rxdone_entry_desc rxdesc;
struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate; const struct rt2x00_rate *rate;
unsigned int header_size;
unsigned int align; unsigned int align;
unsigned int i; unsigned int i;
int idx = -1; int idx = -1;
u16 fc;
/*
* Allocate a new sk_buffer. If no new buffer available, drop the
* received frame and reuse the existing buffer.
*/
skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
if (!skb)
return;
/*
* Unmap the skb.
*/
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/*
* Extract the RXD details.
*/
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/* /*
* The data behind the ieee80211 header must be * The data behind the ieee80211 header must be
* aligned on a 4 byte boundary. * aligned on a 4 byte boundary.
*/ */
header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
align = ((unsigned long)(entry->skb->data + header_size)) & 3; align = ((unsigned long)(entry->skb->data + header_size)) & 3;
if (align) { if (align) {
skb_push(entry->skb, align); skb_push(entry->skb, align);
/* Move entire frame in 1 command */ /* Move entire frame in 1 command */
memmove(entry->skb->data, entry->skb->data + align, memmove(entry->skb->data, entry->skb->data + align,
rxdesc->size); rxdesc.size);
} }
/* Update data pointers, trim buffer to correct size */ /* Update data pointers, trim buffer to correct size */
skb_trim(entry->skb, rxdesc->size); skb_trim(entry->skb, rxdesc.size);
/* /*
* Update RX statistics. * Update RX statistics.
...@@ -587,10 +638,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -587,10 +638,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
for (i = 0; i < sband->n_bitrates; i++) { for (i = 0; i < sband->n_bitrates; i++) {
rate = rt2x00_get_rate(sband->bitrates[i].hw_value); rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->plcp == rxdesc->signal)) || (rate->plcp == rxdesc.signal)) ||
(!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->bitrate == rxdesc->signal))) { (rate->bitrate == rxdesc.signal))) {
idx = i; idx = i;
break; break;
} }
...@@ -598,8 +649,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -598,8 +649,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
if (idx < 0) { if (idx < 0) {
WARNING(rt2x00dev, "Frame received with unrecognized signal," WARNING(rt2x00dev, "Frame received with unrecognized signal,"
"signal=0x%.2x, plcp=%d.\n", rxdesc->signal, "signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
!!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
idx = 0; idx = 0;
} }
...@@ -607,17 +658,17 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -607,17 +658,17 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
* Only update link status if this is a beacon frame carrying our bssid. * Only update link status if this is a beacon frame carrying our bssid.
*/ */
hdr = (struct ieee80211_hdr *)entry->skb->data; hdr = (struct ieee80211_hdr *)entry->skb->data;
fc = le16_to_cpu(hdr->frame_control); if (ieee80211_is_beacon(hdr->frame_control) &&
if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS)) (rxdesc.dev_flags & RXDONE_MY_BSS))
rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
rt2x00dev->link.qual.rx_success++; rt2x00dev->link.qual.rx_success++;
rx_status->rate_idx = idx; rx_status->rate_idx = idx;
rx_status->qual = rx_status->qual =
rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc->rssi; rx_status->signal = rxdesc.rssi;
rx_status->flag = rxdesc->flags; rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx; rx_status->antenna = rt2x00dev->link.ant.active.rx;
/* /*
...@@ -626,7 +677,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -626,7 +677,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
*/ */
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
entry->skb = NULL;
/*
* Replace the skb with the freshly allocated one.
*/
entry->skb = skb;
entry->flags = 0;
rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
rt2x00queue_index_inc(entry->queue, Q_INDEX);
} }
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
......
...@@ -98,10 +98,57 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -98,10 +98,57 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config); struct ieee80211_conf *conf, const int force_config);
/* /**
* Queue handlers. * DOC: Queue handlers
*/
/**
* rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @queue: The queue for which the skb will be applicable.
*/
struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry);
/**
* rt2x00queue_unmap_skb - Unmap a skb from DMA.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to unmap.
*/
void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
* rt2x00queue_free_skb - free a skb
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to free.
*/
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
* rt2x00queue_free_skb - free a skb
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to free.
*/
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
* rt2x00queue_write_tx_frame - Write TX frame to hardware
* @queue: Queue over which the frame should be send
* @skb: The skb to send
*/ */
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
/**
* rt2x00queue_index_inc - Index incrementation function
* @queue: Queue (&struct data_queue) to perform the action on.
* @index: Index type (&enum queue_index) to perform the action on.
*
* This function will increase the requested index on the queue,
* it will grab the appropriate locks and handle queue overflow events by
* resetting the index to the start of the queue.
*/
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
......
...@@ -60,12 +60,8 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry) ...@@ -60,12 +60,8 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry)
* Fill in skb descriptor * Fill in skb descriptor
*/ */
skbdesc = get_skb_frame_desc(entry->skb); skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry_priv->desc; skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = entry->queue->desc_size; skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
memcpy(entry_priv->data, entry->skb->data, entry->skb->len);
return 0; return 0;
} }
...@@ -80,7 +76,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) ...@@ -80,7 +76,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
struct queue_entry *entry; struct queue_entry *entry;
struct queue_entry_priv_pci *entry_priv; struct queue_entry_priv_pci *entry_priv;
struct skb_frame_desc *skbdesc; struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
u32 word; u32 word;
while (1) { while (1) {
...@@ -91,110 +86,27 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) ...@@ -91,110 +86,27 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
break; break;
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/* /*
* Allocate the sk_buffer and copy all data into it. * Fill in desc fields of the skb descriptor
*/
entry->skb = rt2x00queue_alloc_rxskb(queue);
if (!entry->skb)
return;
memcpy(entry->skb->data, entry_priv->data, rxdesc.size);
skb_trim(entry->skb, rxdesc.size);
/*
* Fill in skb descriptor
*/ */
skbdesc = get_skb_frame_desc(entry->skb); skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry_priv->desc; skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = queue->desc_size; skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
/* /*
* Send the frame to rt2x00lib for further processing. * Send the frame to rt2x00lib for further processing.
*/ */
rt2x00lib_rxdone(entry, &rxdesc); rt2x00lib_rxdone(rt2x00dev, entry);
if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) {
rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1);
rt2x00_desc_write(entry_priv->desc, 0, word);
}
rt2x00queue_index_inc(queue, Q_INDEX);
} }
} }
EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
u32 word;
rt2x00lib_txdone(entry, txdesc);
/*
* Make this entry available for reuse.
*/
entry->flags = 0;
rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0);
rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
rt2x00_desc_write(entry_priv->desc, 0, word);
__clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
*/
if (!rt2x00queue_threshold(entry->queue))
ieee80211_wake_queue(rt2x00dev->hw, qid);
}
EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
/* /*
* Device initialization handlers. * Device initialization handlers.
*/ */
#define desc_size(__queue) \
({ \
((__queue)->limit * (__queue)->desc_size);\
})
#define data_size(__queue) \
({ \
((__queue)->limit * (__queue)->data_size);\
})
#define dma_size(__queue) \
({ \
data_size(__queue) + desc_size(__queue);\
})
#define desc_offset(__queue, __base, __i) \
({ \
(__base) + data_size(__queue) + \
((__i) * (__queue)->desc_size); \
})
#define data_offset(__queue, __base, __i) \
({ \
(__base) + \
((__i) * (__queue)->data_size); \
})
static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue) struct data_queue *queue)
{ {
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
struct queue_entry_priv_pci *entry_priv; struct queue_entry_priv_pci *entry_priv;
void *addr; void *addr;
dma_addr_t dma; dma_addr_t dma;
...@@ -203,21 +115,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, ...@@ -203,21 +115,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
/* /*
* Allocate DMA memory for descriptor and buffer. * Allocate DMA memory for descriptor and buffer.
*/ */
addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); addr = dma_alloc_coherent(rt2x00dev->dev,
queue->limit * queue->desc_size,
&dma, GFP_KERNEL | GFP_DMA);
if (!addr) if (!addr)
return -ENOMEM; return -ENOMEM;
memset(addr, 0, dma_size(queue)); memset(addr, 0, queue->limit * queue->desc_size);
/* /*
* Initialize all queue entries to contain valid addresses. * Initialize all queue entries to contain valid addresses.
*/ */
for (i = 0; i < queue->limit; i++) { for (i = 0; i < queue->limit; i++) {
entry_priv = queue->entries[i].priv_data; entry_priv = queue->entries[i].priv_data;
entry_priv->desc = desc_offset(queue, addr, i); entry_priv->desc = addr + i * queue->desc_size;
entry_priv->desc_dma = desc_offset(queue, dma, i); entry_priv->desc_dma = dma + i * queue->desc_size;
entry_priv->data = data_offset(queue, addr, i);
entry_priv->data_dma = data_offset(queue, dma, i);
} }
return 0; return 0;
...@@ -226,19 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, ...@@ -226,19 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue) struct data_queue *queue)
{ {
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
struct queue_entry_priv_pci *entry_priv = struct queue_entry_priv_pci *entry_priv =
queue->entries[0].priv_data; queue->entries[0].priv_data;
if (entry_priv->data) if (entry_priv->desc)
pci_free_consistent(pci_dev, dma_size(queue), dma_free_coherent(rt2x00dev->dev,
entry_priv->data, entry_priv->data_dma); queue->limit * queue->desc_size,
entry_priv->data = NULL; entry_priv->desc, entry_priv->desc_dma);
entry_priv->desc = NULL;
} }
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
{ {
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
struct data_queue *queue; struct data_queue *queue;
int status; int status;
...@@ -279,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) ...@@ -279,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
/* /*
* Free irq line. * Free irq line.
*/ */
free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev); free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev);
/* /*
* Free DMA * Free DMA
...@@ -308,7 +220,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) ...@@ -308,7 +220,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
{ {
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0),
pci_resource_len(pci_dev, 0)); pci_resource_len(pci_dev, 0));
...@@ -357,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) ...@@ -357,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (pci_set_mwi(pci_dev)) if (pci_set_mwi(pci_dev))
ERROR_PROBE("MWI not available.\n"); ERROR_PROBE("MWI not available.\n");
if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) {
ERROR_PROBE("PCI DMA not supported.\n"); ERROR_PROBE("PCI DMA not supported.\n");
retval = -EIO; retval = -EIO;
goto exit_disable_device; goto exit_disable_device;
...@@ -373,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) ...@@ -373,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
pci_set_drvdata(pci_dev, hw); pci_set_drvdata(pci_dev, hw);
rt2x00dev = hw->priv; rt2x00dev = hw->priv;
rt2x00dev->dev = pci_dev; rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops; rt2x00dev->ops = ops;
rt2x00dev->hw = hw; rt2x00dev->hw = hw;
......
...@@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry); ...@@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry);
struct queue_entry_priv_pci { struct queue_entry_priv_pci {
__le32 *desc; __le32 *desc;
dma_addr_t desc_dma; dma_addr_t desc_dma;
void *data;
dma_addr_t data_dma;
}; };
/** /**
...@@ -118,15 +115,6 @@ struct queue_entry_priv_pci { ...@@ -118,15 +115,6 @@ struct queue_entry_priv_pci {
*/ */
void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
/**
* rt2x00pci_txdone - Handle TX done events
* @rt2x00dev: Device pointer, see &struct rt2x00_dev.
* @entry: Entry which has completed the transmission of a frame.
* @desc: TX done descriptor
*/
void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
struct txdone_entry_desc *desc);
/* /*
* Device initialization handlers. * Device initialization handlers.
*/ */
......
...@@ -25,34 +25,30 @@ ...@@ -25,34 +25,30 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/dma-mapping.h>
#include "rt2x00.h" #include "rt2x00.h"
#include "rt2x00lib.h" #include "rt2x00lib.h"
struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{ {
struct sk_buff *skb;
unsigned int frame_size; unsigned int frame_size;
unsigned int reserved_size; unsigned int reserved_size;
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
/* /*
* The frame size includes descriptor size, because the * The frame size includes descriptor size, because the
* hardware directly receive the frame into the skbuffer. * hardware directly receive the frame into the skbuffer.
*/ */
frame_size = queue->data_size + queue->desc_size; frame_size = entry->queue->data_size + entry->queue->desc_size;
/* /*
* For the allocation we should keep a few things in mind: * Reserve a few bytes extra headroom to allow drivers some moving
* 1) 4byte alignment of 802.11 payload * space (e.g. for alignment), while keeping the skb aligned.
*
* For (1) we need at most 4 bytes to guarentee the correct
* alignment. We are going to optimize the fact that the chance
* that the 802.11 header_size % 4 == 2 is much bigger then
* anything else. However since we need to move the frame up
* to 3 bytes to the front, which means we need to preallocate
* 6 bytes.
*/ */
reserved_size = 6; reserved_size = 8;
/* /*
* Allocate skbuffer. * Allocate skbuffer.
...@@ -64,9 +60,56 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) ...@@ -64,9 +60,56 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue)
skb_reserve(skb, reserved_size); skb_reserve(skb, reserved_size);
skb_put(skb, frame_size); skb_put(skb, frame_size);
/*
* Populate skbdesc.
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->entry = entry;
if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) {
skbdesc->skb_dma = dma_map_single(rt2x00dev->dev,
skb->data,
skb->len,
DMA_FROM_DEVICE);
skbdesc->flags |= SKBDESC_DMA_MAPPED_RX;
}
return skb; return skb;
} }
EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);
void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len,
DMA_TO_DEVICE);
skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
}
EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
DMA_FROM_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
}
if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
DMA_TO_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
}
}
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{
rt2x00queue_unmap_skb(rt2x00dev, skb);
dev_kfree_skb_any(skb);
}
void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
...@@ -80,7 +123,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ...@@ -80,7 +123,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
unsigned int data_length; unsigned int data_length;
unsigned int duration; unsigned int duration;
unsigned int residual; unsigned int residual;
u16 frame_control;
memset(txdesc, 0, sizeof(*txdesc)); memset(txdesc, 0, sizeof(*txdesc));
...@@ -95,11 +137,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ...@@ -95,11 +137,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/* Data length should be extended with 4 bytes for CRC */ /* Data length should be extended with 4 bytes for CRC */
data_length = entry->skb->len + 4; data_length = entry->skb->len + 4;
/*
* Read required fields from ieee80211 header.
*/
frame_control = le16_to_cpu(hdr->frame_control);
/* /*
* Check whether this frame is to be acked. * Check whether this frame is to be acked.
*/ */
...@@ -109,9 +146,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ...@@ -109,9 +146,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/* /*
* Check if this is a RTS/CTS frame * Check if this is a RTS/CTS frame
*/ */
if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { if (ieee80211_is_rts(hdr->frame_control) ||
ieee80211_is_cts(hdr->frame_control)) {
__set_bit(ENTRY_TXD_BURST, &txdesc->flags); __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
if (is_rts_frame(frame_control)) if (ieee80211_is_rts(hdr->frame_control))
__set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags); __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
else else
__set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
...@@ -139,7 +177,8 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ...@@ -139,7 +177,8 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Beacons and probe responses require the tsf timestamp * Beacons and probe responses require the tsf timestamp
* to be inserted into the frame. * to be inserted into the frame.
*/ */
if (txdesc->queue == QID_BEACON || is_probe_resp(frame_control)) if (ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control))
__set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
/* /*
...@@ -236,6 +275,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -236,6 +275,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
{ {
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc; struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
if (unlikely(rt2x00queue_full(queue))) if (unlikely(rt2x00queue_full(queue)))
return -EINVAL; return -EINVAL;
...@@ -256,11 +296,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -256,11 +296,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb; entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc); rt2x00queue_create_tx_descriptor(entry, &txdesc);
/*
* skb->cb array is now ours and we are free to use it.
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->entry = entry;
if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
__clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
return -EIO; return -EIO;
} }
if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
rt2x00queue_map_txskb(queue->rt2x00dev, skb);
__set_bit(ENTRY_DATA_PENDING, &entry->flags); __set_bit(ENTRY_DATA_PENDING, &entry->flags);
rt2x00queue_index_inc(queue, Q_INDEX); rt2x00queue_index_inc(queue, Q_INDEX);
...@@ -336,7 +386,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) ...@@ -336,7 +386,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
spin_unlock_irqrestore(&queue->lock, irqflags); spin_unlock_irqrestore(&queue->lock, irqflags);
} }
EXPORT_SYMBOL_GPL(rt2x00queue_index_inc);
static void rt2x00queue_reset(struct data_queue *queue) static void rt2x00queue_reset(struct data_queue *queue)
{ {
...@@ -426,12 +475,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, ...@@ -426,12 +475,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
return 0; return 0;
} }
static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
unsigned int i;
if (!queue->entries)
return;
for (i = 0; i < queue->limit; i++) {
if (queue->entries[i].skb)
rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
}
}
static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
unsigned int i;
struct sk_buff *skb;
for (i = 0; i < queue->limit; i++) {
skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]);
if (!skb)
return -ENOMEM;
queue->entries[i].skb = skb;
}
return 0;
}
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
{ {
struct data_queue *queue; struct data_queue *queue;
int status; int status;
status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx);
if (status) if (status)
goto exit; goto exit;
...@@ -446,11 +524,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) ...@@ -446,11 +524,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
if (status) if (status)
goto exit; goto exit;
if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) {
return 0; status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1],
rt2x00dev->ops->atim);
if (status)
goto exit;
}
status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
rt2x00dev->ops->atim);
if (status) if (status)
goto exit; goto exit;
...@@ -468,6 +549,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) ...@@ -468,6 +549,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
{ {
struct data_queue *queue; struct data_queue *queue;
rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
queue_for_each(rt2x00dev, queue) { queue_for_each(rt2x00dev, queue) {
kfree(queue->entries); kfree(queue->entries);
queue->entries = NULL; queue->entries = NULL;
......
...@@ -42,15 +42,18 @@ ...@@ -42,15 +42,18 @@
/** /**
* DOC: Number of entries per queue * DOC: Number of entries per queue
* *
* After research it was concluded that 12 entries in a RX and TX * Under normal load without fragmentation 12 entries are sufficient
* queue would be sufficient. Although this is almost one third of * without the queue being filled up to the maximum. When using fragmentation
* the amount the legacy driver allocated, the queues aren't getting * and the queue threshold code we need to add some additional margins to
* filled to the maximum even when working with the maximum rate. * make sure the queue will never (or only under extreme load) fill up
* completely.
* Since we don't use preallocated DMA having a large number of queue entries
* will have only minimal impact on the memory requirements for the queue.
*/ */
#define RX_ENTRIES 12 #define RX_ENTRIES 24
#define TX_ENTRIES 12 #define TX_ENTRIES 24
#define BEACON_ENTRIES 1 #define BEACON_ENTRIES 1
#define ATIM_ENTRIES 1 #define ATIM_ENTRIES 8
/** /**
* enum data_queue_qid: Queue identification * enum data_queue_qid: Queue identification
...@@ -82,10 +85,13 @@ enum data_queue_qid { ...@@ -82,10 +85,13 @@ enum data_queue_qid {
/** /**
* enum skb_frame_desc_flags: Flags for &struct skb_frame_desc * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
* *
* @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
* @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
*/ */
//enum skb_frame_desc_flags { enum skb_frame_desc_flags {
// TEMPORARILY EMPTY SKBDESC_DMA_MAPPED_RX = (1 << 0),
//}; SKBDESC_DMA_MAPPED_TX = (1 << 1),
};
/** /**
* struct skb_frame_desc: Descriptor information for the skb buffer * struct skb_frame_desc: Descriptor information for the skb buffer
...@@ -94,19 +100,20 @@ enum data_queue_qid { ...@@ -94,19 +100,20 @@ enum data_queue_qid {
* this structure should not exceed the size of that array (40 bytes). * this structure should not exceed the size of that array (40 bytes).
* *
* @flags: Frame flags, see &enum skb_frame_desc_flags. * @flags: Frame flags, see &enum skb_frame_desc_flags.
* @data: Pointer to data part of frame (Start of ieee80211 header). * @desc_len: Length of the frame descriptor.
* @desc: Pointer to descriptor part of the frame. * @desc: Pointer to descriptor part of the frame.
* Note that this pointer could point to something outside * Note that this pointer could point to something outside
* of the scope of the skb->data pointer. * of the scope of the skb->data pointer.
* @data_len: Length of the frame data. * @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
* @desc_len: Length of the frame descriptor.
* @entry: The entry to which this sk buffer belongs. * @entry: The entry to which this sk buffer belongs.
*/ */
struct skb_frame_desc { struct skb_frame_desc {
unsigned int flags; unsigned int flags;
void *desc;
unsigned int desc_len; unsigned int desc_len;
void *desc;
dma_addr_t skb_dma;
struct queue_entry *entry; struct queue_entry *entry;
}; };
......
...@@ -45,14 +45,17 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) ...@@ -45,14 +45,17 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
return 0; return 0;
if (state == RFKILL_STATE_ON) { if (state == RFKILL_STATE_UNBLOCKED) {
INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
__clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
retval = rt2x00lib_enable_radio(rt2x00dev); retval = rt2x00lib_enable_radio(rt2x00dev);
} else if (state == RFKILL_STATE_OFF) { } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n");
__set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
rt2x00lib_disable_radio(rt2x00dev); rt2x00lib_disable_radio(rt2x00dev);
} else {
WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n",
state);
} }
return retval; return retval;
......
...@@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, ...@@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
void *buffer, const u16 buffer_length, void *buffer, const u16 buffer_length,
const int timeout) const int timeout)
{ {
struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
int status; int status;
unsigned int i; unsigned int i;
unsigned int pipe = unsigned int pipe =
...@@ -130,10 +130,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) ...@@ -130,10 +130,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
struct queue_entry *entry = (struct queue_entry *)urb->context; struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct txdone_entry_desc txdesc; struct txdone_entry_desc txdesc;
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return; return;
/* /*
...@@ -157,26 +156,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) ...@@ -157,26 +156,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
txdesc.retry = 0; txdesc.retry = 0;
rt2x00lib_txdone(entry, &txdesc); rt2x00lib_txdone(entry, &txdesc);
/*
* Make this entry available for reuse.
*/
entry->flags = 0;
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
*/
if (!rt2x00queue_threshold(entry->queue))
ieee80211_wake_queue(rt2x00dev->hw, qid);
} }
int rt2x00usb_write_tx_data(struct queue_entry *entry) int rt2x00usb_write_tx_data(struct queue_entry *entry)
{ {
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc; struct skb_frame_desc *skbdesc;
u32 length; u32 length;
...@@ -191,10 +176,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry) ...@@ -191,10 +176,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
* Fill in skb descriptor * Fill in skb descriptor
*/ */
skbdesc = get_skb_frame_desc(entry->skb); skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry->skb->data; skbdesc->desc = entry->skb->data;
skbdesc->desc_len = entry->queue->desc_size; skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
/* /*
* USB devices cannot blindly pass the skb->len as the * USB devices cannot blindly pass the skb->len as the
...@@ -264,13 +247,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) ...@@ -264,13 +247,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{ {
struct queue_entry *entry = (struct queue_entry *)urb->context; struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct sk_buff *skb; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
u8 rxd[32]; u8 rxd[32];
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return; return;
/* /*
...@@ -278,50 +259,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) ...@@ -278,50 +259,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* to be actually valid, or if the urb is signaling * to be actually valid, or if the urb is signaling
* a problem. * a problem.
*/ */
if (urb->actual_length < entry->queue->desc_size || urb->status) if (urb->actual_length < entry->queue->desc_size || urb->status) {
goto skip_entry; __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
usb_submit_urb(urb, GFP_ATOMIC);
return;
}
/* /*
* Fill in skb descriptor * Fill in desc fields of the skb descriptor
*/ */
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->entry = entry;
skbdesc->desc = rxd; skbdesc->desc = rxd;
skbdesc->desc_len = entry->queue->desc_size; skbdesc->desc_len = entry->queue->desc_size;
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/*
* Allocate a new sk buffer to replace the current one.
* If allocation fails, we should drop the current frame
* so we can recycle the existing sk buffer for the new frame.
*/
skb = rt2x00queue_alloc_rxskb(entry->queue);
if (!skb)
goto skip_entry;
/* /*
* Send the frame to rt2x00lib for further processing. * Send the frame to rt2x00lib for further processing.
*/ */
rt2x00lib_rxdone(entry, &rxdesc); rt2x00lib_rxdone(rt2x00dev, entry);
/*
* Replace current entry's skb with the newly allocated one,
* and reinitialize the urb.
*/
entry->skb = skb;
urb->transfer_buffer = entry->skb->data;
urb->transfer_buffer_length = entry->skb->len;
skip_entry:
if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) {
__set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
usb_submit_urb(urb, GFP_ATOMIC);
}
rt2x00queue_index_inc(entry->queue, Q_INDEX);
} }
/* /*
...@@ -331,6 +284,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) ...@@ -331,6 +284,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{ {
struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb *entry_priv;
struct queue_entry_priv_usb_bcn *bcn_priv; struct queue_entry_priv_usb_bcn *bcn_priv;
struct data_queue *queue;
unsigned int i; unsigned int i;
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
...@@ -339,9 +293,11 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) ...@@ -339,9 +293,11 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
/* /*
* Cancel all queues. * Cancel all queues.
*/ */
for (i = 0; i < rt2x00dev->rx->limit; i++) { queue_for_each(rt2x00dev, queue) {
entry_priv = rt2x00dev->rx->entries[i].priv_data; for (i = 0; i < queue->limit; i++) {
usb_kill_urb(entry_priv->urb); entry_priv = queue->entries[i].priv_data;
usb_kill_urb(entry_priv->urb);
}
} }
/* /*
...@@ -364,7 +320,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); ...@@ -364,7 +320,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry) struct queue_entry *entry)
{ {
struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct queue_entry_priv_usb *entry_priv = entry->priv_data;
usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_fill_bulk_urb(entry_priv->urb, usb_dev,
...@@ -431,8 +387,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, ...@@ -431,8 +387,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
entry_priv = queue->entries[i].priv_data; entry_priv = queue->entries[i].priv_data;
usb_kill_urb(entry_priv->urb); usb_kill_urb(entry_priv->urb);
usb_free_urb(entry_priv->urb); usb_free_urb(entry_priv->urb);
if (queue->entries[i].skb)
kfree_skb(queue->entries[i].skb);
} }
/* /*
...@@ -454,10 +408,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, ...@@ -454,10 +408,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
{ {
struct data_queue *queue; struct data_queue *queue;
struct sk_buff *skb; int status;
unsigned int entry_size;
unsigned int i;
int uninitialized_var(status);
/* /*
* Allocate DMA * Allocate DMA
...@@ -468,18 +419,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) ...@@ -468,18 +419,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
goto exit; goto exit;
} }
/*
* For the RX queue, skb's should be allocated.
*/
entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
for (i = 0; i < rt2x00dev->rx->limit; i++) {
skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);
if (!skb)
goto exit;
rt2x00dev->rx->entries[i].skb = skb;
}
return 0; return 0;
exit: exit:
...@@ -558,7 +497,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, ...@@ -558,7 +497,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
usb_set_intfdata(usb_intf, hw); usb_set_intfdata(usb_intf, hw);
rt2x00dev = hw->priv; rt2x00dev = hw->priv;
rt2x00dev->dev = usb_intf; rt2x00dev->dev = &usb_intf->dev;
rt2x00dev->ops = ops; rt2x00dev->ops = ops;
rt2x00dev->hw = hw; rt2x00dev->hw = hw;
mutex_init(&rt2x00dev->usb_cache_mutex); mutex_init(&rt2x00dev->usb_cache_mutex);
......
...@@ -26,6 +26,12 @@ ...@@ -26,6 +26,12 @@
#ifndef RT2X00USB_H #ifndef RT2X00USB_H
#define RT2X00USB_H #define RT2X00USB_H
#define to_usb_device_intf(d) \
({ \
struct usb_interface *intf = to_usb_interface(d); \
interface_to_usbdev(intf); \
})
/* /*
* This variable should be used with the * This variable should be used with the
* usb_driver structure initialization. * usb_driver structure initialization.
......
...@@ -1827,7 +1827,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1827,7 +1827,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM; IEEE80211_HW_SIGNAL_DBM;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev, rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0)); EEPROM_MAC_ADDR_0));
...@@ -2007,6 +2007,12 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -2007,6 +2007,12 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
REGISTER_TIMEOUT32(skb->len)); REGISTER_TIMEOUT32(skb->len));
rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON);
/*
* Clean up the beacon skb.
*/
dev_kfree_skb(skb);
intf->beacon->skb = NULL;
return 0; return 0;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane" ...@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane"
config SSB_POSSIBLE config SSB_POSSIBLE
bool bool
depends on HAS_IOMEM depends on HAS_IOMEM && HAS_DMA
default y default y
config SSB config SSB
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -241,7 +241,10 @@ enum nl80211_attrs { ...@@ -241,7 +241,10 @@ enum nl80211_attrs {
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
}; };
#define NL80211_MAX_SUPP_RATES 32 #define NL80211_MAX_SUPP_RATES 32
#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
/** /**
* enum nl80211_iftype - (virtual) interface types * enum nl80211_iftype - (virtual) interface types
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册