]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'upstream-fixes' into upstream
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 11 Sep 2006 20:40:03 +0000 (16:40 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 11 Sep 2006 20:40:03 +0000 (16:40 -0400)
1  2 
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.h

index 58419985e00fa156eb1e37623b711a6b69d68428,aa792821854e288139411940218c3cd5b297a10c..7c4e32cf0d471d2ebf0b1496e6eb520285900f18
@@@ -42,11 -42,12 +42,11 @@@ void zd_chip_init(struct zd_chip *chip
  
  void zd_chip_clear(struct zd_chip *chip)
  {
 -      mutex_lock(&chip->mutex);
 +      ZD_ASSERT(!mutex_is_locked(&chip->mutex));
        zd_usb_clear(&chip->usb);
        zd_rf_clear(&chip->rf);
 -      mutex_unlock(&chip->mutex);
        mutex_destroy(&chip->mutex);
 -      memset(chip, 0, sizeof(*chip));
 +      ZD_MEMCLEAR(chip, sizeof(*chip));
  }
  
  static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
@@@ -67,11 -68,10 +67,11 @@@ static int scnprint_id(struct zd_chip *
        i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
        i += scnprintf(buffer+i, size-i, " ");
        i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
 -      i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c", chip->pa_type,
 +      i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type,
                chip->patch_cck_gain ? 'g' : '-',
                chip->patch_cr157 ? '7' : '-',
 -              chip->patch_6m_band_edge ? '6' : '-');
 +              chip->patch_6m_band_edge ? '6' : '-',
 +              chip->new_phy_layout ? 'N' : '-');
        return i;
  }
  
@@@ -330,14 -330,13 +330,14 @@@ static int read_pod(struct zd_chip *chi
        chip->patch_cck_gain = (value >> 8) & 0x1;
        chip->patch_cr157 = (value >> 13) & 0x1;
        chip->patch_6m_band_edge = (value >> 21) & 0x1;
 +      chip->new_phy_layout = (value >> 31) & 0x1;
  
        dev_dbg_f(zd_chip_dev(chip),
                "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
 -              "patch 6M %d\n",
 +              "patch 6M %d new PHY %d\n",
                zd_rf_name(*rf_type), *rf_type,
                chip->pa_type, chip->patch_cck_gain,
 -              chip->patch_cr157, chip->patch_6m_band_edge);
 +              chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout);
        return 0;
  error:
        *rf_type = 0;
        chip->patch_cck_gain = 0;
        chip->patch_cr157 = 0;
        chip->patch_6m_band_edge = 0;
 +      chip->new_phy_layout = 0;
        return r;
  }
  
@@@ -719,7 -717,7 +719,7 @@@ static int zd1211b_hw_reset_phy(struct 
                { CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
                { CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
                { CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
 -              { CR30,  0x49 }, /* jointly decoder, no ASIC */
 +              { CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
                { CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
                { CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
                { CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
@@@ -809,6 -807,7 +809,6 @@@ static int zd1211_hw_init_hmac(struct z
                { CR_ACK_TIMEOUT_EXT,           0x80 },
                { CR_ADDA_PWR_DWN,              0x00 },
                { CR_ACK_TIME_80211,            0x100 },
 -              { CR_IFS_VALUE,                 0x547c032 },
                { CR_RX_PE_DELAY,               0x70 },
                { CR_PS_CTRL,                   0x10000000 },
                { CR_RTS_CTS_RATE,              0x02030203 },
@@@ -855,10 -854,11 +855,10 @@@ static int zd1211b_hw_init_hmac(struct 
                { CR_ACK_TIMEOUT_EXT,           0x80 },
                { CR_ADDA_PWR_DWN,              0x00 },
                { CR_ACK_TIME_80211,            0x100 },
 -              { CR_IFS_VALUE,                 0x547c032 },
                { CR_RX_PE_DELAY,               0x70 },
                { CR_PS_CTRL,                   0x10000000 },
                { CR_RTS_CTS_RATE,              0x02030203 },
 -              { CR_RX_THRESHOLD,              0x000c0640 },
 +              { CR_RX_THRESHOLD,              0x000c0eff, },
                { CR_AFTER_PNP,                 0x1 },
                { CR_WEP_PROTECT,               0x114 },
        };
@@@ -970,15 -970,10 +970,15 @@@ static int hw_init(struct zd_chip *chip
        r = hw_init_hmac(chip);
        if (r)
                return r;
 -      r = set_beacon_interval(chip, 100);
 +
 +      /* 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 0;
 +
 +      return set_beacon_interval(chip, 100);
  }
  
  #ifdef DEBUG
@@@ -1435,9 -1430,43 +1435,43 @@@ static int ofdm_qual_db(u8 status_quali
                        break;
        }
  
+       switch (rate) {
+       case ZD_OFDM_RATE_6M:
+       case ZD_OFDM_RATE_9M:
+               i += 3;
+               break;
+       case ZD_OFDM_RATE_12M:
+       case ZD_OFDM_RATE_18M:
+               i += 5;
+               break;
+       case ZD_OFDM_RATE_24M:
+       case ZD_OFDM_RATE_36M:
+               i += 9;
+               break;
+       case ZD_OFDM_RATE_48M:
+       case ZD_OFDM_RATE_54M:
+               i += 15;
+               break;
+       default:
+               return -EINVAL;
+       }
        return i;
  }
  
+ static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
+ {
+       int r;
+       r = ofdm_qual_db(status_quality, rate, size);
+       ZD_ASSERT(r >= 0);
+       if (r < 0)
+               r = 0;
+       r = (r * 100)/29;
+       return r <= 100 ? r : 100;
+ }
  static unsigned int log10times100(unsigned int x)
  {
        static const u8 log10[] = {
@@@ -1481,31 -1510,28 +1515,28 @@@ static int cck_snr_db(u8 status_quality
        return r;
  }
  
- static int rx_qual_db(const void *rx_frame, unsigned int size,
-                     const struct rx_status *status)
+ static int cck_qual_percent(u8 status_quality)
  {
-       return (status->frame_status&ZD_RX_OFDM) ?
-               ofdm_qual_db(status->signal_quality_ofdm,
-                            zd_ofdm_plcp_header_rate(rx_frame),
-                            size) :
-               cck_snr_db(status->signal_quality_cck);
+       int r;
+       r = cck_snr_db(status_quality);
+       r = (100*r)/17;
+       return r <= 100 ? r : 100;
  }
  
  u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
                      const struct rx_status *status)
  {
-       int r = rx_qual_db(rx_frame, size, status);
-       if (r < 0)
-               r = 0;
-       r = (r * 100) / 14;
-       if (r > 100)
-               r = 100;
-       return r;
+       return (status->frame_status&ZD_RX_OFDM) ?
+               ofdm_qual_percent(status->signal_quality_ofdm,
+                                 zd_ofdm_plcp_header_rate(rx_frame),
+                                 size) :
+               cck_qual_percent(status->signal_quality_cck);
  }
  
  u8 zd_rx_strength_percent(u8 rssi)
  {
-       int r = (rssi*100) / 30;
+       int r = (rssi*100) / 41;
        if (r > 100)
                r = 100;
        return (u8) r;
@@@ -1618,34 -1644,3 +1649,34 @@@ int zd_rfwritev_locked(struct zd_chip *
  
        return 0;
  }
 +
 +/*
 + * We can optionally program the RF directly through CR regs, if supported by
 + * the hardware. This is much faster than the older method.
 + */
 +int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
 +{
 +      struct zd_ioreq16 ioreqs[] = {
 +              { CR244, (value >> 16) & 0xff },
 +              { CR243, (value >>  8) & 0xff },
 +              { CR242,  value        & 0xff },
 +      };
 +      ZD_ASSERT(mutex_is_locked(&chip->mutex));
 +      return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 +}
 +
 +int zd_rfwritev_cr_locked(struct zd_chip *chip,
 +                        const u32 *values, unsigned int count)
 +{
 +      int r;
 +      unsigned int i;
 +
 +      for (i = 0; i < count; i++) {
 +              r = zd_rfwrite_cr_locked(chip, values[i]);
 +              if (r)
 +                      return r;
 +      }
 +
 +      return 0;
 +}
 +
index 0eda534a648cf30ef2129a81985f1929fbfd22a5,a9bd80a08613518311ec69a3a0823a9a29eb1aa6..0ddccf893989022a5860528245d01b31edf8215e
@@@ -127,9 -127,11 +127,9 @@@ out
  
  void zd_mac_clear(struct zd_mac *mac)
  {
 -      /* Aquire the lock. */
 -      spin_lock(&mac->lock);
 -      spin_unlock(&mac->lock);
        zd_chip_clear(&mac->chip);
 -      memset(mac, 0, sizeof(*mac));
 +      ZD_ASSERT(!spin_is_locked(&mac->lock));
 +      ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
  }
  
  static int reset_mode(struct zd_mac *mac)
@@@ -814,13 -816,25 +814,25 @@@ static int filter_rx(struct ieee80211_d
        return -EINVAL;
  }
  
- static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi)
+ static void update_qual_rssi(struct zd_mac *mac,
+                            const u8 *buffer, unsigned int length,
+                            u8 qual_percent, u8 rssi_percent)
  {
        unsigned long flags;
+       struct ieee80211_hdr_3addr *hdr;
+       int i;
+       hdr = (struct ieee80211_hdr_3addr *)buffer;
+       if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
+               return;
+       if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
+               return;
  
        spin_lock_irqsave(&mac->lock, flags);
-       mac->qual_average = (7 * mac->qual_average + qual_percent) / 8;
-       mac->rssi_average = (7 * mac->rssi_average + rssi) / 8;
+       i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
+       mac->qual_buffer[i] = qual_percent;
+       mac->rssi_buffer[i] = rssi_percent;
+       mac->stats_count++;
        spin_unlock_irqrestore(&mac->lock, flags);
  }
  
@@@ -851,7 -865,6 +863,6 @@@ static int fill_rx_stats(struct ieee802
        if (stats->rate)
                stats->mask |= IEEE80211_STATMASK_RATE;
  
-       update_qual_rssi(mac, stats->signal, stats->rssi);
        return 0;
  }
  
@@@ -875,6 -888,8 +886,8 @@@ int zd_mac_rx(struct zd_mac *mac, cons
                  sizeof(struct rx_status);
        buffer += ZD_PLCP_HEADER_SIZE;
  
+       update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
        r = filter_rx(ieee, buffer, length, &stats);
        if (r <= 0)
                return r;
@@@ -979,17 -994,31 +992,31 @@@ struct iw_statistics *zd_mac_get_wirele
  {
        struct zd_mac *mac = zd_netdev_mac(ndev);
        struct iw_statistics *iw_stats = &mac->iw_stats;
+       unsigned int i, count, qual_total, rssi_total;
  
        memset(iw_stats, 0, sizeof(struct iw_statistics));
        /* We are not setting the status, because ieee->state is not updated
         * at all and this driver doesn't track authentication state.
         */
        spin_lock_irq(&mac->lock);
-       iw_stats->qual.qual = mac->qual_average;
-       iw_stats->qual.level = mac->rssi_average;
-       iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED|
-                                IW_QUAL_NOISE_INVALID;
+       count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
+               mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
+       qual_total = rssi_total = 0;
+       for (i = 0; i < count; i++) {
+               qual_total += mac->qual_buffer[i];
+               rssi_total += mac->rssi_buffer[i];
+       }
        spin_unlock_irq(&mac->lock);
+       iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
+       if (count > 0) {
+               iw_stats->qual.qual = qual_total / count;
+               iw_stats->qual.level = rssi_total / count;
+               iw_stats->qual.updated |=
+                       IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
+       } else {
+               iw_stats->qual.updated |=
+                       IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
+       }
        /* TODO: update counter */
        return iw_stats;
  }
index 082bcf8ec8dc6fd5d69ad4911892b75397a45c34,b3ba49b84634b50ac209d62d7be19d591cf4a1ba..2b596cc8a41a638d6f4c7e3f58f719c31c33aaaf
@@@ -1,4 -1,4 +1,4 @@@
- /* zd_mac.c
+ /* zd_mac.h
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -87,9 -87,9 +87,9 @@@ struct rx_length_info 
  #define RX_LENGTH_INFO_TAG            0x697e
  
  struct rx_status {
+       u8 signal_quality_cck;
        /* rssi */
        u8 signal_strength;
-       u8 signal_quality_cck;
        u8 signal_quality_ofdm;
        u8 decryption_type;
        u8 frame_status;
@@@ -120,14 -120,17 +120,17 @@@ enum mac_flags 
        MAC_FIXED_CHANNEL = 0x01,
  };
  
+ #define ZD_MAC_STATS_BUFFER_SIZE 16
  struct zd_mac {
 -      struct net_device *netdev;
        struct zd_chip chip;
        spinlock_t lock;
 +      struct net_device *netdev;
        /* Unlocked reading possible */
        struct iw_statistics iw_stats;
-       u8 qual_average;
-       u8 rssi_average;
+       unsigned int stats_count;
+       u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
+       u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
        u8 regdomain;
        u8 default_regdomain;
        u8 requested_channel;