]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'upstream' into upstream-jgarzik
authorJohn W. Linville <linville@tuxdriver.com>
Sat, 17 Feb 2007 23:26:09 +0000 (18:26 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Sat, 17 Feb 2007 23:26:09 +0000 (18:26 -0500)
Conflicts:

net/ieee80211/softmac/ieee80211softmac_module.c
net/ieee80211/softmac/ieee80211softmac_wx.c

1  2 
drivers/net/wireless/airo.c
drivers/net/wireless/bcm43xx/bcm43xx.h
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_radio.c
drivers/net/wireless/zd1211rw/zd_chip.c
net/ieee80211/softmac/ieee80211softmac_module.c
net/ieee80211/softmac/ieee80211softmac_wx.c

index b08055abe83a3982345bde47937567af90b2e121,4ad910b1b69ab178ed673620a590fbf2103a4926..a8c2bfe26c2715291253628782cde302f3d63b39
@@@ -1623,7 -1623,7 +1623,7 @@@ static void emmh32_setseed(emmh32_conte
  
        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;
                }
@@@ -4430,53 -4430,53 +4430,53 @@@ static int proc_BSSList_open( struct in
  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,
index 0e790efae683cfdbe2e17e204ad7667af56871ed,6b1749bb72425a63cd4eed924b5dbd3628e3758c..95ff175d8f334227485ee75e995c8993f290f9eb
@@@ -21,7 -21,7 +21,7 @@@
  #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)
@@@ -507,8 -503,6 +507,6 @@@ struct bcm43xx_sprominfo 
        u8 et1macaddr[6];
        u8 et0phyaddr:5;
        u8 et1phyaddr:5;
-       u8 et0mdcport:1;
-       u8 et1mdcport:1;
        u8 boardrev;
        u8 locale:4;
        u8 antennas_aphy:2;
@@@ -542,7 -536,7 +540,7 @@@ struct bcm43xx_lopair 
  
  struct bcm43xx_phyinfo {
        /* Hardware Data */
-       u8 version;
+       u8 analog;
        u8 type;
        u8 rev;
        u16 antenna_diversity;
@@@ -762,8 -756,7 +760,8 @@@ struct bcm43xx_private 
            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;
  
index 2e400aacc436e2a72d10ab2f18a7875a15e0bfa5,e5336facd1586a4322d6289ec5b49c63db8afb6a..73c831a3b7479cd82b287863ddecd65934c1681a
@@@ -851,8 -851,6 +851,6 @@@ static int bcm43xx_sprom_extract(struc
        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];
@@@ -1449,12 -1447,10 +1447,10 @@@ static void handle_irq_transmit_status(
  
                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);
@@@ -2437,9 -2433,6 +2433,9 @@@ static int bcm43xx_chip_init(struct bcm
        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);
@@@ -3175,25 -3168,10 +3171,25 @@@ static void bcm43xx_periodic_every30sec
  }
  
  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);
@@@ -3696,7 -3674,7 +3692,7 @@@ static int bcm43xx_read_phyinfo(struct 
  {
        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)) {
index af19a07032a3ed8ba59a6ff031b97f9dbae1b3d4,3fbb3c6f779ef9bb3356391646eb6af849b62c37..32beb91b7164a5d27ebb9d23f1546de85610d87a
@@@ -1393,11 -1393,12 +1393,12 @@@ u16 bcm43xx_radio_init2050(struct bcm43
        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);
@@@ -1981,7 -1982,6 +1982,7 @@@ void bcm43xx_radio_turn_on(struct bcm43
        }
        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)
index 12dfc0b6efe6796b2f371b53a357e23dc1a558f6,953ac3aac9bed9c72f40980bd858a499c8c8ecb0..9c64f894b71b180fecb9f9742b29fdaac0d46162
@@@ -84,18 -84,6 +84,18 @@@ static void print_id(struct zd_chip *ch
        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.
   */
@@@ -113,7 -101,7 +113,7 @@@ int zd_ioread32v_locked(struct zd_chip 
  
        /* 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];
        }
  
@@@ -175,7 -163,7 +175,7 @@@ int _zd_iowrite32v_locked(struct zd_chi
                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;
        }
@@@ -478,8 -466,7 +478,8 @@@ static int read_values(struct zd_chip *
  
        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;
@@@ -811,18 -798,47 +811,18 @@@ static int hw_reset_phy(struct zd_chip 
  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);
  }
@@@ -963,14 -974,16 +963,14 @@@ static int hw_init(struct zd_chip *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)
@@@ -1005,11 -1018,9 +1005,11 @@@ static int test_init(struct zd_chip *ch
  
  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;
@@@ -1035,8 -1046,7 +1035,8 @@@ static int print_fw_version(struct zd_c
        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;
  
@@@ -1116,22 -1126,6 +1116,22 @@@ int zd_chip_disable_hwint(struct zd_chi
        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;
  
@@@ -1331,15 -1325,15 +1331,15 @@@ u8 zd_chip_get_channel(struct zd_chip *
  
  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;
index 4f8c3ef7081950b6e20157245b100dfca7f64065,770a068b298bb822871164343f39d4fceb22d62e..e9cdc6615ddc7483447d34907205c907a39782a0
@@@ -32,19 -32,19 +32,19 @@@ struct net_device *alloc_ieee80211softm
  {
        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);
@@@ -133,7 -133,7 +133,7 @@@ EXPORT_SYMBOL_GPL(ieee80211softmac_clea
  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);
@@@ -208,9 -208,9 +208,9 @@@ EXPORT_SYMBOL_GPL(ieee80211softmac_high
  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
@@@ -265,17 -265,10 +265,10 @@@ void ieee80211softmac_init_bss(struct i
        /* 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;
@@@ -332,7 -325,7 +325,7 @@@ void ieee80211softmac_set_rates(struct 
  {
        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;
@@@ -344,7 -337,7 +337,7 @@@ static u8 raise_rate(struct ieee80211so
  {
        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];
@@@ -357,7 -350,7 +350,7 @@@ u8 ieee80211softmac_lower_rate_delta(st
  {
        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];
@@@ -438,7 -431,7 +431,7 @@@ ieee80211softmac_create_network(struct 
        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);
@@@ -529,7 -522,7 +522,7 @@@ ieee80211softmac_get_network_by_bssid(s
  {
        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);
@@@ -556,13 -549,13 +549,13 @@@ ieee80211softmac_get_network_by_essid_l
  /* 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;
  }
index c306d52566e0dfda1673b37a089a85dd40ea78a7,89c83fa9aacb1fd91e6be04a2ae0a5a8c2c44065..f13937bf9e8ce20f3b2c171948593795d082b8ee
@@@ -142,14 -142,14 +142,14 @@@ ieee80211softmac_wx_get_essid(struct ne
        /* 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;
@@@ -177,15 -177,10 +177,10 @@@ ieee80211softmac_wx_set_rate(struct net
        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;
@@@ -265,12 -260,6 +260,12 @@@ ieee80211softmac_wx_get_rate(struct net
        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;
@@@ -366,7 -355,7 +361,7 @@@ ieee80211softmac_wx_set_wap(struct net_
        } 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);
@@@ -437,7 -426,7 +432,7 @@@ ieee80211softmac_wx_set_genie(struct ne
                mac->wpa.IEbuflen = 0;
        }
  
 - out: 
 + out:
        spin_unlock_irqrestore(&mac->lock, flags);
        mutex_unlock(&mac->associnfo.mutex);
  
@@@ -458,9 -447,9 +453,9 @@@ ieee80211softmac_wx_get_genie(struct ne
  
        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)