Merge branch 'bcm43xx' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream
This commit is contained in:
commit
fd39c68892
|
@ -504,6 +504,12 @@ struct bcm43xx_phyinfo {
|
|||
* This lock is only used by bcm43xx_phy_{un}lock()
|
||||
*/
|
||||
spinlock_t lock;
|
||||
|
||||
/* Firmware. */
|
||||
const struct firmware *ucode;
|
||||
const struct firmware *pcm;
|
||||
const struct firmware *initvals0;
|
||||
const struct firmware *initvals1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -593,12 +599,14 @@ struct bcm43xx_coreinfo {
|
|||
u8 available:1,
|
||||
enabled:1,
|
||||
initialized:1;
|
||||
/** core_id ID number */
|
||||
u16 id;
|
||||
/** core_rev revision number */
|
||||
u8 rev;
|
||||
/** Index number for _switch_core() */
|
||||
u8 index;
|
||||
/** core_id ID number */
|
||||
u16 id;
|
||||
/** Core-specific data. */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* Additional information for each 80211 core. */
|
||||
|
@ -647,7 +655,10 @@ enum {
|
|||
BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
|
||||
};
|
||||
#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
|
||||
#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
|
||||
#define bcm43xx_set_status(bcm, stat) do { \
|
||||
atomic_set(&(bcm)->init_status, (stat)); \
|
||||
smp_wmb(); \
|
||||
} while (0)
|
||||
|
||||
/* *** THEORY OF LOCKING ***
|
||||
*
|
||||
|
@ -721,10 +732,6 @@ struct bcm43xx_private {
|
|||
struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
|
||||
/* Additional information, specific to the 80211 cores. */
|
||||
struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
|
||||
/* Index of the current 80211 core. If current_core is not
|
||||
* an 80211 core, this is -1.
|
||||
*/
|
||||
int current_80211_core_idx;
|
||||
/* Number of available 80211 cores. */
|
||||
int nr_80211_available;
|
||||
|
||||
|
@ -737,6 +744,8 @@ struct bcm43xx_private {
|
|||
u32 irq_savedstate;
|
||||
/* Link Quality calculation context. */
|
||||
struct bcm43xx_noise_calculation noisecalc;
|
||||
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
|
||||
int mac_suspended;
|
||||
|
||||
/* Threshold values. */
|
||||
//TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
|
||||
|
@ -759,12 +768,6 @@ struct bcm43xx_private {
|
|||
struct bcm43xx_key key[54];
|
||||
u8 default_key_idx;
|
||||
|
||||
/* Firmware. */
|
||||
const struct firmware *ucode;
|
||||
const struct firmware *pcm;
|
||||
const struct firmware *initvals0;
|
||||
const struct firmware *initvals1;
|
||||
|
||||
/* Random Number Generator. */
|
||||
struct hwrng rng;
|
||||
char rng_name[20 + 1];
|
||||
|
@ -827,34 +830,33 @@ int bcm43xx_using_pio(struct bcm43xx_private *bcm)
|
|||
* any of these functions.
|
||||
*/
|
||||
static inline
|
||||
struct bcm43xx_coreinfo_80211 *
|
||||
bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
|
||||
{
|
||||
assert(bcm->current_core->id == BCM43xx_COREID_80211);
|
||||
return bcm->current_core->priv;
|
||||
}
|
||||
static inline
|
||||
struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
|
||||
{
|
||||
assert(bcm43xx_using_pio(bcm));
|
||||
assert(bcm->current_80211_core_idx >= 0);
|
||||
assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
|
||||
return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
|
||||
return &(bcm43xx_current_80211_priv(bcm)->pio);
|
||||
}
|
||||
static inline
|
||||
struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
|
||||
{
|
||||
assert(!bcm43xx_using_pio(bcm));
|
||||
assert(bcm->current_80211_core_idx >= 0);
|
||||
assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
|
||||
return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
|
||||
return &(bcm43xx_current_80211_priv(bcm)->dma);
|
||||
}
|
||||
static inline
|
||||
struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
|
||||
{
|
||||
assert(bcm->current_80211_core_idx >= 0);
|
||||
assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
|
||||
return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
|
||||
return &(bcm43xx_current_80211_priv(bcm)->phy);
|
||||
}
|
||||
static inline
|
||||
struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
|
||||
{
|
||||
assert(bcm->current_80211_core_idx >= 0);
|
||||
assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
|
||||
return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
|
||||
return &(bcm43xx_current_80211_priv(bcm)->radio);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -316,6 +316,42 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
|
|||
return res;
|
||||
}
|
||||
|
||||
static ssize_t restart_write_file(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct bcm43xx_private *bcm = file->private_data;
|
||||
char *buf = really_big_buffer;
|
||||
ssize_t buf_size;
|
||||
ssize_t res;
|
||||
unsigned long flags;
|
||||
|
||||
buf_size = min(count, sizeof (really_big_buffer) - 1);
|
||||
down(&big_buffer_sem);
|
||||
if (copy_from_user(buf, user_buf, buf_size)) {
|
||||
res = -EFAULT;
|
||||
goto out_up;
|
||||
}
|
||||
mutex_lock(&(bcm)->mutex);
|
||||
spin_lock_irqsave(&(bcm)->irq_lock, flags);
|
||||
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
|
||||
printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
|
||||
res = -EFAULT;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (count > 0 && buf[0] == '1') {
|
||||
bcm43xx_controller_restart(bcm, "manually restarted");
|
||||
res = count;
|
||||
} else
|
||||
res = -EINVAL;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
|
||||
mutex_unlock(&(bcm)->mutex);
|
||||
out_up:
|
||||
up(&big_buffer_sem);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef fappend
|
||||
|
||||
|
||||
|
@ -349,6 +385,11 @@ static struct file_operations txstat_fops = {
|
|||
.open = open_file_generic,
|
||||
};
|
||||
|
||||
static struct file_operations restart_fops = {
|
||||
.write = restart_write_file,
|
||||
.open = open_file_generic,
|
||||
};
|
||||
|
||||
|
||||
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
|
||||
{
|
||||
|
@ -400,6 +441,10 @@ void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
|
|||
bcm, &txstat_fops);
|
||||
if (!e->dentry_txstat)
|
||||
printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
|
||||
e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
|
||||
bcm, &restart_fops);
|
||||
if (!e->dentry_restart)
|
||||
printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" failed!\n", devdir);
|
||||
}
|
||||
|
||||
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
|
||||
|
@ -415,6 +460,7 @@ void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
|
|||
debugfs_remove(e->dentry_devinfo);
|
||||
debugfs_remove(e->dentry_tsf);
|
||||
debugfs_remove(e->dentry_txstat);
|
||||
debugfs_remove(e->dentry_restart);
|
||||
debugfs_remove(e->subdir);
|
||||
kfree(e->xmitstatus_buffer);
|
||||
kfree(e->xmitstatus_print_buffer);
|
||||
|
|
|
@ -20,6 +20,7 @@ struct bcm43xx_dfsentry {
|
|||
struct dentry *dentry_spromdump;
|
||||
struct dentry *dentry_tsf;
|
||||
struct dentry *dentry_txstat;
|
||||
struct dentry *dentry_restart;
|
||||
|
||||
struct bcm43xx_private *bcm;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -133,6 +133,9 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm);
|
|||
|
||||
int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
|
||||
|
||||
int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
|
||||
int phytype);
|
||||
|
||||
void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
|
||||
|
||||
void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
|
||||
|
|
|
@ -309,6 +309,70 @@ static DEVICE_ATTR(shortpreamble, 0644,
|
|||
bcm43xx_attr_preamble_show,
|
||||
bcm43xx_attr_preamble_store);
|
||||
|
||||
static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct bcm43xx_private *bcm = dev_to_bcm(dev);
|
||||
int phytype;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (count < 1)
|
||||
goto out;
|
||||
switch (buf[0]) {
|
||||
case 'a': case 'A':
|
||||
phytype = BCM43xx_PHYTYPE_A;
|
||||
break;
|
||||
case 'b': case 'B':
|
||||
phytype = BCM43xx_PHYTYPE_B;
|
||||
break;
|
||||
case 'g': case 'G':
|
||||
phytype = BCM43xx_PHYTYPE_G;
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&(bcm)->mutex);
|
||||
err = bcm43xx_select_wireless_core(bcm, phytype);
|
||||
mutex_unlock(&(bcm)->mutex);
|
||||
if (err == -ESRCH)
|
||||
err = -ENODEV;
|
||||
|
||||
out:
|
||||
return err ? err : count;
|
||||
}
|
||||
|
||||
static ssize_t bcm43xx_attr_phymode_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bcm43xx_private *bcm = dev_to_bcm(dev);
|
||||
ssize_t count = 0;
|
||||
|
||||
mutex_lock(&(bcm)->mutex);
|
||||
switch (bcm43xx_current_phy(bcm)->type) {
|
||||
case BCM43xx_PHYTYPE_A:
|
||||
snprintf(buf, PAGE_SIZE, "A");
|
||||
break;
|
||||
case BCM43xx_PHYTYPE_B:
|
||||
snprintf(buf, PAGE_SIZE, "B");
|
||||
break;
|
||||
case BCM43xx_PHYTYPE_G:
|
||||
snprintf(buf, PAGE_SIZE, "G");
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
mutex_unlock(&(bcm)->mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(phymode, 0644,
|
||||
bcm43xx_attr_phymode_show,
|
||||
bcm43xx_attr_phymode_store);
|
||||
|
||||
int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
|
||||
{
|
||||
struct device *dev = &bcm->pci_dev->dev;
|
||||
|
@ -325,9 +389,14 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
|
|||
err = device_create_file(dev, &dev_attr_shortpreamble);
|
||||
if (err)
|
||||
goto err_remove_interfmode;
|
||||
err = device_create_file(dev, &dev_attr_phymode);
|
||||
if (err)
|
||||
goto err_remove_shortpreamble;
|
||||
|
||||
out:
|
||||
return err;
|
||||
err_remove_shortpreamble:
|
||||
device_remove_file(dev, &dev_attr_shortpreamble);
|
||||
err_remove_interfmode:
|
||||
device_remove_file(dev, &dev_attr_interference);
|
||||
err_remove_sprom:
|
||||
|
@ -339,6 +408,7 @@ void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
|
|||
{
|
||||
struct device *dev = &bcm->pci_dev->dev;
|
||||
|
||||
device_remove_file(dev, &dev_attr_phymode);
|
||||
device_remove_file(dev, &dev_attr_shortpreamble);
|
||||
device_remove_file(dev, &dev_attr_interference);
|
||||
device_remove_file(dev, &dev_attr_sprom);
|
||||
|
|
|
@ -47,9 +47,8 @@
|
|||
#define BCM43xx_WX_VERSION 18
|
||||
|
||||
#define MAX_WX_STRING 80
|
||||
/* FIXME: the next line is a guess as to what the maximum value of RX power
|
||||
(in dBm) might be */
|
||||
#define RX_POWER_MAX -10
|
||||
/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
|
||||
#define RX_RSSI_MAX 60
|
||||
|
||||
|
||||
static int bcm43xx_wx_get_name(struct net_device *net_dev,
|
||||
|
@ -230,9 +229,8 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
|
|||
range->throughput = 27 * 1000 * 1000;
|
||||
|
||||
range->max_qual.qual = 100;
|
||||
/* TODO: Real max RSSI */
|
||||
range->max_qual.level = 0;
|
||||
range->max_qual.noise = 0;
|
||||
range->max_qual.level = 152; /* set floor at -104 dBm (152 - 256) */
|
||||
range->max_qual.noise = 152;
|
||||
range->max_qual.updated = IW_QUAL_ALL_UPDATED;
|
||||
|
||||
range->avg_qual.qual = 50;
|
||||
|
@ -845,6 +843,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
|
|||
struct iw_statistics *wstats;
|
||||
struct ieee80211_network *network = NULL;
|
||||
static int tmp_level = 0;
|
||||
static int tmp_qual = 0;
|
||||
unsigned long flags;
|
||||
|
||||
wstats = &bcm->stats.wstats;
|
||||
|
@ -863,25 +862,28 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
|
|||
wstats->qual.level = 0;
|
||||
wstats->qual.noise = 0;
|
||||
wstats->qual.updated = 7;
|
||||
wstats->qual.updated |= IW_QUAL_ALL_UPDATED;
|
||||
wstats->qual.updated |= IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
|
||||
return wstats;
|
||||
}
|
||||
/* fill in the real statistics when iface associated */
|
||||
spin_lock_irqsave(&mac->ieee->lock, flags);
|
||||
list_for_each_entry(network, &mac->ieee->network_list, list) {
|
||||
if (!memcmp(mac->associnfo.bssid, network->bssid, ETH_ALEN)) {
|
||||
if (!tmp_level) /* get initial value */
|
||||
tmp_level = network->stats.rssi;
|
||||
else /* smooth results */
|
||||
tmp_level = (7 * tmp_level + network->stats.rssi)/8;
|
||||
if (!tmp_level) { /* get initial values */
|
||||
tmp_level = network->stats.signal;
|
||||
tmp_qual = network->stats.rssi;
|
||||
} else { /* smooth results */
|
||||
tmp_level = (15 * tmp_level + network->stats.signal)/16;
|
||||
tmp_qual = (15 * tmp_qual + network->stats.rssi)/16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&mac->ieee->lock, flags);
|
||||
wstats->qual.level = tmp_level;
|
||||
wstats->qual.qual = 100 + tmp_level - RX_POWER_MAX; // TODO: get the real signal quality
|
||||
wstats->qual.qual = 100 * tmp_qual / RX_RSSI_MAX;
|
||||
wstats->qual.noise = bcm->stats.noise;
|
||||
wstats->qual.updated = IW_QUAL_ALL_UPDATED;
|
||||
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
|
||||
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;
|
||||
|
|
|
@ -492,16 +492,15 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
|
|||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
stats.mac_time = le16_to_cpu(rxhdr->mactime);
|
||||
stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
|
||||
stats.rssi = rxhdr->rssi;
|
||||
stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
|
||||
!!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
|
||||
!!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
|
||||
stats.signal = rxhdr->signal_quality; //FIXME
|
||||
//TODO stats.noise =
|
||||
if (is_ofdm)
|
||||
stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
|
||||
else
|
||||
stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
|
||||
//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate);
|
||||
stats.received_channel = radio->channel;
|
||||
//TODO stats.control =
|
||||
stats.mask = IEEE80211_STATMASK_SIGNAL |
|
||||
|
|
Loading…
Reference in New Issue