crypto_cipher_setkey(tfm, pkey, 16);
counter = 0;
- for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) {
+ for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
aes_counter[15] = (u8)(counter >> 0);
aes_counter[14] = (u8)(counter >> 8);
aes_counter[13] = (u8)(counter >> 16);
memcpy (plain, aes_counter, 16);
crypto_cipher_encrypt_one(tfm, plain, plain);
cipher = plain;
- for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
+ for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
j += 4;
}
static int proc_config_open( struct inode *inode, struct file *file );
static int proc_wepkey_open( struct inode *inode, struct file *file );
-static struct file_operations proc_statsdelta_ops = {
+static const struct file_operations proc_statsdelta_ops = {
.read = proc_read,
.open = proc_statsdelta_open,
.release = proc_close
};
-static struct file_operations proc_stats_ops = {
+static const struct file_operations proc_stats_ops = {
.read = proc_read,
.open = proc_stats_open,
.release = proc_close
};
-static struct file_operations proc_status_ops = {
+static const struct file_operations proc_status_ops = {
.read = proc_read,
.open = proc_status_open,
.release = proc_close
};
-static struct file_operations proc_SSID_ops = {
+static const struct file_operations proc_SSID_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_SSID_open,
.release = proc_close
};
-static struct file_operations proc_BSSList_ops = {
+static const struct file_operations proc_BSSList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_BSSList_open,
.release = proc_close
};
-static struct file_operations proc_APList_ops = {
+static const struct file_operations proc_APList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_APList_open,
.release = proc_close
};
-static struct file_operations proc_config_ops = {
+static const struct file_operations proc_config_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_config_open,
.release = proc_close
};
-static struct file_operations proc_wepkey_ops = {
+static const struct file_operations proc_wepkey_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_wepkey_open,
#define PFX KBUILD_MODNAME ": "
#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
- #define BCM43xx_IRQWAIT_MAX_RETRIES 50
+ #define BCM43xx_IRQWAIT_MAX_RETRIES 100
#define BCM43xx_IO_SIZE 8192
#define BCM43xx_SBF_PS2 0x04000000
#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
#define BCM43xx_SBF_TIME_UPDATE 0x10000000
- #define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
+ #define BCM43xx_SBF_MODE_G 0x80000000
/* Microcode */
#define BCM43xx_UCODE_REVISION 0x0000
#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
#define BCM43xx_UCODEFLAG_JAPAN 0x0080
+/* Hardware Radio Enable masks */
+#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16)
+#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
+
/* Generic-Interrupt reasons. */
#define BCM43xx_IRQ_READY (1 << 0)
#define BCM43xx_IRQ_BEACON (1 << 1)
u8 et1macaddr[6];
u8 et0phyaddr:5;
u8 et1phyaddr:5;
- u8 et0mdcport:1;
- u8 et1mdcport:1;
u8 boardrev;
u8 locale:4;
u8 antennas_aphy:2;
struct bcm43xx_phyinfo {
/* Hardware Data */
- u8 version;
+ u8 analog;
u8 type;
u8 rev;
u16 antenna_diversity;
bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
short_preamble:1, /* TRUE, if short preamble is enabled. */
- firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
+ firmware_norelease:1, /* Do not release the firmware. Used on suspend. */
+ radio_hw_enable:1; /* TRUE if radio is hardware enabled */
struct bcm43xx_stats stats;
value = sprom[BCM43xx_SPROM_ETHPHY];
bcm->sprom.et0phyaddr = (value & 0x001F);
bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
- bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
- bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
/* boardrev, antennas, locale */
value = sprom[BCM43xx_SPROM_BOARDREV];
bcm43xx_debugfs_log_txstat(bcm, &stat);
- if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
+ continue;
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
continue;
- if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
- //TODO: packet was not acked (was lost)
- }
- //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_handle_xmitstatus(bcm, &stat);
if (err)
goto err_gpio_cleanup;
bcm43xx_radio_turn_on(bcm);
+ bcm->radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
+ dprintk(KERN_INFO PFX "Radio %s by hardware\n",
+ (bcm->radio_hw_enable == 0) ? "disabled" : "enabled");
bcm43xx_write16(bcm, 0x03E6, 0x0000);
err = bcm43xx_phy_init(bcm);
}
static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
+{
+ bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
+ //TODO for APHY (temperature?)
+}
+
+static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
+ int radio_hw_enable;
+ /* check if radio hardware enabled status changed */
+ radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
+ if (unlikely(bcm->radio_hw_enable != radio_hw_enable)) {
+ bcm->radio_hw_enable = radio_hw_enable;
+ dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n",
+ (radio_hw_enable == 0) ? "disabled" : "enabled");
+ bcm43xx_leds_update(bcm, 0);
+ }
if (phy->type == BCM43xx_PHYTYPE_G) {
//TODO: update_aci_moving_average
if (radio->aci_enable && radio->aci_wlan_automatic) {
//TODO: implement rev1 workaround
}
}
- bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
- //TODO for APHY (temperature?)
}
static void do_periodic_work(struct bcm43xx_private *bcm)
{
- if (bcm->periodic_state % 8 == 0)
+ if (bcm->periodic_state % 120 == 0)
bcm43xx_periodic_every120sec(bcm);
- if (bcm->periodic_state % 4 == 0)
+ if (bcm->periodic_state % 60 == 0)
bcm43xx_periodic_every60sec(bcm);
- if (bcm->periodic_state % 2 == 0)
+ if (bcm->periodic_state % 30 == 0)
bcm43xx_periodic_every30sec(bcm);
- bcm43xx_periodic_every15sec(bcm);
+ if (bcm->periodic_state % 15 == 0)
+ bcm43xx_periodic_every15sec(bcm);
+ bcm43xx_periodic_every1sec(bcm);
- schedule_delayed_work(&bcm->periodic_work, HZ * 15);
+ schedule_delayed_work(&bcm->periodic_work, HZ);
}
static void bcm43xx_periodic_work_handler(struct work_struct *work)
unsigned long orig_trans_start = 0;
mutex_lock(&bcm->mutex);
- if (unlikely(bcm->periodic_state % 4 == 0)) {
+ if (unlikely(bcm->periodic_state % 60 == 0)) {
/* Periodic work will take a long time, so we want it to
* be preemtible.
*/
do_periodic_work(bcm);
- if (unlikely(bcm->periodic_state % 4 == 0)) {
+ if (unlikely(bcm->periodic_state % 60 == 0)) {
spin_lock_irqsave(&bcm->irq_lock, flags);
tasklet_enable(&bcm->isr_tasklet);
bcm43xx_interrupt_enable(bcm, savedirqs);
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
u16 value;
- u8 phy_version;
+ u8 phy_analog;
u8 phy_type;
u8 phy_rev;
int phy_rev_ok = 1;
value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
- phy_version = (value & 0xF000) >> 12;
+ phy_analog = (value & 0xF000) >> 12;
phy_type = (value & 0x0F00) >> 8;
phy_rev = (value & 0x000F);
- dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
- phy_version, phy_type, phy_rev);
+ dprintk(KERN_INFO PFX "Detected PHY: Analog: %x, Type %x, Revision %x\n",
+ phy_analog, phy_type, phy_rev);
switch (phy_type) {
case BCM43xx_PHYTYPE_A:
phy_rev);
}
- phy->version = phy_version;
+ phy->analog = phy_analog;
phy->type = phy_type;
phy->rev = phy_rev;
if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
// Initialization
- if (phy->version == 0) {
+ if (phy->analog == 0) {
bcm43xx_write16(bcm, 0x03E6, 0x0122);
} else {
- if (phy->version >= 2)
- bcm43xx_write16(bcm, 0x03E6, 0x0040);
+ if (phy->analog >= 2)
+ bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003)
+ & 0xFFBF) | 0x0040);
bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
(bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000));
}
ret = bcm43xx_radio_calibrationvalue(bcm);
if (phy->type == BCM43xx_PHYTYPE_B)
- bcm43xx_radio_write16(bcm, 0x0078, 0x0003);
+ bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
bcm43xx_phy_write(bcm, 0x002B, 0x1403);
(bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
bcm43xx_radio_write16(bcm, 0x0043,
- bcm43xx_radio_read16(bcm, 0x0043) | 0x0009);
+ (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009);
bcm43xx_phy_write(bcm, 0x0058, 0x0000);
for (i = 0; i < 16; i++) {
bcm43xx_phy_write(bcm, 0x0059, backup[17]);
bcm43xx_phy_write(bcm, 0x0058, backup[18]);
bcm43xx_write16(bcm, 0x03E6, backup[11]);
- if (phy->version != 0)
+ if (phy->analog != 0)
bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
bcm43xx_phy_write(bcm, 0x0035, backup[10]);
bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
}
radio->enabled = 1;
dprintk(KERN_INFO PFX "Radio turned on\n");
+ bcm43xx_leds_update(bcm, 0);
}
void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0015, 0xAA00);
radio->enabled = 0;
dprintk(KERN_INFO PFX "Radio turned off\n");
+ bcm43xx_leds_update(bcm, 0);
}
void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm)
dev_info(zd_chip_dev(chip), "%s\n", buffer);
}
+static zd_addr_t inc_addr(zd_addr_t addr)
+{
+ u16 a = (u16)addr;
+ /* Control registers use byte addressing, but everything else uses word
+ * addressing. */
+ if ((a & 0xf000) == CR_START)
+ a += 2;
+ else
+ a += 1;
+ return (zd_addr_t)a;
+}
+
/* Read a variable number of 32-bit values. Parameter count is not allowed to
* exceed USB_MAX_IOREAD32_COUNT.
*/
/* Allocate a single memory block for values and addresses. */
count16 = 2*count;
- a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+ a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
GFP_NOFS);
if (!a16) {
dev_dbg_f(zd_chip_dev(chip),
for (i = 0; i < count; i++) {
int j = 2*i;
/* We read the high word always first. */
- a16[j] = zd_inc_word(addr[i]);
+ a16[j] = inc_addr(addr[i]);
a16[j+1] = addr[i];
}
j = 2*i;
/* We write the high word always first. */
ioreqs16[j].value = ioreqs[i].value >> 16;
- ioreqs16[j].addr = zd_inc_word(ioreqs[i].addr);
+ ioreqs16[j].addr = inc_addr(ioreqs[i].addr);
ioreqs16[j+1].value = ioreqs[i].value;
ioreqs16[j+1].addr = ioreqs[i].addr;
}
ZD_ASSERT(mutex_is_locked(&chip->mutex));
for (i = 0;;) {
- r = zd_ioread32_locked(chip, &v, e2p_addr+i/2);
+ r = zd_ioread32_locked(chip, &v,
+ (zd_addr_t)((u16)e2p_addr+i/2));
if (r)
return r;
v -= guard;
static int zd1211_hw_init_hmac(struct zd_chip *chip)
{
static const struct zd_ioreq32 ioreqs[] = {
- { CR_ACK_TIMEOUT_EXT, 0x20 },
- { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
{ CR_ZD1211_RETRY_MAX, 0x2 },
- { CR_SNIFFER_ON, 0 },
- { CR_RX_FILTER, STA_RX_FILTER },
- { CR_GROUP_HASH_P1, 0x00 },
- { CR_GROUP_HASH_P2, 0x80000000 },
- { CR_REG1, 0xa4 },
- { CR_ADDA_PWR_DWN, 0x7f },
- { CR_BCN_PLCP_CFG, 0x00f00401 },
- { CR_PHY_DELAY, 0x00 },
- { CR_ACK_TIMEOUT_EXT, 0x80 },
- { CR_ADDA_PWR_DWN, 0x00 },
- { CR_ACK_TIME_80211, 0x100 },
- { CR_RX_PE_DELAY, 0x70 },
- { CR_PS_CTRL, 0x10000000 },
- { CR_RTS_CTS_RATE, 0x02030203 },
{ CR_RX_THRESHOLD, 0x000c0640 },
- { CR_AFTER_PNP, 0x1 },
- { CR_WEP_PROTECT, 0x114 },
};
- int r;
-
dev_dbg_f(zd_chip_dev(chip), "\n");
ZD_ASSERT(mutex_is_locked(&chip->mutex));
- r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
-#ifdef DEBUG
- if (r) {
- dev_err(zd_chip_dev(chip),
- "error in zd_iowrite32a_locked. Error number %d\n", r);
- }
-#endif /* DEBUG */
- return r;
+ return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}
static int zd1211b_hw_init_hmac(struct zd_chip *chip)
{
static const struct zd_ioreq32 ioreqs[] = {
- { CR_ACK_TIMEOUT_EXT, 0x20 },
- { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
{ CR_ZD1211B_RETRY_MAX, 0x02020202 },
{ CR_ZD1211B_TX_PWR_CTL4, 0x007f003f },
{ CR_ZD1211B_TX_PWR_CTL3, 0x007f003f },
{ CR_ZD1211B_AIFS_CTL1, 0x00280028 },
{ CR_ZD1211B_AIFS_CTL2, 0x008C003C },
{ CR_ZD1211B_TXOP, 0x01800824 },
+ { CR_RX_THRESHOLD, 0x000c0eff, },
+ };
+
+ dev_dbg_f(zd_chip_dev(chip), "\n");
+ ZD_ASSERT(mutex_is_locked(&chip->mutex));
+ return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int hw_init_hmac(struct zd_chip *chip)
+{
+ int r;
+ static const struct zd_ioreq32 ioreqs[] = {
+ { CR_ACK_TIMEOUT_EXT, 0x20 },
+ { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
{ CR_SNIFFER_ON, 0 },
{ CR_RX_FILTER, STA_RX_FILTER },
{ CR_GROUP_HASH_P1, 0x00 },
{ CR_RX_PE_DELAY, 0x70 },
{ CR_PS_CTRL, 0x10000000 },
{ CR_RTS_CTS_RATE, 0x02030203 },
- { CR_RX_THRESHOLD, 0x000c0eff, },
{ CR_AFTER_PNP, 0x1 },
{ CR_WEP_PROTECT, 0x114 },
+ { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
};
- int r;
-
- dev_dbg_f(zd_chip_dev(chip), "\n");
ZD_ASSERT(mutex_is_locked(&chip->mutex));
r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
- if (r) {
- dev_dbg_f(zd_chip_dev(chip),
- "error in zd_iowrite32a_locked. Error number %d\n", r);
- }
- return r;
-}
+ if (r)
+ return r;
-static int hw_init_hmac(struct zd_chip *chip)
-{
return chip->is_zd1211b ?
zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
}
if (r)
return r;
- /* Although the vendor driver defaults to a different value during
- * init, it overwrites the IFS value with the following every time
- * the channel changes. We should aim to be more intelligent... */
- r = zd_iowrite32_locked(chip, IFS_VALUE_DEFAULT, CR_IFS_VALUE);
- if (r)
- return r;
-
return set_beacon_interval(chip, 100);
}
+static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
+{
+ return (zd_addr_t)((u16)chip->fw_regs_base + offset);
+}
+
#ifdef DEBUG
static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
const char *addr_string)
static void dump_fw_registers(struct zd_chip *chip)
{
- static const zd_addr_t addr[4] = {
- FW_FIRMWARE_VER, FW_USB_SPEED, FW_FIX_TX_RATE,
- FW_LINK_STATUS
+ const zd_addr_t addr[4] = {
+ fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
+ fw_reg_addr(chip, FW_REG_USB_SPEED),
+ fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
+ fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
};
int r;
int r;
u16 version;
- r = zd_ioread16_locked(chip, &version, FW_FIRMWARE_VER);
+ r = zd_ioread16_locked(chip, &version,
+ fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
if (r)
return r;
return r;
}
+static int read_fw_regs_offset(struct zd_chip *chip)
+{
+ int r;
+
+ ZD_ASSERT(mutex_is_locked(&chip->mutex));
+ r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
+ FWRAW_REGS_ADDR);
+ if (r)
+ return r;
+ dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
+ (u16)chip->fw_regs_base);
+
+ return 0;
+}
+
+
int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
{
int r;
if (r)
goto out;
- r = zd_usb_init_hw(&chip->usb);
+ r = read_fw_regs_offset(chip);
if (r)
goto out;
int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
{
- static const zd_addr_t a[] = {
- FW_LINK_STATUS,
+ const zd_addr_t a[] = {
+ fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
CR_LED,
};
int r;
u16 v[ARRAY_SIZE(a)];
struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
- [0] = { FW_LINK_STATUS },
+ [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
[1] = { CR_LED },
};
u16 other_led;
{
struct ieee80211softmac_device *softmac;
struct net_device *dev;
-
+
dev = alloc_ieee80211(sizeof(struct ieee80211softmac_device) + sizeof_priv);
softmac = ieee80211_priv(dev);
softmac->dev = dev;
softmac->ieee = netdev_priv(dev);
spin_lock_init(&softmac->lock);
-
+
softmac->ieee->handle_auth = ieee80211softmac_auth_resp;
softmac->ieee->handle_deauth = ieee80211softmac_deauth_resp;
softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
- softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
+ softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
softmac->scaninfo = NULL;
softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
/* to start with, we can't send anything ... */
netif_carrier_off(dev);
-
+
return dev;
}
EXPORT_SYMBOL_GPL(alloc_ieee80211softmac);
/* Clears the pending work queue items, stops all scans, etc. */
-void
+void
ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
{
unsigned long flags;
struct ieee80211softmac_event *eventptr, *eventtmp;
struct ieee80211softmac_auth_queue_item *authptr, *authtmp;
struct ieee80211softmac_network *netptr, *nettmp;
-
+
ieee80211softmac_stop_scan(sm);
ieee80211softmac_wait_for_scan(sm);
-
+
spin_lock_irqsave(&sm->lock, flags);
sm->running = 0;
/* Free all pending assoc work items */
cancel_delayed_work(&sm->associnfo.work);
-
+
/* Free all pending scan work items */
if(sm->scaninfo != NULL)
- cancel_delayed_work(&sm->scaninfo->softmac_scan);
-
+ cancel_delayed_work(&sm->scaninfo->softmac_scan);
+
/* Free all pending auth work items */
list_for_each_entry(authptr, &sm->auth_queue, list)
cancel_delayed_work(&authptr->work);
-
+
/* delete all pending event calls and work items */
list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list)
cancel_delayed_work(&eventptr->work);
list_del(&authptr->list);
kfree(authptr);
}
-
+
/* delete all pending event calls and work items */
list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list) {
list_del(&eventptr->list);
kfree(eventptr);
}
-
+
/* Free all networks */
list_for_each_entry_safe(netptr, nettmp, &sm->network_list, list) {
ieee80211softmac_del_network_locked(sm, netptr);
void free_ieee80211softmac(struct net_device *dev)
{
struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- ieee80211softmac_clear_pending_work(sm);
+ ieee80211softmac_clear_pending_work(sm);
kfree(sm->scaninfo);
kfree(sm->wpa.IE);
free_ieee80211(dev);
void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
u8 erp_value)
{
- int use_protection;
+ int use_protection;
int short_preamble;
- u32 changes = 0;
+ u32 changes = 0;
/* Barker preamble mode */
short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
/* Change the default txrate to the highest possible value.
* The txrate machine will lower it, if it is too high.
*/
- /* FIXME: We don't correctly handle backing down to lower
- rates, so 801.11g devices start off at 11M for now. People
- can manually change it if they really need to, but 11M is
- more reliable. Note similar logic in
- ieee80211softmac_wx_set_rate() */
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
+ if (ieee->modulation & IEEE80211_OFDM_MODULATION)
+ txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
+ else
txrates->user_rate = IEEE80211_CCK_RATE_11MB;
- } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
- txrates->user_rate = IEEE80211_OFDM_RATE_54MB;
- } else
- assert(0);
txrates->default_rate = IEEE80211_CCK_RATE_1MB;
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
unsigned long flags;
-
+
spin_lock_irqsave(&mac->lock, flags);
memcpy(mac->ratesinfo.rates, rates, count);
mac->ratesinfo.count = count;
{
int i;
struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
+
for (i=0; i<ri->count-1; i++) {
if (ri->rates[i] == rate)
return ri->rates[i+1];
{
int i;
struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
+
for (i=delta; i<ri->count; i++) {
if (ri->rates[i] == rate)
return ri->rates[i-delta];
softnet->channel = net->channel;
softnet->essid.len = net->ssid_len;
memcpy(softnet->essid.data, net->ssid, softnet->essid.len);
-
+
/* copy rates over */
softnet->supported_rates.count = net->rates_len;
memcpy(&softnet->supported_rates.rates[0], net->rates, net->rates_len);
{
unsigned long flags;
struct ieee80211softmac_network *softmac_net;
-
+
spin_lock_irqsave(&mac->lock, flags);
softmac_net = ieee80211softmac_get_network_by_bssid_locked(mac, bssid);
spin_unlock_irqrestore(&mac->lock, flags);
/* Get a network from the list by ESSID with locking */
struct ieee80211softmac_network *
ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid)
+ struct ieee80211softmac_essid *essid)
{
unsigned long flags;
struct ieee80211softmac_network *softmac_net = NULL;
spin_lock_irqsave(&mac->lock, flags);
- softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid);
+ softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid);
spin_unlock_irqrestore(&mac->lock, flags);
return softmac_net;
}
/* If all fails, return ANY (empty) */
data->essid.length = 0;
data->essid.flags = 0; /* active */
-
+
/* If we have a statically configured ESSID then return it */
if (sm->associnfo.static_essid) {
data->essid.length = sm->associnfo.req_essid.len;
data->essid.flags = 1; /* active */
memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len);
}
-
+
/* If we're associating/associated, return that */
if (sm->associnfo.associated || sm->associnfo.associating) {
data->essid.length = sm->associnfo.associate_essid.len;
int err = -EINVAL;
if (in_rate == -1) {
- /* FIXME: We don't correctly handle backing down to lower
- rates, so 801.11g devices start off at 11M for now. People
- can manually change it if they really need to, but 11M is
- more reliable. Note similar logic in
- ieee80211softmac_wx_set_rate() */
- if (ieee->modulation & IEEE80211_CCK_MODULATION)
- in_rate = 11000000;
+ if (ieee->modulation & IEEE80211_OFDM_MODULATION)
+ in_rate = 24000000;
else
- in_rate = 54000000;
+ in_rate = 11000000;
}
switch (in_rate) {
ieee80211softmac_recalc_txrates(mac);
err = 0;
-out_unlock:
+out_unlock:
spin_unlock_irqrestore(&mac->lock, flags);
out:
return err;
int err = -EINVAL;
spin_lock_irqsave(&mac->lock, flags);
+
+ if (unlikely(!mac->running)) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
+
switch (mac->txrates.default_rate) {
case IEEE80211_CCK_RATE_1MB:
data->bitrate.value = 1000000;
} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
/* the bssid we have is no longer fixed */
mac->associnfo.bssfixed = 0;
- } else {
+ } else {
if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
if (mac->associnfo.associating || mac->associnfo.associated) {
/* bssid unchanged and associated or associating - just return */
mac->associnfo.bssfixed = 1;
/* queue associate if new bssid or (old one again and not associated) */
schedule_delayed_work(&mac->associnfo.work, 0);
- }
+ }
out:
mutex_unlock(&mac->associnfo.mutex);
mac->wpa.IEbuflen = 0;
}
- out:
+ out:
spin_unlock_irqrestore(&mac->lock, flags);
mutex_unlock(&mac->associnfo.mutex);
mutex_lock(&mac->associnfo.mutex);
spin_lock_irqsave(&mac->lock, flags);
-
+
wrqu->data.length = 0;
-
+
if (mac->wpa.IE && mac->wpa.IElen) {
wrqu->data.length = mac->wpa.IElen;
if (mac->wpa.IElen <= space)