提交 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
M: ionut@cs.columbia.edu
S: Maintained
STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
W: http://mosquitonet.Stanford.EDU/strip.html
S: Unsupported ?
STRADIS MPEG-2 DECODER DRIVER
P: Nathan Laredo
M: laredo@gnu.org
......
......@@ -148,9 +148,9 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
unsigned long offset,
enum dma_data_direction dir)
{
dma_sync_single_range_for_device(sdev->dma_dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
ssb_dma_sync_single_range_for_device(sdev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}
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,
enum dma_data_direction dir)
{
dma_sync_single_range_for_cpu(sdev->dma_dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
......@@ -613,10 +613,10 @@ static void b44_tx(struct b44 *bp)
BUG_ON(skb == NULL);
dma_unmap_single(bp->sdev->dma_dev,
rp->mapping,
skb->len,
DMA_TO_DEVICE);
ssb_dma_unmap_single(bp->sdev,
rp->mapping,
skb->len,
DMA_TO_DEVICE);
rp->skb = NULL;
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)
if (skb == NULL)
return -ENOMEM;
mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
mapping = ssb_dma_map_single(bp->sdev, skb->data,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
/* Hardware bug work-around, the chip is unable to do PCI DMA
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) {
/* Sigh... */
if (!dma_mapping_error(mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping,
RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping,
RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
if (skb == NULL)
return -ENOMEM;
mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
if (dma_mapping_error(mapping) ||
mapping = ssb_dma_map_single(bp->sdev, skb->data,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
if (!dma_mapping_error(mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
return -ENOMEM;
}
......@@ -750,9 +750,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_idx * sizeof(dest_desc),
DMA_BIDIRECTIONAL);
dma_sync_single_for_device(bp->sdev->dma_dev, le32_to_cpu(src_desc->addr),
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
}
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;
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,
DMA_FROM_DEVICE);
rh = (struct rx_header *) skb->data;
......@@ -806,8 +806,8 @@ static int b44_rx(struct b44 *bp, int budget)
skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
if (skb_size < 0)
goto drop_it;
dma_unmap_single(bp->sdev->dma_dev, map,
skb_size, DMA_FROM_DEVICE);
ssb_dma_unmap_single(bp->sdev, map,
skb_size, DMA_FROM_DEVICE);
/* Leave out rx_header */
skb_put(skb, len + 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)
goto err_out;
}
mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
struct sk_buff *bounce_skb;
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
if (!dma_mapping_error(mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping, len,
DMA_TO_DEVICE);
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, len,
DMA_TO_DEVICE);
bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb)
goto err_out;
mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
len, DMA_TO_DEVICE);
if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
if (!dma_mapping_error(mapping))
dma_unmap_single(bp->sdev->dma_dev, mapping,
len, DMA_TO_DEVICE);
mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
len, DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping,
len, DMA_TO_DEVICE);
dev_kfree_skb_any(bounce_skb);
goto err_out;
}
......@@ -1082,8 +1082,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
......@@ -1094,8 +1094,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
DMA_TO_DEVICE);
ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len,
DMA_TO_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
......@@ -1117,14 +1117,14 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
if (bp->flags & B44_FLAG_RX_RING_HACK)
dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
if (bp->flags & B44_FLAG_TX_RING_HACK)
dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
......@@ -1144,25 +1144,27 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
if (bp->rx_ring) {
if (bp->flags & B44_FLAG_RX_RING_HACK) {
dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
kfree(bp->rx_ring);
} else
dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma);
ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma,
GFP_KERNEL);
bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
if (bp->flags & B44_FLAG_TX_RING_HACK) {
dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
kfree(bp->tx_ring);
} else
dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma);
ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma,
GFP_KERNEL);
bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
......@@ -1187,7 +1189,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
goto out_err;
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) {
/* Allocation may have failed due to pci_alloc_consistent
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)
if (!rx_ring)
goto out_err;
rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
DMA_TABLE_BYTES,
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) {
kfree(rx_ring);
goto out_err;
......@@ -1214,9 +1216,9 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
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) {
/* 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
than necessary... */
struct dma_desc *tx_ring;
......@@ -1226,11 +1228,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!tx_ring)
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_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) {
kfree(tx_ring);
goto out_err;
......
......@@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
* independent format
*/
static char *gelic_wl_translate_scan(struct net_device *netdev,
struct iw_request_info *info,
char *ev,
char *stop,
struct gelic_wl_scan_info *network)
......@@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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 */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
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 */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = be16_to_cpu(scan->channel);
iwe.u.freq.e = 0; /* table value in MHz */
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 */
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
/* 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) */
i = 0;
j = 0;
......@@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else
rate = scan->rate[i++] & 0x7f;
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);
}
while (j < network->rate_ext_len) {
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);
}
/* Check if we added any rate */
if (IW_EV_LCP_LEN < (tmp - ev))
if (iwe_stream_lcp_len(info) < (tmp - ev))
ev = tmp;
/* ENCODE */
......@@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
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 */
iwe.cmd = SIOCGIWMODE;
......@@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.u.mode = IW_MODE_MASTER;
else
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 */
......@@ -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.qual = be16_to_cpu(scan->rssi);
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 */
memset(&iwe, 0, sizeof(iwe));
......@@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
if (len) {
iwe.cmd = IWEVGENIE;
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 {
/* this scan info has IE data */
......@@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
iwe.cmd = IWEVGENIE;
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))) {
......@@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
iwe.cmd = IWEVGENIE;
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,
if (wl->scan_age == 0 ||
time_after(scan_info->last_scanned + wl->scan_age,
this_time))
ev = gelic_wl_translate_scan(netdev, ev, stop,
ev = gelic_wl_translate_scan(netdev, info,
ev, stop,
scan_info);
else
pr_debug("%s:entry too old\n", __func__);
......
......@@ -14,30 +14,6 @@ config WLAN_PRE80211
This option does not affect the kernel build, it only
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
tristate "Aironet Arlan 655 & IC2200 DS support"
depends on ISA && !64BIT && WLAN_PRE80211
......
......@@ -6,7 +6,6 @@ obj-$(CONFIG_IPW2100) += ipw2100.o
obj-$(CONFIG_IPW2200) += ipw2200.o
obj-$(CONFIG_STRIP) += strip.o
obj-$(CONFIG_ARLAN) += arlan.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,
static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct adm8211_tx_hdr *txhdr;
u16 fc;
size_t payload_len, hdrlen;
int plcp, dur, len, plcp_signal, short_preamble;
struct ieee80211_hdr *hdr;
......@@ -1696,8 +1695,7 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
plcp_signal = txrate->bitrate;
hdr = (struct ieee80211_hdr *)skb->data;
fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
hdrlen = ieee80211_get_hdrlen(fc);
hdrlen = ieee80211_hdrlen(hdr->frame_control);
memcpy(skb->cb, skb->data, hdrlen);
hdr = (struct ieee80211_hdr *)skb->cb;
skb_pull(skb, hdrlen);
......@@ -1711,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
txhdr->frame_control = hdr->frame_control;
len = hdrlen + payload_len + FCS_LEN;
if (fc & IEEE80211_FCTL_PROTECTED)
len += 8;
txhdr->frag = cpu_to_le16(0x0FFF);
adm8211_calc_durations(&dur, &plcp, payload_len,
......@@ -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)
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;
adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
......
......@@ -85,10 +85,10 @@ static struct pci_driver airo_driver = {
/* Include Wireless Extension definition and check version - Jean II */
#include <linux/wireless.h>
#define WIRELESS_SPY // enable iwspy support
#include <net/iw_handler.h> // New driver API
#define WIRELESS_SPY /* enable iwspy support */
#include <net/iw_handler.h> /* New driver API */
#define CISCO_EXT // enable Cisco extensions
#define CISCO_EXT /* enable Cisco extensions */
#ifdef CISCO_EXT
#include <linux/delay.h>
#endif
......@@ -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
IN4500. I would be extremely interested in the situation where this
doesn't work though!!! */
static int do8bitIO = 0;
static int do8bitIO /* = 0 */;
/* Return codes */
#define SUCCESS 0
......@@ -398,8 +398,8 @@ static int do8bitIO = 0;
#define MAXTXQ 64
/* BAP selectors */
#define BAP0 0 // Used for receiving packets
#define BAP1 2 // Used for xmiting packets and working with RIDS
#define BAP0 0 /* Used for receiving packets */
#define BAP1 2 /* Used for xmiting packets and working with RIDS */
/* Flags */
#define COMMAND_BUSY 0x8000
......@@ -5522,11 +5522,13 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
Cmd cmd;
Resp rsp;
if ((ai->APList == NULL) &&
(ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
if (!ai->APList)
ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL);
if (!ai->APList)
return -ENOMEM;
if ((ai->SSID == NULL) &&
(ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
if (!ai->SSID)
ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
if (!ai->SSID)
return -ENOMEM;
readAPListRid(ai, ai->APList);
readSsidRid(ai, ai->SSID);
......@@ -5537,7 +5539,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
disable_MAC(ai, 0);
netif_device_detach(dev);
ai->power = state;
cmd.cmd=HOSTSLEEP;
cmd.cmd = HOSTSLEEP;
issuecommand(ai, &cmd, &rsp);
pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
......@@ -5567,7 +5569,7 @@ static int airo_pci_resume(struct pci_dev *pdev)
msleep(100);
}
set_bit (FLAG_COMMIT, &ai->flags);
set_bit(FLAG_COMMIT, &ai->flags);
disable_MAC(ai, 0);
msleep(200);
if (ai->SSID) {
......@@ -5594,9 +5596,6 @@ static int airo_pci_resume(struct pci_dev *pdev)
static int __init airo_init_module( void )
{
int i;
#if 0
int have_isa_dev = 0;
#endif
airo_entry = create_proc_entry("driver/aironet",
S_IFDIR | airo_perm,
......@@ -5607,15 +5606,11 @@ static int __init airo_init_module( void )
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 "
"io=0x%x", irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL ))
#if 0
have_isa_dev = 1;
#else
/* do nothing */ ;
#endif
}
#ifdef CONFIG_PCI
......@@ -5661,7 +5656,7 @@ static void __exit airo_cleanup_module( void )
static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
{
if( !rssi_rid )
if (!rssi_rid)
return 0;
return (0x100 - rssi_rid[rssi].rssidBm);
......@@ -5671,10 +5666,10 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
{
int i;
if( !rssi_rid )
if (!rssi_rid)
return 0;
for( i = 0; i < 256; i++ )
for (i = 0; i < 256; i++)
if (rssi_rid[i].rssidBm == dbm)
return rssi_rid[i].rssipct;
......@@ -7156,6 +7151,7 @@ static int airo_set_scan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II
*/
static inline char *airo_translate_scan(struct net_device *dev,
struct iw_request_info *info,
char *current_ev,
char *end_buf,
BSSListRid *bss)
......@@ -7172,7 +7168,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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 */
......@@ -7182,7 +7179,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
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 */
iwe.cmd = SIOCGIWMODE;
......@@ -7192,7 +7190,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
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 */
......@@ -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.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);
......@@ -7223,7 +7223,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
| IW_QUAL_DBM;
}
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 */
iwe.cmd = SIOCGIWENCODE;
......@@ -7232,11 +7233,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
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
* 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;
/* Those two flags are ignored... */
......@@ -7249,10 +7251,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* 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 */
if((current_val - current_ev) > IW_EV_LCP_LEN)
if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val;
/* Beacon interval */
......@@ -7261,7 +7265,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
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);
}
......@@ -7295,8 +7300,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, (char *) info_element);
current_ev = iwe_stream_add_point(
info, current_ev,
end_buf, &iwe,
(char *) info_element);
}
break;
......@@ -7304,8 +7311,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, (char *) info_element);
current_ev = iwe_stream_add_point(
info, current_ev, end_buf,
&iwe, (char *) info_element);
break;
default:
......@@ -7344,7 +7352,7 @@ static int airo_get_scan(struct net_device *dev,
list_for_each_entry (net, &ai->network_list, list) {
/* 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,
&net->bss);
......
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
......
......@@ -58,11 +58,6 @@
#include "reg.h"
#include "debug.h"
enum {
ATH_LED_TX,
ATH_LED_RX,
};
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
......@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data);
/* LED functions */
static void ath5k_led_off(unsigned long data);
static void ath5k_led_blink(struct ath5k_softc *sc,
unsigned int on,
unsigned int off);
static void ath5k_led_event(struct ath5k_softc *sc,
int event);
static int ath5k_init_leds(struct ath5k_softc *sc);
static void ath5k_led_enable(struct ath5k_softc *sc);
static void ath5k_led_off(struct ath5k_softc *sc);
static void ath5k_unregister_leds(struct ath5k_softc *sc);
/*
* Module init/exit functions
......@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath5k_softc *sc = hw->priv;
if (test_bit(ATH_STAT_LEDSOFT, sc->status))
ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
ath5k_led_off(sc);
ath5k_stop_hw(sc);
pci_save_state(pdev);
......@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0);
ath5k_init(sc);
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, 0);
}
ath5k_led_enable(sc);
/*
* Reset the key cache since some parts do not
......@@ -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->restq, ath5k_tasklet_reset, (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);
SET_IEEE80211_PERM_ADDR(hw, mac);
......@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
goto err_queues;
}
ath5k_init_leds(sc);
return 0;
err_queues:
ath5k_txq_release(sc);
......@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_desc_free(sc, pdev);
ath5k_txq_release(sc);
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
ath5k_unregister_leds(sc);
/*
* NB: can't reclaim these until after ieee80211_ifdetach
......@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
return 0;
}
/*
* TODO: CLEAN THIS !!!
*/
static void
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;
if (mode == AR5K_MODE_11A) {
......@@ -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
the hw does not set the index used to decrypt. In such cases
get the index from the packet. */
if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
skb->len >= hlen + 4) {
if (ieee80211_has_protected(hdr->frame_control) &&
!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
skb->len >= hlen + 4) {
keyix = skb->data[hlen + 3] >> 6;
if (test_bit(keyix, sc->keymap))
......@@ -1712,10 +1626,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) ==
IEEE80211_FTYPE_MGMT &&
(le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) ==
IEEE80211_STYPE_BEACON &&
if (ieee80211_is_beacon(mgmt->frame_control) &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
/*
......@@ -1903,8 +1814,6 @@ ath5k_tasklet_rx(unsigned long data)
ath5k_check_ibss_tsf(sc, skb, &rxs);
__ieee80211_rx(sc->hw, skb, &rxs);
sc->led_rxrate = rs.rs_rate;
ath5k_led_event(sc, ATH_LED_RX);
next:
list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0);
......@@ -1985,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data)
struct ath5k_softc *sc = (void *)data;
ath5k_tx_processq(sc, sc->txq);
ath5k_led_event(sc, ATH_LED_TX);
}
/*****************\
* Beacon handling *
\*****************/
......@@ -2366,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
ieee80211_stop_queues(sc->hw);
if (!test_bit(ATH_STAT_INVALID, sc->status)) {
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
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_led_off(sc);
ath5k_hw_set_intr(ah, 0);
}
ath5k_txq_cleanup(sc);
......@@ -2566,55 +2467,124 @@ ath5k_calibrate(unsigned long data)
\***************/
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_LEDENDBLINK, sc->status))
__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);
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
ath5k_led_off(sc);
}
}
/*
* Blink the LED according to the specified on/off times.
*/
static void
ath5k_led_blink(struct ath5k_softc *sc, unsigned int on,
unsigned int off)
ath5k_led_on(struct ath5k_softc *sc)
{
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);
__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
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;
if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status)))
return; /* don't interrupt active blink */
switch (event) {
case ATH_LED_TX:
ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon,
sc->hwmap[sc->led_txrate].ledoff);
break;
case ATH_LED_RX:
ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon,
sc->hwmap[sc->led_rxrate].ledoff);
break;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
}
static void
ath5k_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
led_dev);
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 *
......@@ -2625,7 +2595,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_buf *bf;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned long flags;
int hdrlen;
int pad;
......@@ -2651,8 +2620,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
memmove(skb->data, skb->data+pad, hdrlen);
}
sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value;
spin_lock_irqsave(&sc->txbuflock, flags);
if (list_empty(&sc->txbuf)) {
ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
......
......@@ -45,6 +45,7 @@
#include <linux/list.h>
#include <linux/wireless.h>
#include <linux/if_ether.h>
#include <linux/leds.h>
#include "ath5k.h"
#include "debug.h"
......@@ -79,6 +80,19 @@ struct ath5k_txq {
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
#define ATH_CHAN_MAX (26+26+26+200+200)
#else
......@@ -118,13 +132,11 @@ struct ath5k_softc {
size_t desc_len; /* size of TX/RX descriptors */
u16 cachelsz; /* cache line size */
DECLARE_BITMAP(status, 6);
DECLARE_BITMAP(status, 4);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
#define ATH_STAT_PROMISC 2
#define ATH_STAT_LEDBLINKING 3 /* LED blink operation active */
#define ATH_STAT_LEDENDBLINK 4 /* finish LED blink operation */
#define ATH_STAT_LEDSOFT 5 /* enable LED gpio status */
#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
unsigned int curmode; /* current phy mode */
......@@ -132,13 +144,6 @@ struct ath5k_softc {
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 */
DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
......@@ -148,9 +153,6 @@ struct ath5k_softc {
unsigned int led_pin, /* GPIO pin for driving LED */
led_on, /* pin setting for LED on */
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 */
......@@ -159,6 +161,7 @@ struct ath5k_softc {
spinlock_t rxbuflock;
u32 *rxlink; /* link ptr in last RX desc */
struct tasklet_struct rxtq; /* rx intr tasklet */
struct ath5k_led rx_led; /* rx led */
struct list_head txbuf; /* transmit buffer */
spinlock_t txbuflock;
......@@ -167,6 +170,7 @@ struct ath5k_softc {
struct ath5k_txq *txq; /* beacon and tx*/
struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
......
......@@ -31,14 +31,14 @@
#include "base.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_11b = AR5K_RATES_11B;
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_xr = AR5K_RATES_XR;
/*Prototypes*/
/* Prototypes */
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_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
......
......@@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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;
if (iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
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.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.u.freq.m = priv->BSSinfo[i].channel;
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 */
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level;
/* 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;
......@@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
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 */
......
......@@ -441,6 +441,8 @@ enum {
#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
/* The firmware register that contains the watchdog counter. */
#define B43_WATCHDOG_REG 1
/* Device specific rate values.
* The actual values defined here are (rate_in_mbps * 2).
......
......@@ -74,70 +74,327 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
} while (0)
/* wl->irq_lock is locked */
static ssize_t tsf_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
/* The biggest address values for SHM access from the debugfs files. */
#define B43_MAX_SHM_ROUTING 4
#define B43_MAX_SHM_ADDR 0xFFFF
static ssize_t shm16read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
u64 tsf;
unsigned int routing, addr;
u16 val;
b43_tsf_read(dev, &tsf);
fappend("0x%08x%08x\n",
(unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
(unsigned int)(tsf & 0xFFFFFFFFULL));
routing = dev->dfsentry->shm16read_routing_next;
addr = dev->dfsentry->shm16read_addr_next;
if ((routing > B43_MAX_SHM_ROUTING) ||
(addr > B43_MAX_SHM_ADDR))
return -EDESTADDRREQ;
val = b43_shm_read16(dev, routing, addr);
fappend("0x%04X\n", val);
return count;
}
/* wl->irq_lock is locked */
static int tsf_write_file(struct b43_wldev *dev,
const char *buf, size_t count)
static int shm16read__write_file(struct b43_wldev *dev,
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;
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;
}
/* wl->irq_lock is locked */
static ssize_t ucode_regs_read_file(struct b43_wldev *dev,
static int shm16write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int routing, addr, mask, set;
u16 val;
int res;
unsigned long flags;
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
&routing, &addr, &mask, &set);
if (res != 4)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
if ((mask > 0xFFFF) || (set > 0xFFFF))
return -E2BIG;
spin_lock_irqsave(&dev->wl->shm_lock, flags);
if (mask == 0)
val = 0;
else
val = __b43_shm_read16(dev, routing, addr);
val &= mask;
val |= set;
__b43_shm_write16(dev, routing, addr, val);
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
return 0;
}
static ssize_t shm32read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
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++) {
fappend("r%d = 0x%04x\n", i,
b43_shm_read16(dev, B43_SHM_SCRATCH, i));
val = b43_shm_read32(dev, routing, addr);
fappend("0x%08X\n", val);
return count;
}
static int shm32read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int routing, addr;
int res;
res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
if (res != 2)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
dev->dfsentry->shm32read_routing_next = routing;
dev->dfsentry->shm32read_addr_next = addr;
return 0;
}
static int shm32write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int routing, addr, mask, set;
u32 val;
int res;
unsigned long flags;
res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
&routing, &addr, &mask, &set);
if (res != 4)
return -EINVAL;
if (routing > B43_MAX_SHM_ROUTING)
return -EADDRNOTAVAIL;
if (addr > B43_MAX_SHM_ADDR)
return -EADDRNOTAVAIL;
if (routing == B43_SHM_SHARED) {
if ((addr % 2) != 0)
return -EADDRNOTAVAIL;
}
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
return -E2BIG;
spin_lock_irqsave(&dev->wl->shm_lock, flags);
if (mask == 0)
val = 0;
else
val = __b43_shm_read32(dev, routing, addr);
val &= mask;
val |= set;
__b43_shm_write32(dev, routing, addr, val);
spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
return 0;
}
/* The biggest MMIO address that we allow access to from the debugfs files. */
#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
static ssize_t mmio16read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
unsigned int addr;
u16 val;
addr = dev->dfsentry->mmio16read_next;
if (addr > B43_MAX_MMIO_ACCESS)
return -EDESTADDRREQ;
val = b43_read16(dev, addr);
fappend("0x%04X\n", val);
return count;
}
static int mmio16read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr;
int res;
res = sscanf(buf, "0x%X", &addr);
if (res != 1)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((addr % 2) != 0)
return -EINVAL;
dev->dfsentry->mmio16read_next = addr;
return 0;
}
static int mmio16write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr, mask, set;
int res;
u16 val;
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
if (res != 3)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((mask > 0xFFFF) || (set > 0xFFFF))
return -E2BIG;
if ((addr % 2) != 0)
return -EINVAL;
if (mask == 0)
val = 0;
else
val = b43_read16(dev, addr);
val &= mask;
val |= set;
b43_write16(dev, addr, val);
return 0;
}
static ssize_t mmio32read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
unsigned int addr;
u32 val;
addr = dev->dfsentry->mmio32read_next;
if (addr > B43_MAX_MMIO_ACCESS)
return -EDESTADDRREQ;
val = b43_read32(dev, addr);
fappend("0x%08X\n", val);
return count;
}
static int mmio32read__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr;
int res;
res = sscanf(buf, "0x%X", &addr);
if (res != 1)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((addr % 4) != 0)
return -EINVAL;
dev->dfsentry->mmio32read_next = addr;
return 0;
}
static int mmio32write__write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
unsigned int addr, mask, set;
int res;
u32 val;
res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
if (res != 3)
return -EINVAL;
if (addr > B43_MAX_MMIO_ACCESS)
return -EADDRNOTAVAIL;
if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
return -E2BIG;
if ((addr % 4) != 0)
return -EINVAL;
if (mask == 0)
val = 0;
else
val = b43_read32(dev, addr);
val &= mask;
val |= set;
b43_write32(dev, addr, val);
return 0;
}
/* wl->irq_lock is locked */
static ssize_t shm_read_file(struct b43_wldev *dev,
static ssize_t tsf_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
int i;
u16 tmp;
__le16 *le16buf = (__le16 *)buf;
u64 tsf;
for (i = 0; i < 0x1000; i++) {
if (bufsize < sizeof(tmp))
break;
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
le16buf[i] = cpu_to_le16(tmp);
count += sizeof(tmp);
bufsize -= sizeof(tmp);
}
b43_tsf_read(dev, &tsf);
fappend("0x%08x%08x\n",
(unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
(unsigned int)(tsf & 0xFFFFFFFFULL));
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,
char *buf, size_t bufsize)
{
......@@ -496,9 +753,15 @@ static ssize_t b43_debugfs_write(struct file *file,
.take_irqlock = _take_irqlock, \
}
B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
......@@ -538,6 +801,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0);
add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0);
add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
#undef add_dyn_dbg
}
......@@ -584,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
return;
}
e->mmio16read_next = 0xFFFF; /* invalid address */
e->mmio32read_next = 0xFFFF; /* invalid address */
e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
#define ADD_FILE(name, mode) \
do { \
struct dentry *d; \
......@@ -596,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
} while (0)
ADD_FILE(shm16read, 0600);
ADD_FILE(shm16write, 0200);
ADD_FILE(shm32read, 0600);
ADD_FILE(shm32write, 0200);
ADD_FILE(mmio16read, 0600);
ADD_FILE(mmio16write, 0200);
ADD_FILE(mmio32read, 0600);
ADD_FILE(mmio32write, 0200);
ADD_FILE(tsf, 0600);
ADD_FILE(ucode_regs, 0400);
ADD_FILE(shm, 0400);
ADD_FILE(txstat, 0400);
ADD_FILE(txpower_g, 0600);
ADD_FILE(restart, 0200);
......@@ -620,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
return;
b43_remove_dynamic_debug(dev);
debugfs_remove(e->file_shm16read.dentry);
debugfs_remove(e->file_shm16write.dentry);
debugfs_remove(e->file_shm32read.dentry);
debugfs_remove(e->file_shm32write.dentry);
debugfs_remove(e->file_mmio16read.dentry);
debugfs_remove(e->file_mmio16write.dentry);
debugfs_remove(e->file_mmio32read.dentry);
debugfs_remove(e->file_mmio32write.dentry);
debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_ucode_regs.dentry);
debugfs_remove(e->file_shm.dentry);
debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_txpower_g.dentry);
debugfs_remove(e->file_restart.dentry);
......
......@@ -11,6 +11,7 @@ enum b43_dyndbg { /* Dynamic debugging features */
B43_DBG_PWORK_FAST,
B43_DBG_PWORK_STOP,
B43_DBG_LO,
B43_DBG_FIRMWARE,
__B43_NR_DYNDBG,
};
......@@ -36,9 +37,15 @@ struct b43_dfsentry {
struct b43_wldev *dev;
struct dentry *subdir;
struct b43_dfs_file file_shm16read;
struct b43_dfs_file file_shm16write;
struct b43_dfs_file file_shm32read;
struct b43_dfs_file file_shm32write;
struct b43_dfs_file file_mmio16read;
struct b43_dfs_file file_mmio16write;
struct b43_dfs_file file_mmio32read;
struct b43_dfs_file file_mmio32write;
struct b43_dfs_file file_tsf;
struct b43_dfs_file file_ucode_regs;
struct b43_dfs_file file_shm;
struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart;
......@@ -46,6 +53,18 @@ struct b43_dfsentry {
struct b43_txstatus_log txstatlog;
/* The cached address for the next mmio16read file read */
u16 mmio16read_next;
/* The cached address for the next mmio32read file read */
u16 mmio32read_next;
/* The cached address for the next shm16read file read */
u32 shm16read_routing_next;
u32 shm16read_addr_next;
/* The cached address for the next shm32read file read */
u32 shm32read_routing_next;
u32 shm32read_addr_next;
/* Enabled/Disabled list for the dynamic debugging features. */
u32 dyn_debug[__B43_NR_DYNDBG];
/* Dentries for the dynamic debugging entries. */
......
......@@ -328,11 +328,11 @@ static inline
dma_addr_t dmaaddr;
if (tx) {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
buf, len, DMA_TO_DEVICE);
dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_TO_DEVICE);
} else {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
buf, len, DMA_FROM_DEVICE);
dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_FROM_DEVICE);
}
return dmaaddr;
......@@ -343,11 +343,11 @@ static inline
dma_addr_t addr, size_t len, int tx)
{
if (tx) {
dma_unmap_single(ring->dev->dev->dma_dev,
addr, len, DMA_TO_DEVICE);
ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_TO_DEVICE);
} else {
dma_unmap_single(ring->dev->dev->dma_dev,
addr, len, DMA_FROM_DEVICE);
ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_FROM_DEVICE);
}
}
......@@ -356,8 +356,8 @@ static inline
dma_addr_t addr, size_t len)
{
B43_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
addr, len, DMA_FROM_DEVICE);
ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE);
}
static inline
......@@ -365,8 +365,8 @@ static inline
dma_addr_t addr, size_t len)
{
B43_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev,
addr, len, DMA_FROM_DEVICE);
ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE);
}
static inline
......@@ -381,7 +381,6 @@ static inline
static int alloc_ringmemory(struct b43_dmaring *ring)
{
struct device *dma_dev = ring->dev->dev->dma_dev;
gfp_t flags = GFP_KERNEL;
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
......@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
* For unknown reasons - possibly a hardware error - the BCM4311 rev
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
* which accounts for the GFP_DMA flag below.
*
* The flags here must match the flags in free_ringmemory below!
*/
if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA;
ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
&(ring->dmabase), flags);
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
B43_DMA_RINGMEMSIZE,
&(ring->dmabase), flags);
if (!ring->descbase) {
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
return -ENOMEM;
......@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring)
{
struct device *dma_dev = ring->dev->dev->dma_dev;
gfp_t flags = GFP_KERNEL;
if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA;
dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase, flags);
}
/* Reset the RX DMA channel */
......@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
dma_addr_t addr,
size_t buffersize, bool dma_to_device)
{
if (unlikely(dma_mapping_error(addr)))
if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1;
switch (ring->type) {
......@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev,
ring->txhdr_cache,
b43_txhdr_size(dev),
DMA_TO_DEVICE);
dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache,
b43_txhdr_size(dev),
DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) {
......@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (!ring->txhdr_cache)
goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev,
ring->txhdr_cache,
b43_txhdr_size(dev),
DMA_TO_DEVICE);
dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache,
b43_txhdr_size(dev),
DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) {
......@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
}
}
dma_unmap_single(dev->dev->dma_dev,
dma_test, b43_txhdr_size(dev),
DMA_TO_DEVICE);
ssb_dma_unmap_single(dev->dev,
dma_test, b43_txhdr_size(dev),
DMA_TO_DEVICE);
}
err = alloc_ringmemory(ring);
......
......@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
}
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
u32 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
......@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset);
ret = b43_read32(dev, B43_MMIO_SHM_DATA);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
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;
unsigned long flags;
u16 ret;
u32 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
ret = __b43_shm_read32(dev, routing, offset);
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret;
}
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
{
u16 ret;
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
......@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset);
ret = b43_read16(dev, B43_MMIO_SHM_DATA);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
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;
unsigned long flags;
u16 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
ret = __b43_shm_read16(dev, routing, offset);
spin_unlock_irqrestore(&wl->shm_lock, flags);
return ret;
}
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
......@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
(value >> 16) & 0xffff);
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
goto out;
return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
b43_write32(dev, B43_MMIO_SHM_DATA, value);
out:
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;
unsigned long flags;
spin_lock_irqsave(&wl->shm_lock, flags);
__b43_shm_write32(dev, routing, offset, value);
spin_unlock_irqrestore(&wl->shm_lock, flags);
}
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
/* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2);
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
goto out;
return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
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);
}
......@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
/* http://bcm-specs.sipsolutions.net/EnableMac */
void b43_mac_enable(struct b43_wldev *dev)
{
if (b43_debug(dev, B43_DBG_FIRMWARE)) {
u16 fwstate;
fwstate = b43_shm_read16(dev, B43_SHM_SHARED,
B43_SHM_SH_UCODESTAT);
if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) &&
(fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) {
b43err(dev->wl, "b43_mac_enable(): The firmware "
"should be suspended, but current state is %u\n",
fwstate);
}
}
dev->mac_suspended--;
B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) {
......@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev)
static void b43_periodic_every15sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u16 wdr;
if (dev->fw.opensource) {
/* Check if the firmware is still alive.
* It will reset the watchdog counter to 0 in its idle loop. */
wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
if (unlikely(wdr)) {
b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
b43_controller_restart(dev, "Firmware watchdog");
return;
} else {
b43_shm_write16(dev, B43_SHM_SCRATCH,
B43_WATCHDOG_REG, 1);
}
}
if (phy->type == B43_PHYTYPE_G) {
//TODO: update_aci_moving_average
......
......@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
u64 b43_hf_read(struct b43_wldev *dev);
void b43_hf_write(struct b43_wldev *dev, u64 value);
......
......@@ -586,7 +586,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
spin_lock(&q->lock); /* IRQs are already disabled. */
info = (void *)pack->skb;
info = IEEE80211_SKB_CB(pack->skb);
memset(&info->status, 0, sizeof(info->status));
b43_fill_txstatus_report(info, status);
......
......@@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock;
err = 0;
switch (state) {
case RFKILL_STATE_ON:
case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill
* button from software. */
......@@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on)
b43_radio_turn_on(dev);
break;
case RFKILL_STATE_OFF:
case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on)
b43_radio_turn_off(dev, 0);
break;
default:
b43warn(wl, "Received unexpected rfkill state %d.\n", state);
break;
}
out_unlock:
mutex_unlock(&wl->mutex);
......
......@@ -193,7 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
const struct ieee80211_hdr *wlhdr =
(const struct ieee80211_hdr *)fragment_data;
int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
u16 fctl = le16_to_cpu(wlhdr->frame_control);
__le16 fctl = wlhdr->frame_control;
struct ieee80211_rate *fbrate;
u8 rate, rate_fb;
int rate_ofdm, rate_fb_ofdm;
......@@ -259,7 +259,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
B43_TXH_MAC_KEYIDX;
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG;
wlhdr_len = ieee80211_get_hdrlen(fctl);
wlhdr_len = ieee80211_hdrlen(fctl);
iv_len = min((size_t) info->control.iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
......@@ -317,8 +317,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
/* MAC control */
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK;
if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
if (!ieee80211_is_pspoll(fctl))
mac_ctl |= B43_TXH_MAC_HWSEQ;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43_TXH_MAC_STMSDU;
......@@ -509,7 +508,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
struct b43_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr;
const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
u16 fctl;
__le16 fctl;
u16 phystat0, phystat3, chanstat, mactime;
u32 macstat;
u16 chanid;
......@@ -549,7 +548,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop;
}
wlhdr = (struct ieee80211_hdr *)(skb->data);
fctl = le16_to_cpu(wlhdr->frame_control);
fctl = wlhdr->frame_control;
if (macstat & B43_RX_MAC_DEC) {
unsigned int keyidx;
......@@ -564,7 +563,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
B43_WARN_ON(keyidx >= dev->max_nr_keys);
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
wlhdr_len = ieee80211_get_hdrlen(fctl);
wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) {
b43dbg(dev->wl,
"RX: Packet size underrun (3)\n");
......@@ -604,9 +603,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
* of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol.
*/
if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
== (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
dev->wl->radiotap_enabled) {
if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
u16 low_mactime_now;
b43_tsf_read(dev, &status.mactime);
......
......@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
dma_addr_t dmaaddr;
if (tx)
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
buf, len,
DMA_TO_DEVICE);
dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len,
DMA_TO_DEVICE);
else
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
buf, len,
DMA_FROM_DEVICE);
dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len,
DMA_FROM_DEVICE);
return dmaaddr;
}
......@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
int tx)
{
if (tx)
dma_unmap_single(ring->dev->dev->dma_dev,
addr, len,
DMA_TO_DEVICE);
ssb_dma_unmap_single(ring->dev->dev,
addr, len,
DMA_TO_DEVICE);
else
dma_unmap_single(ring->dev->dev->dma_dev,
addr, len,
DMA_FROM_DEVICE);
ssb_dma_unmap_single(ring->dev->dev,
addr, len,
DMA_FROM_DEVICE);
}
static inline
......@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
{
B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
addr, len, DMA_FROM_DEVICE);
ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE);
}
static inline
......@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
{
B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev,
addr, len, DMA_FROM_DEVICE);
ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE);
}
static inline
......@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
static int alloc_ringmemory(struct b43legacy_dmaring *ring)
{
struct device *dma_dev = ring->dev->dev->dma_dev;
ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
&(ring->dmabase), GFP_KERNEL);
/* GFP flags must match the flags in free_ringmemory()! */
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
B43legacy_DMA_RINGMEMSIZE,
&(ring->dmabase),
GFP_KERNEL);
if (!ring->descbase) {
b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
" failed\n");
......@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
static void free_ringmemory(struct b43legacy_dmaring *ring)
{
struct device *dma_dev = ring->dev->dev->dma_dev;
dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase, GFP_KERNEL);
}
/* Reset the RX DMA channel */
......@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
size_t buffersize,
bool dma_to_device)
{
if (unlikely(dma_mapping_error(addr)))
if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1;
switch (ring->type) {
......@@ -894,9 +893,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
if (b43legacy_dma_mapping_error(ring, dma_test,
sizeof(struct b43legacy_txhdr_fw3), 1)) {
......@@ -908,7 +907,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
if (!ring->txhdr_cache)
goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev,
dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
......@@ -918,9 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_txhdr_cache;
}
dma_unmap_single(dev->dev->dma_dev,
dma_test, sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
ssb_dma_unmap_single(dev->dev, dma_test,
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
}
ring->nr_slots = nr_slots;
......
......@@ -90,7 +90,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock;
err = 0;
switch (state) {
case RFKILL_STATE_ON:
case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill
* button from software. */
......@@ -100,10 +100,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on)
b43legacy_radio_turn_on(dev);
break;
case RFKILL_STATE_OFF:
case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on)
b43legacy_radio_turn_off(dev, 0);
break;
default:
b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
state);
break;
}
out_unlock:
......
......@@ -442,7 +442,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
struct b43legacy_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr;
const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr;
u16 fctl;
__le16 fctl;
u16 phystat0;
u16 phystat3;
u16 chanstat;
......@@ -480,7 +480,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
goto drop;
}
wlhdr = (struct ieee80211_hdr *)(skb->data);
fctl = le16_to_cpu(wlhdr->frame_control);
fctl = wlhdr->frame_control;
if ((macstat & B43legacy_RX_MAC_DEC) &&
!(macstat & B43legacy_RX_MAC_DECERR)) {
......@@ -499,11 +499,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
/* Remove PROTECTED flag to mark it as decrypted. */
B43legacy_WARN_ON(!(fctl & IEEE80211_FCTL_PROTECTED));
fctl &= ~IEEE80211_FCTL_PROTECTED;
wlhdr->frame_control = cpu_to_le16(fctl);
B43legacy_WARN_ON(!ieee80211_has_protected(fctl));
fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
wlhdr->frame_control = fctl;
wlhdr_len = ieee80211_get_hdrlen(fctl);
wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) {
b43legacydbg(dev->wl, "RX: Packet size"
" underrun3\n");
......@@ -556,9 +556,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
* of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol.
*/
if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
== (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
dev->wl->radiotap_enabled) {
if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
u16 low_mactime_now;
b43legacy_tsf_read(dev, &status.mactime);
......
......@@ -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[],
struct iw_quality qual[], int buf_size,
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);
......
......@@ -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
* 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;
local_info_t *local;
......@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
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);
/* Use the mode to indicate if it's a station or
* an Access Point */
......@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
else
iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN;
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);
/* Some quality */
memset(&iwe, 0, sizeof(iwe));
......@@ -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.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN;
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);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) {
......@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe,
current_ev = iwe_stream_add_point(info, current_ev,
end_buf, &iwe,
sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe));
......@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe,
sta->u.ap.ssid
/* 0 byte memcpy */);
current_ev = iwe_stream_add_point(info, current_ev,
end_buf, &iwe,
sta->u.ap.ssid);
if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) {
......@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
* 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(
current_ev, end_buf, &iwe,
info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
......@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
sprintf(buf, "beacon_interval=%d",
sta->listen_interval);
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);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
......
......@@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
#ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local,
struct iw_request_info *info,
struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss,
char *current_ev, char *end_buf)
......@@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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);
/* Other entries will be displayed in the order we give them */
......@@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
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));
iwe.cmd = SIOCGIWMODE;
......@@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
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);
}
memset(&iwe, 0, sizeof(iwe));
......@@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000;
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);
}
if (scan) {
......@@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local,
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
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);
}
memset(&iwe, 0, sizeof(iwe));
......@@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
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 */
if (scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE;
current_val = current_ev + IW_EV_LCP_LEN;
current_val = current_ev + iwe_stream_lcp_len(info);
pos = scan->sup_rates;
for (i = 0; i < sizeof(scan->sup_rates); i++) {
if (pos[i] == 0)
......@@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
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);
}
/* 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;
}
......@@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
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);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
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);
if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) {
......@@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
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);
......@@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
current_ev = iwe_stream_add_point(
current_ev, end_buf, &iwe, bss->wpa_ie);
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
current_ev = iwe_stream_add_point(
current_ev, end_buf, &iwe, bss->rsn_ie);
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->rsn_ie);
}
return current_ev;
......@@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local,
struct iw_request_info *info,
char *buffer, int buflen)
{
struct hfa384x_hostscan_result *scan;
......@@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local,
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1;
current_ev = __prism2_translate_scan(
local, scan, bss, current_ev, end_buf);
local, info, scan, bss, current_ev,
end_buf);
found++;
}
}
if (!found) {
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 */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
......@@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local,
bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included)
continue;
current_ev = __prism2_translate_scan(local, NULL, bss,
current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf);
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
......@@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
}
local->scan_timestamp = 0;
res = prism2_translate_scan(local, extra, data->length);
res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) {
data->length = res;
......@@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
* Jean II */
/* Translate to WE format */
res = prism2_ap_translate_scan(dev, extra);
res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res);
......
......@@ -8,7 +8,7 @@ config IWLCORE
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL
select RFKILL_INPUT if IWLWIFI_RFKILL
select RFKILL_INPUT if (IWLWIFI_RFKILL && INPUT)
config IWLWIFI_LEDS
bool
......
......@@ -54,17 +54,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
mutex_lock(&priv->mutex);
switch (state) {
case RFKILL_STATE_ON:
case RFKILL_STATE_UNBLOCKED:
iwl_radio_kill_sw_enable_radio(priv);
/* if HW rf-kill is set dont allow ON state */
if (iwl_is_rfkill(priv))
err = -EBUSY;
break;
case RFKILL_STATE_OFF:
case RFKILL_STATE_SOFT_BLOCKED:
iwl_radio_kill_sw_disable_radio(priv);
if (!iwl_is_rfkill(priv))
err = -EBUSY;
break;
default:
IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
}
mutex_unlock(&priv->mutex);
......@@ -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->resume = NULL;
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
priv->rfkill_mngr.input_dev = input_allocate_device();
if (!priv->rfkill_mngr.input_dev) {
IWL_ERROR("Unable to allocate rfkill input device.\n");
......@@ -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->evbit[0] = BIT(EV_KEY);
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
#endif
ret = rfkill_register(priv->rfkill_mngr.rfkill);
if (ret) {
......@@ -116,11 +121,13 @@ int iwl_rfkill_init(struct iwl_priv *priv)
goto free_input_dev;
}
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
ret = input_register_device(priv->rfkill_mngr.input_dev);
if (ret) {
IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
goto unregister_rfkill;
}
#endif
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
......@@ -130,8 +137,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
priv->rfkill_mngr.rfkill = NULL;
free_input_dev:
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
input_free_device(priv->rfkill_mngr.input_dev);
priv->rfkill_mngr.input_dev = NULL;
#endif
freed_rfkill:
if (priv->rfkill_mngr.rfkill != NULL)
......@@ -147,13 +156,16 @@ EXPORT_SYMBOL(iwl_rfkill_init);
void iwl_rfkill_unregister(struct iwl_priv *priv)
{
#if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE)
if (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)
rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.input_dev = NULL;
priv->rfkill_mngr.rfkill = NULL;
}
EXPORT_SYMBOL(iwl_rfkill_unregister);
......
......@@ -776,8 +776,9 @@ int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
#define MAX_CUSTOM_LEN 64
static inline char *lbs_translate_scan(struct lbs_private *priv,
char *start, char *stop,
struct bss_descriptor *bss)
struct iw_request_info *info,
char *start, char *stop,
struct bss_descriptor *bss)
{
struct chan_freq_power *cfp;
char *current_val; /* For rates */
......@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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 */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
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 */
iwe.cmd = SIOCGIWMODE;
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 */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
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 */
iwe.cmd = IWEVQUAL;
......@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
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 */
iwe.cmd = SIOCGIWENCODE;
......@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
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.u.bitrate.fixed = 0;
......@@ -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++) {
/* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000;
current_val = iwe_stream_add_value(start, current_val,
stop, &iwe, IW_EV_PARAM_LEN);
current_val = iwe_stream_add_value(info, start, current_val,
stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
&& !lbs_ssid_cmp(priv->curbssparams.ssid,
priv->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)) {
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);
}
/* 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;
memset(&iwe, 0, sizeof(iwe));
......@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
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));
......@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
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) {
......@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
iwe.u.data.length = p - custom;
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:
......@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
}
/* 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)
continue;
ev = next_ev;
......
......@@ -430,15 +430,16 @@ static int __init init_mac80211_hwsim(void)
hwsim_radios[i] = hw;
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)) {
printk(KERN_DEBUG "mac80211_hwsim: device_create "
printk(KERN_DEBUG
"mac80211_hwsim: device_create_drvdata "
"failed (%ld)\n", PTR_ERR(data->dev));
err = -ENOMEM;
goto failed;
}
data->dev->driver = &mac80211_hwsim_driver;
dev_set_drvdata(data->dev, hw);
SET_IEEE80211_DEV(hw, data->dev);
addr[3] = i >> 8;
......
......@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */
static inline char *orinoco_translate_scan(struct net_device *dev,
struct iw_request_info *info,
char *current_ev,
char *end_buf,
union hermes_scan_info *bss,
......@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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 */
......@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
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 */
iwe.cmd = SIOCGIWMODE;
......@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
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;
......@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
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);
}
......@@ -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;
else
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 */
iwe.cmd = SIOCGIWENCODE;
......@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
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
* for given network. */
......@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
jiffies_to_msecs(jiffies - last_scanned));
iwe.u.data.length = p - custom;
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 */
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 step;
......@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
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,
IW_EV_PARAM_LEN);
}
/* 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;
}
......@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
list_for_each_entry(bss, &priv->bss_list, list) {
/* 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,
&bss->bss,
bss->last_scanned);
......
......@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/
static char *
prism54_translate_bss(struct net_device *ndev, char *current_ev,
char *end_buf, struct obj_bss *bss, char noise)
prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
char *current_ev, char *end_buf, struct obj_bss *bss,
char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
......@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
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);
/* 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,
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
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);
/* Capabilities */
......@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
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);
/* Encryption capability */
if (cap & CAP_CRYPT)
......@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
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 */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
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);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
......@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
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 WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, wpa_ie);
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, wpa_ie);
}
/* 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 mask;
......@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
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);
}
mask <<= 1;
}
/* 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;
}
......@@ -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 */
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,
&(bsslist->bsslist[i]),
noise);
......@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
struct prism2_hostapd_param *param)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_request_info info;
int i, rvalue;
struct obj_bsslist *bsslist;
u32 noise = 0;
......@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
info.cmd = PRISM54_HOSTAPD;
info.flags = 0;
/* ok now, scan the list and translate its info */
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,
&(bsslist->bsslist[i]),
noise);
......
......@@ -1648,7 +1648,9 @@ static int rndis_iw_set_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
struct usbnet *usbdev = dev->priv;
......@@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
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),
bssid->ssid.essid);
iwe.cmd = SIOCGIWESSID;
iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
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));
iwe.cmd = SIOCGIWMODE;
......@@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_AUTO;
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));
iwe.cmd = SIOCGIWFREQ;
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));
iwe.cmd = IWEVQUAL;
......@@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| 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));
iwe.cmd = SIOCGIWENCODE;
......@@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev,
else
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:");
current_val = cev + IW_EV_LCP_LEN;
current_val = cev + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE;
for (i = 0; i < sizeof(bssid->rates); i++) {
if (bssid->rates[i] & 0x7f) {
......@@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev,
((bssid->rates[i] & 0x7f) *
500000);
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,
IW_EV_PARAM_LEN);
}
}
if ((current_val - cev) > IW_EV_LCP_LEN)
if ((current_val - cev) > iwe_stream_lcp_len(info))
cev = current_val;
beacon = le32_to_cpu(bssid->config.beacon_period);
......@@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
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);
devdbg(usbdev, "ATIM %d", atim);
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
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_len = min(bssid_len - (int)sizeof(*bssid),
......@@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev,
(ie->id == MFIE_TYPE_RSN) ? 2 : 1);
iwe.cmd = IWEVGENIE;
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);
}
......@@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
bssid);
cev = rndis_translate_scan(dev, info, cev,
extra + IW_SCAN_MAX_DATA, bssid);
bssid = (void *)bssid + bssid_len;
bssid_len = le32_to_cpu(bssid->length);
count--;
......
......@@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word;
rt2x00_desc_read(entry_priv->desc, 2, &word);
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH,
entry->queue->data_size);
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
rt2x00_desc_write(entry_priv->desc, 2, 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_read(entry_priv->desc, 0, &word);
......@@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words.
*/
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_read(txd, 2, &word);
......@@ -1154,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
}
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)
IEEE80211_HW_SIGNAL_DBM;
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,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
......@@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *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_DMA, &rt2x00dev->flags);
/*
* Set the rssi offset.
......@@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
* Write entire beacon with descriptor to register,
* 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);
rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
......
......@@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 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_read(entry_priv->desc, 0, &word);
......@@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words.
*/
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_read(txd, 2, &word);
......@@ -1311,7 +1312,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
}
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)
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,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
......@@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *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_DMA, &rt2x00dev->flags);
/*
* Set the rssi offset.
......@@ -1842,7 +1844,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
* Write entire beacon with descriptor to register,
* 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);
rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
......
......@@ -1594,7 +1594,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
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,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
......@@ -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)
{
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 rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
struct queue_entry_priv_usb_bcn *bcn_priv;
......
......@@ -44,7 +44,7 @@
/*
* Module information.
*/
#define DRV_VERSION "2.1.7"
#define DRV_VERSION "2.1.8"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
......@@ -110,33 +110,6 @@
#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
#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
* The chipset on the device is composed of a RT and RF chip.
......@@ -628,6 +601,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_BEACON_GUARD,
DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
/*
* Driver configuration
......@@ -652,11 +626,7 @@ struct rt2x00_dev {
* When accessing this variable, the rt2x00dev_{pci,usb}
* macro's should be used for correct typecasting.
*/
void *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)) )
struct device *dev;
/*
* Callback functions.
......@@ -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.
* @queue: The queue for which the skb will be applicable.
* rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
* @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
......@@ -985,26 +956,14 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
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.
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
void rt2x00lib_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc);
void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry);
/*
* mac80211 handlers.
......
......@@ -469,12 +469,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
struct rt2x00_dev *rt2x00dev = data;
struct rt2x00_intf *intf = vif_to_intf(vif);
if (vif->type != IEEE80211_IF_TYPE_AP &&
vif->type != IEEE80211_IF_TYPE_IBSS)
return;
/*
* Clean up the beacon skb.
*/
rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
intf->beacon->skb = NULL;
spin_lock(&intf->lock);
intf->delayed_flags |= DELAYED_UPDATE_BEACON;
spin_unlock(&intf->lock);
......@@ -498,6 +505,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
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
......@@ -546,39 +559,77 @@ void rt2x00lib_txdone(struct queue_entry *entry,
ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
else
dev_kfree_skb_irq(entry->skb);
/*
* Make this entry available for reuse.
*/
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);
void rt2x00lib_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
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;
unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate;
unsigned int header_size;
unsigned int align;
unsigned int i;
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
* aligned on a 4 byte boundary.
*/
header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
align = ((unsigned long)(entry->skb->data + header_size)) & 3;
if (align) {
skb_push(entry->skb, align);
/* Move entire frame in 1 command */
memmove(entry->skb->data, entry->skb->data + align,
rxdesc->size);
rxdesc.size);
}
/* Update data pointers, trim buffer to correct size */
skb_trim(entry->skb, rxdesc->size);
skb_trim(entry->skb, rxdesc.size);
/*
* Update RX statistics.
......@@ -587,10 +638,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
for (i = 0; i < sband->n_bitrates; i++) {
rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->plcp == rxdesc->signal)) ||
(!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->bitrate == rxdesc->signal))) {
if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->plcp == rxdesc.signal)) ||
(!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
(rate->bitrate == rxdesc.signal))) {
idx = i;
break;
}
......@@ -598,8 +649,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
if (idx < 0) {
WARNING(rt2x00dev, "Frame received with unrecognized signal,"
"signal=0x%.2x, plcp=%d.\n", rxdesc->signal,
!!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP));
"signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
!!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
idx = 0;
}
......@@ -607,17 +658,17 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
* Only update link status if this is a beacon frame carrying our bssid.
*/
hdr = (struct ieee80211_hdr *)entry->skb->data;
fc = le16_to_cpu(hdr->frame_control);
if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS))
rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi);
if (ieee80211_is_beacon(hdr->frame_control) &&
(rxdesc.dev_flags & RXDONE_MY_BSS))
rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
rt2x00dev->link.qual.rx_success++;
rx_status->rate_idx = idx;
rx_status->qual =
rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
rx_status->signal = rxdesc->rssi;
rx_status->flag = rxdesc->flags;
rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc.rssi;
rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
/*
......@@ -626,7 +677,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
*/
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
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);
......
......@@ -98,10 +98,57 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
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);
/**
* 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_tx(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
......
......@@ -60,12 +60,8 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry)
* Fill in skb descriptor
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
memcpy(entry_priv->data, entry->skb->data, entry->skb->len);
return 0;
}
......@@ -80,7 +76,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
struct queue_entry *entry;
struct queue_entry_priv_pci *entry_priv;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
u32 word;
while (1) {
......@@ -91,110 +86,27 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
break;
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/*
* Allocate the sk_buffer and copy all data into it.
*/
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
* Fill in desc fields of the skb descriptor
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = queue->desc_size;
skbdesc->entry = entry;
skbdesc->desc_len = entry->queue->desc_size;
/*
* Send the frame to rt2x00lib for further processing.
*/
rt2x00lib_rxdone(entry, &rxdesc);
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);
rt2x00lib_rxdone(rt2x00dev, entry);
}
}
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.
*/
#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,
struct data_queue *queue)
{
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
struct queue_entry_priv_pci *entry_priv;
void *addr;
dma_addr_t dma;
......@@ -203,21 +115,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
/*
* 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)
return -ENOMEM;
memset(addr, 0, dma_size(queue));
memset(addr, 0, queue->limit * queue->desc_size);
/*
* Initialize all queue entries to contain valid addresses.
*/
for (i = 0; i < queue->limit; i++) {
entry_priv = queue->entries[i].priv_data;
entry_priv->desc = desc_offset(queue, addr, i);
entry_priv->desc_dma = desc_offset(queue, dma, i);
entry_priv->data = data_offset(queue, addr, i);
entry_priv->data_dma = data_offset(queue, dma, i);
entry_priv->desc = addr + i * queue->desc_size;
entry_priv->desc_dma = dma + i * queue->desc_size;
}
return 0;
......@@ -226,19 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
struct queue_entry_priv_pci *entry_priv =
queue->entries[0].priv_data;
if (entry_priv->data)
pci_free_consistent(pci_dev, dma_size(queue),
entry_priv->data, entry_priv->data_dma);
entry_priv->data = NULL;
if (entry_priv->desc)
dma_free_coherent(rt2x00dev->dev,
queue->limit * queue->desc_size,
entry_priv->desc, entry_priv->desc_dma);
entry_priv->desc = NULL;
}
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;
int status;
......@@ -279,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
/*
* Free irq line.
*/
free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev);
free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev);
/*
* Free DMA
......@@ -308,7 +220,7 @@ static void rt2x00pci_free_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),
pci_resource_len(pci_dev, 0));
......@@ -357,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (pci_set_mwi(pci_dev))
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");
retval = -EIO;
goto exit_disable_device;
......@@ -373,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
pci_set_drvdata(pci_dev, hw);
rt2x00dev = hw->priv;
rt2x00dev->dev = pci_dev;
rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
......
......@@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry);
struct queue_entry_priv_pci {
__le32 *desc;
dma_addr_t desc_dma;
void *data;
dma_addr_t data_dma;
};
/**
......@@ -118,15 +115,6 @@ struct queue_entry_priv_pci {
*/
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.
*/
......
......@@ -25,34 +25,30 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include "rt2x00.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 reserved_size;
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
/*
* The frame size includes descriptor size, because the
* 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:
* 1) 4byte alignment of 802.11 payload
*
* 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.
* Reserve a few bytes extra headroom to allow drivers some moving
* space (e.g. for alignment), while keeping the skb aligned.
*/
reserved_size = 6;
reserved_size = 8;
/*
* Allocate skbuffer.
......@@ -64,9 +60,56 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue)
skb_reserve(skb, reserved_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;
}
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,
struct txentry_desc *txdesc)
......@@ -80,7 +123,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
unsigned int data_length;
unsigned int duration;
unsigned int residual;
u16 frame_control;
memset(txdesc, 0, sizeof(*txdesc));
......@@ -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 = 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.
*/
......@@ -109,9 +146,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/*
* 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);
if (is_rts_frame(frame_control))
if (ieee80211_is_rts(hdr->frame_control))
__set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
else
__set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
......@@ -139,7 +177,8 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Beacons and probe responses require the tsf timestamp
* 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);
/*
......@@ -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 txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
if (unlikely(rt2x00queue_full(queue)))
return -EINVAL;
......@@ -256,11 +296,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb;
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))) {
__clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
return -EIO;
}
if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
rt2x00queue_map_txskb(queue->rt2x00dev, skb);
__set_bit(ENTRY_DATA_PENDING, &entry->flags);
rt2x00queue_index_inc(queue, Q_INDEX);
......@@ -336,7 +386,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
spin_unlock_irqrestore(&queue->lock, irqflags);
}
EXPORT_SYMBOL_GPL(rt2x00queue_index_inc);
static void rt2x00queue_reset(struct data_queue *queue)
{
......@@ -426,12 +475,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
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)
{
struct data_queue *queue;
int status;
status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx);
if (status)
goto exit;
......@@ -446,11 +524,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
if (status)
goto exit;
if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
return 0;
if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) {
status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1],
rt2x00dev->ops->atim);
if (status)
goto exit;
}
status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1],
rt2x00dev->ops->atim);
status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
if (status)
goto exit;
......@@ -468,6 +549,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
queue_for_each(rt2x00dev, queue) {
kfree(queue->entries);
queue->entries = NULL;
......
......@@ -42,15 +42,18 @@
/**
* DOC: Number of entries per queue
*
* After research it was concluded that 12 entries in a RX and TX
* queue would be sufficient. Although this is almost one third of
* the amount the legacy driver allocated, the queues aren't getting
* filled to the maximum even when working with the maximum rate.
* Under normal load without fragmentation 12 entries are sufficient
* without the queue being filled up to the maximum. When using fragmentation
* and the queue threshold code we need to add some additional margins to
* 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 TX_ENTRIES 12
#define RX_ENTRIES 24
#define TX_ENTRIES 24
#define BEACON_ENTRIES 1
#define ATIM_ENTRIES 1
#define ATIM_ENTRIES 8
/**
* enum data_queue_qid: Queue identification
......@@ -82,10 +85,13 @@ enum data_queue_qid {
/**
* 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 {
// TEMPORARILY EMPTY
//};
enum skb_frame_desc_flags {
SKBDESC_DMA_MAPPED_RX = (1 << 0),
SKBDESC_DMA_MAPPED_TX = (1 << 1),
};
/**
* struct skb_frame_desc: Descriptor information for the skb buffer
......@@ -94,19 +100,20 @@ enum data_queue_qid {
* this structure should not exceed the size of that array (40 bytes).
*
* @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.
* Note that this pointer could point to something outside
* of the scope of the skb->data pointer.
* @data_len: Length of the frame data.
* @desc_len: Length of the frame descriptor.
* @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
* @entry: The entry to which this sk buffer belongs.
*/
struct skb_frame_desc {
unsigned int flags;
void *desc;
unsigned int desc_len;
void *desc;
dma_addr_t skb_dma;
struct queue_entry *entry;
};
......
......@@ -45,14 +45,17 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
return 0;
if (state == RFKILL_STATE_ON) {
if (state == RFKILL_STATE_UNBLOCKED) {
INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
__clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
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");
__set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
rt2x00lib_disable_radio(rt2x00dev);
} else {
WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n",
state);
}
return retval;
......
......@@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
void *buffer, const u16 buffer_length,
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;
unsigned int i;
unsigned int pipe =
......@@ -130,10 +130,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct txdone_entry_desc txdesc;
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
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;
/*
......@@ -157,26 +156,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
txdesc.retry = 0;
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)
{
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 skb_frame_desc *skbdesc;
u32 length;
......@@ -191,10 +176,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
* Fill in skb descriptor
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->desc = entry->skb->data;
skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
/*
* USB devices cannot blindly pass the skb->len as the
......@@ -264,13 +247,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u8 rxd[32];
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;
/*
......@@ -278,50 +259,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* to be actually valid, or if the urb is signaling
* a problem.
*/
if (urb->actual_length < entry->queue->desc_size || urb->status)
goto skip_entry;
if (urb->actual_length < entry->queue->desc_size || urb->status) {
__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_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.
*/
rt2x00lib_rxdone(entry, &rxdesc);
/*
* 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);
rt2x00lib_rxdone(rt2x00dev, entry);
}
/*
......@@ -331,6 +284,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
struct queue_entry_priv_usb *entry_priv;
struct queue_entry_priv_usb_bcn *bcn_priv;
struct data_queue *queue;
unsigned int i;
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
......@@ -339,9 +293,11 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Cancel all queues.
*/
for (i = 0; i < rt2x00dev->rx->limit; i++) {
entry_priv = rt2x00dev->rx->entries[i].priv_data;
usb_kill_urb(entry_priv->urb);
queue_for_each(rt2x00dev, queue) {
for (i = 0; i < queue->limit; i++) {
entry_priv = queue->entries[i].priv_data;
usb_kill_urb(entry_priv->urb);
}
}
/*
......@@ -364,7 +320,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
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;
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
......@@ -431,8 +387,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
entry_priv = queue->entries[i].priv_data;
usb_kill_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,
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
struct sk_buff *skb;
unsigned int entry_size;
unsigned int i;
int uninitialized_var(status);
int status;
/*
* Allocate DMA
......@@ -468,18 +419,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
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;
exit:
......@@ -558,7 +497,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
usb_set_intfdata(usb_intf, hw);
rt2x00dev = hw->priv;
rt2x00dev->dev = usb_intf;
rt2x00dev->dev = &usb_intf->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
mutex_init(&rt2x00dev->usb_cache_mutex);
......
......@@ -26,6 +26,12 @@
#ifndef 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
* usb_driver structure initialization.
......
......@@ -1827,7 +1827,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM;
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,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
......@@ -2007,6 +2007,12 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
REGISTER_TIMEOUT32(skb->len));
rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON);
/*
* Clean up the beacon skb.
*/
dev_kfree_skb(skb);
intf->beacon->skb = NULL;
return 0;
}
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane"
config SSB_POSSIBLE
bool
depends on HAS_IOMEM
depends on HAS_IOMEM && HAS_DMA
default y
config SSB
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -241,7 +241,10 @@ enum nl80211_attrs {
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
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册