char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ int i;
unsigned long flags;
- int i, nr_80211;
struct bcm43xx_phyinfo *phy;
char suffix[7] = { 0 };
int have_a = 0, have_b = 0, have_g = 0;
- spin_lock_irqsave(&bcm->lock, flags);
- nr_80211 = bcm43xx_num_80211_cores(bcm);
- for (i = 0; i < nr_80211; i++) {
- phy = bcm->phy + i;
+ bcm43xx_lock_irqsafe(bcm, flags);
+ for (i = 0; i < bcm->nr_80211_available; i++) {
+ phy = &(bcm->core_80211_ext[i].phy);
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
have_a = 1;
assert(0);
}
}
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
i = 0;
if (have_a) {
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct ieee80211softmac_device *softmac = bcm->softmac;
unsigned long flags;
u8 channel;
int freq;
int err = -EINVAL;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
channel = data->freq.m;
freq = bcm43xx_channel_to_freq(bcm, channel);
}
if (!bcm43xx_is_valid_channel(bcm, channel))
goto out_unlock;
- if (bcm->initialized) {
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
//ieee80211softmac_disassoc(softmac, $REASON);
bcm43xx_mac_suspend(bcm);
err = bcm43xx_radio_selectchannel(bcm, channel, 0);
bcm43xx_mac_enable(bcm);
} else {
- bcm->current_core->radio->initial_channel = channel;
+ bcm43xx_current_radio(bcm)->initial_channel = channel;
err = 0;
}
out_unlock:
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ struct bcm43xx_radioinfo *radio;
unsigned long flags;
int err = -ENODEV;
u16 channel;
- spin_lock_irqsave(&bcm->lock, flags);
- channel = bcm->current_core->radio->channel;
+ bcm43xx_lock_irqsafe(bcm, flags);
+ radio = bcm43xx_current_radio(bcm);
+ channel = radio->channel;
if (channel == 0xFF) {
- assert(!bcm->initialized);
- channel = bcm->current_core->radio->initial_channel;
+ channel = radio->initial_channel;
if (channel == 0xFF)
goto out_unlock;
}
err = 0;
out_unlock:
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
if (mode == IW_MODE_AUTO)
mode = BCM43xx_INITIAL_IWMODE;
- spin_lock_irqsave(&bcm->lock, flags);
- if (bcm->ieee->iw_mode != mode)
- bcm43xx_set_iwmode(bcm, mode);
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
+ if (bcm->ieee->iw_mode != mode)
+ bcm43xx_set_iwmode(bcm, mode);
+ } else
+ bcm->ieee->iw_mode = mode;
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
data->mode = bcm->ieee->iw_mode;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
-static int bcm43xx_wx_set_sensitivity(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
-static int bcm43xx_wx_get_sensitivity(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
const struct ieee80211_geo *geo;
unsigned long flags;
int i, j;
+ struct bcm43xx_phyinfo *phy;
data->data.length = sizeof(*range);
memset(range, 0, sizeof(*range));
range->max_qual.qual = 100;
/* TODO: Real max RSSI */
- range->max_qual.level = 0;
- range->max_qual.noise = 0;
+ range->max_qual.level = 3;
+ range->max_qual.noise = 100;
range->max_qual.updated = 7;
range->avg_qual.qual = 70;
- range->avg_qual.level = 0;
- range->avg_qual.noise = 0;
+ range->avg_qual.level = 2;
+ range->avg_qual.noise = 40;
range->avg_qual.updated = 7;
range->min_rts = BCM43xx_MIN_RTS_THRESHOLD;
IW_ENC_CAPA_CIPHER_TKIP |
IW_ENC_CAPA_CIPHER_CCMP;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
+ phy = bcm43xx_current_phy(bcm);
range->num_bitrates = 0;
i = 0;
- if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ||
- bcm->current_core->phy->type == BCM43xx_PHYTYPE_G) {
+ if (phy->type == BCM43xx_PHYTYPE_A ||
+ phy->type == BCM43xx_PHYTYPE_G) {
range->num_bitrates = 8;
range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB;
}
- if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_B ||
- bcm->current_core->phy->type == BCM43xx_PHYTYPE_G) {
+ if (phy->type == BCM43xx_PHYTYPE_B ||
+ phy->type == BCM43xx_PHYTYPE_G) {
range->num_bitrates += 4;
range->bitrate[i++] = IEEE80211_CCK_RATE_1MB;
range->bitrate[i++] = IEEE80211_CCK_RATE_2MB;
}
range->num_frequency = j;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
size_t len;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_noirq(bcm);
len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
memcpy(bcm->nick, extra, len);
bcm->nick[len] = '\0';
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_noirq(bcm);
return 0;
}
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
size_t len;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_noirq(bcm);
len = strlen(bcm->nick) + 1;
memcpy(extra, bcm->nick, len);
data->data.length = (__u16)len;
data->data.flags = 1;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_noirq(bcm);
return 0;
}
unsigned long flags;
int err = -EINVAL;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
if (data->rts.disabled) {
bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
err = 0;
err = 0;
}
}
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
data->rts.value = bcm->rts_threshold;
data->rts.fixed = 0;
data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
unsigned long flags;
int err = -EINVAL;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
if (data->frag.disabled) {
bcm->ieee->fts = MAX_FRAG_THRESHOLD;
err = 0;
err = 0;
}
}
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
data->frag.value = bcm->ieee->fts;
data->frag.fixed = 0;
data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
return -EOPNOTSUPP;
}
- spin_lock_irqsave(&bcm->lock, flags);
- if (!bcm->initialized)
+ bcm43xx_lock_irqsafe(bcm, flags);
+ if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
goto out_unlock;
- radio = bcm->current_core->radio;
- phy = bcm->current_core->phy;
+ radio = bcm43xx_current_radio(bcm);
+ phy = bcm43xx_current_phy(bcm);
if (data->txpower.disabled != (!(radio->enabled))) {
if (data->txpower.disabled)
bcm43xx_radio_turn_off(bcm);
err = 0;
out_unlock:
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
unsigned long flags;
int err = -ENODEV;
- spin_lock_irqsave(&bcm->lock, flags);
- if (!bcm->initialized)
+ bcm43xx_lock_irqsafe(bcm, flags);
+ if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
goto out_unlock;
- radio = bcm->current_core->radio;
+ radio = bcm43xx_current_radio(bcm);
/* desired dBm value is in Q5.2 */
data->txpower.value = radio->txpower_desired >> 2;
data->txpower.fixed = 1;
err = 0;
out_unlock:
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
-static int bcm43xx_wx_set_retry(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
-static int bcm43xx_wx_get_retry(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
static int bcm43xx_wx_set_encoding(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
return err;
}
-static int bcm43xx_wx_set_power(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
-static int bcm43xx_wx_get_power(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- /*TODO*/
- return 0;
-}
-
static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
return -EINVAL;
}
- spin_lock_irqsave(&bcm->lock, flags);
- if (bcm->initialized) {
+ bcm43xx_lock_irqsafe(bcm, flags);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
if (err) {
printk(KERN_ERR PFX "Interference Mitigation not "
"not supported while the interface is down.\n");
err = -ENODEV;
} else
- bcm->current_core->radio->interfmode = mode;
+ bcm43xx_current_radio(bcm)->interfmode = mode;
}
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return err;
}
unsigned long flags;
int mode;
- spin_lock_irqsave(&bcm->lock, flags);
- mode = bcm->current_core->radio->interfmode;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
+ mode = bcm43xx_current_radio(bcm)->interfmode;
+ bcm43xx_unlock_irqsafe(bcm, flags);
switch (mode) {
case BCM43xx_RADIO_INTERFMODE_NONE:
int on;
on = *((int *)extra);
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
bcm->short_preamble = !!on;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
return 0;
}
unsigned long flags;
int on;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
on = bcm->short_preamble;
- spin_unlock_irqrestore(&bcm->lock, flags);
+ bcm43xx_unlock_irqsafe(bcm, flags);
if (on)
strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
int on;
on = *((int *)extra);
- spin_lock_irqsave(&bcm->lock, flags);
+
+ bcm43xx_lock_irqsafe(bcm, flags);
bcm->ieee->host_encrypt = !!on;
bcm->ieee->host_decrypt = !!on;
bcm->ieee->host_build_iv = !on;
-
- spin_unlock_irqrestore(&bcm->lock, flags);
-
+ bcm43xx_unlock_irqsafe(bcm, flags);
+
return 0;
}
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
int on;
-
- spin_lock_irqsave(&bcm->lock, flags);
+
+ bcm43xx_lock_irqsafe(bcm, flags);
on = bcm->ieee->host_encrypt;
- spin_unlock_irqrestore(&bcm->lock, flags);
-
+ bcm43xx_unlock_irqsafe(bcm, flags);
+
if (on)
strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
else
strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING);
data->data.length = strlen(extra + 1);
-
+
return 0;
}
if (!sprom)
goto out;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
err = -ENODEV;
- if (!bcm->initialized) {
- spin_unlock_irqrestore(&bcm->lock, flags);
- goto out_kfree;
- }
- err = bcm43xx_sprom_read(bcm, sprom);
- spin_unlock_irqrestore(&bcm->lock, flags);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ err = bcm43xx_sprom_read(bcm, sprom);
+ bcm43xx_unlock_irqsafe(bcm, flags);
if (!err)
data->data.length = sprom2hex(sprom, extra);
-out_kfree:
kfree(sprom);
out:
return err;
if (err)
goto out_kfree;
- spin_lock_irqsave(&bcm->lock, flags);
+ bcm43xx_lock_irqsafe(bcm, flags);
err = -ENODEV;
- if (!bcm->initialized)
- goto out_unlock;
- err = bcm43xx_sprom_write(bcm, sprom);
-out_unlock:
- spin_unlock_irqrestore(&bcm->lock, flags);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ err = bcm43xx_sprom_write(bcm, sprom);
+ bcm43xx_unlock_irqsafe(bcm, flags);
out_kfree:
kfree(sprom);
out:
return err;
}
+/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
+
+static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_dev)
+{
+ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
+ struct iw_statistics *wstats;
+
+ wstats = &bcm->stats.wstats;
+ if (!mac->associated) {
+ wstats->miss.beacon = 0;
+// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
+ wstats->discard.retries = 0;
+// bcm->ieee->ieee_stats.tx_discards_wrong_sa = 0; // FIXME: same question
+ wstats->discard.nwid = 0;
+// bcm->ieee->ieee_stats.rx_discards_undecryptable = 0; // FIXME: ditto
+ wstats->discard.code = 0;
+// bcm->ieee->ieee_stats.rx_fragments = 0; // FIXME: same here
+ wstats->discard.fragment = 0;
+ wstats->discard.misc = 0;
+ wstats->qual.qual = 0;
+ wstats->qual.level = 0;
+ wstats->qual.noise = 0;
+ wstats->qual.updated = 7;
+ wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
+ IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
+ return wstats;
+ }
+ /* fill in the real statistics when iface associated */
+ wstats->qual.qual = 100; // TODO: get the real signal quality
+ wstats->qual.level = 3 - bcm->stats.link_quality;
+ wstats->qual.noise = bcm->stats.noise;
+ wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
+ IW_QUAL_NOISE_UPDATED;
+ wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable;
+ wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded;
+ wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa;
+ wstats->discard.fragment = bcm->ieee->ieee_stats.rx_fragments;
+ wstats->discard.misc = 0; // FIXME
+ wstats->miss.beacon = 0; // FIXME
+ return wstats;
+}
+
#ifdef WX
# undef WX
{
.cmd = PRIV_WX_SET_SHORTPREAMBLE,
.set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- .name = "set_shortpreambl",
+ .name = "set_shortpreamb",
},
{
.cmd = PRIV_WX_GET_SHORTPREAMBLE,
.get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
- .name = "get_shortpreambl",
+ .name = "get_shortpreamb",
},
{
.cmd = PRIV_WX_SET_SWENCRYPTION,
.set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- .name = "set_swencryption",
+ .name = "set_swencrypt",
},
{
.cmd = PRIV_WX_GET_SWENCRYPTION,
.get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
- .name = "get_swencryption",
+ .name = "get_swencrypt",
},
{
.cmd = PRIV_WX_SPROM_WRITE,
.num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args),
.private = bcm43xx_priv_wx_handlers,
.private_args = bcm43xx_priv_wx_args,
+ .get_wireless_stats = bcm43xx_get_wireless_stats,
};
-
-/* vim: set ts=8 sw=8 sts=8: */