X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fzd1211rw%2Fzd_mac.c;h=a9bd80a08613518311ec69a3a0823a9a29eb1aa6;hb=ab5cfd2aa3af40b35d7a948de8e279dc82c5b9f6;hp=3bdc54d128d0613cb5ead20e81a1b642b4f0efd4;hpb=075d6adf909ac8706bd0be7832e6dadb0aef314b;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 3bdc54d128d..a9bd80a0861 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -108,7 +108,9 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) if (r) goto disable_int; - r = zd_set_encryption_type(chip, NO_WEP); + /* We must inform the device that we are doing encryption/decryption in + * software at the moment. */ + r = zd_set_encryption_type(chip, ENC_SNIFFER); if (r) goto disable_int; @@ -136,10 +138,8 @@ static int reset_mode(struct zd_mac *mac) { struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct zd_ioreq32 ioreqs[3] = { - { CR_RX_FILTER, RX_FILTER_BEACON|RX_FILTER_PROBE_RESPONSE| - RX_FILTER_AUTH|RX_FILTER_ASSOC_RESPONSE }, + { CR_RX_FILTER, STA_RX_FILTER }, { CR_SNIFFER_ON, 0U }, - { CR_ENCRYPTION_TYPE, NO_WEP }, }; if (ieee->iw_mode == IW_MODE_MONITOR) { @@ -713,10 +713,10 @@ static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) struct zd_rt_hdr { struct ieee80211_radiotap_header rt_hdr; u8 rt_flags; + u8 rt_rate; u16 rt_channel; u16 rt_chbitmask; - u16 rt_rate; -}; +} __attribute__((packed)); static void fill_rt_header(void *buffer, struct zd_mac *mac, const struct ieee80211_rx_stats *stats, @@ -735,14 +735,14 @@ static void fill_rt_header(void *buffer, struct zd_mac *mac, if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; + hdr->rt_rate = stats->rate / 5; + /* FIXME: 802.11a */ hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( _zd_chip_get_channel(&mac->chip))); hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); - - hdr->rt_rate = stats->rate / 5; } /* Returns 1 if the data packet is for us and 0 otherwise. */ @@ -816,13 +816,25 @@ static int filter_rx(struct ieee80211_device *ieee, 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); } @@ -853,7 +865,6 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, if (stats->rate) stats->mask |= IEEE80211_STATMASK_RATE; - update_qual_rssi(mac, stats->signal, stats->rssi); return 0; } @@ -877,6 +888,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) 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; @@ -981,17 +994,31 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) { 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; }