diff options
author | David S. Miller <davem@davemloft.net> | 2008-05-15 03:52:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-05-15 03:52:37 -0400 |
commit | f42a44494bcdf03fc851c03d438464d59c0ceaf5 (patch) | |
tree | 986ea7b54e9fc79a64863fd7e92eabd99ffd37a3 | |
parent | 63fe46da9c380b3f2bbdf3765044649517cc717c (diff) | |
parent | ef85ad541f9a6ccd3f89ec73f92b2d6f45a9d3e8 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
71 files changed, 2529 insertions, 2126 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index d93a1de77eb0..7af5d8851f67 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -445,9 +445,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
445 | struct ieee80211_rx_status rx_status = {0}; | 445 | struct ieee80211_rx_status rx_status = {0}; |
446 | 446 | ||
447 | if (priv->pdev->revision < ADM8211_REV_CA) | 447 | if (priv->pdev->revision < ADM8211_REV_CA) |
448 | rx_status.ssi = rssi; | 448 | rx_status.signal = rssi; |
449 | else | 449 | else |
450 | rx_status.ssi = 100 - rssi; | 450 | rx_status.signal = 100 - rssi; |
451 | 451 | ||
452 | rx_status.rate_idx = rate; | 452 | rx_status.rate_idx = rate; |
453 | 453 | ||
@@ -1893,9 +1893,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1893 | 1893 | ||
1894 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); | 1894 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); |
1895 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ | 1895 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ |
1896 | dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; | ||
1896 | 1897 | ||
1897 | dev->channel_change_time = 1000; | 1898 | dev->channel_change_time = 1000; |
1898 | dev->max_rssi = 100; /* FIXME: find better value */ | 1899 | dev->max_signal = 100; /* FIXME: find better value */ |
1899 | 1900 | ||
1900 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ | 1901 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ |
1901 | 1902 | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 45f47c1c0a35..8a78283e8607 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -1148,7 +1148,6 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); | |||
1148 | static void airo_networks_free(struct airo_info *ai); | 1148 | static void airo_networks_free(struct airo_info *ai); |
1149 | 1149 | ||
1150 | struct airo_info { | 1150 | struct airo_info { |
1151 | struct net_device_stats stats; | ||
1152 | struct net_device *dev; | 1151 | struct net_device *dev; |
1153 | struct list_head dev_list; | 1152 | struct list_head dev_list; |
1154 | /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we | 1153 | /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we |
@@ -1924,7 +1923,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) { | |||
1924 | if (npacks >= MAXTXQ - 1) { | 1923 | if (npacks >= MAXTXQ - 1) { |
1925 | netif_stop_queue (dev); | 1924 | netif_stop_queue (dev); |
1926 | if (npacks > MAXTXQ) { | 1925 | if (npacks > MAXTXQ) { |
1927 | ai->stats.tx_fifo_errors++; | 1926 | dev->stats.tx_fifo_errors++; |
1928 | return 1; | 1927 | return 1; |
1929 | } | 1928 | } |
1930 | skb_queue_tail (&ai->txq, skb); | 1929 | skb_queue_tail (&ai->txq, skb); |
@@ -2044,13 +2043,13 @@ static void get_tx_error(struct airo_info *ai, s32 fid) | |||
2044 | bap_read(ai, &status, 2, BAP0); | 2043 | bap_read(ai, &status, 2, BAP0); |
2045 | } | 2044 | } |
2046 | if (le16_to_cpu(status) & 2) /* Too many retries */ | 2045 | if (le16_to_cpu(status) & 2) /* Too many retries */ |
2047 | ai->stats.tx_aborted_errors++; | 2046 | ai->dev->stats.tx_aborted_errors++; |
2048 | if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */ | 2047 | if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */ |
2049 | ai->stats.tx_heartbeat_errors++; | 2048 | ai->dev->stats.tx_heartbeat_errors++; |
2050 | if (le16_to_cpu(status) & 8) /* Aid fail */ | 2049 | if (le16_to_cpu(status) & 8) /* Aid fail */ |
2051 | { } | 2050 | { } |
2052 | if (le16_to_cpu(status) & 0x10) /* MAC disabled */ | 2051 | if (le16_to_cpu(status) & 0x10) /* MAC disabled */ |
2053 | ai->stats.tx_carrier_errors++; | 2052 | ai->dev->stats.tx_carrier_errors++; |
2054 | if (le16_to_cpu(status) & 0x20) /* Association lost */ | 2053 | if (le16_to_cpu(status) & 0x20) /* Association lost */ |
2055 | { } | 2054 | { } |
2056 | /* We produce a TXDROP event only for retry or lifetime | 2055 | /* We produce a TXDROP event only for retry or lifetime |
@@ -2102,7 +2101,7 @@ static void airo_end_xmit(struct net_device *dev) { | |||
2102 | for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++); | 2101 | for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++); |
2103 | } else { | 2102 | } else { |
2104 | priv->fids[fid] &= 0xffff; | 2103 | priv->fids[fid] &= 0xffff; |
2105 | priv->stats.tx_window_errors++; | 2104 | dev->stats.tx_window_errors++; |
2106 | } | 2105 | } |
2107 | if (i < MAX_FIDS / 2) | 2106 | if (i < MAX_FIDS / 2) |
2108 | netif_wake_queue(dev); | 2107 | netif_wake_queue(dev); |
@@ -2128,7 +2127,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { | |||
2128 | netif_stop_queue(dev); | 2127 | netif_stop_queue(dev); |
2129 | 2128 | ||
2130 | if (i == MAX_FIDS / 2) { | 2129 | if (i == MAX_FIDS / 2) { |
2131 | priv->stats.tx_fifo_errors++; | 2130 | dev->stats.tx_fifo_errors++; |
2132 | return 1; | 2131 | return 1; |
2133 | } | 2132 | } |
2134 | } | 2133 | } |
@@ -2167,7 +2166,7 @@ static void airo_end_xmit11(struct net_device *dev) { | |||
2167 | for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++); | 2166 | for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++); |
2168 | } else { | 2167 | } else { |
2169 | priv->fids[fid] &= 0xffff; | 2168 | priv->fids[fid] &= 0xffff; |
2170 | priv->stats.tx_window_errors++; | 2169 | dev->stats.tx_window_errors++; |
2171 | } | 2170 | } |
2172 | if (i < MAX_FIDS) | 2171 | if (i < MAX_FIDS) |
2173 | netif_wake_queue(dev); | 2172 | netif_wake_queue(dev); |
@@ -2199,7 +2198,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { | |||
2199 | netif_stop_queue(dev); | 2198 | netif_stop_queue(dev); |
2200 | 2199 | ||
2201 | if (i == MAX_FIDS) { | 2200 | if (i == MAX_FIDS) { |
2202 | priv->stats.tx_fifo_errors++; | 2201 | dev->stats.tx_fifo_errors++; |
2203 | return 1; | 2202 | return 1; |
2204 | } | 2203 | } |
2205 | } | 2204 | } |
@@ -2219,8 +2218,9 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { | |||
2219 | return 0; | 2218 | return 0; |
2220 | } | 2219 | } |
2221 | 2220 | ||
2222 | static void airo_read_stats(struct airo_info *ai) | 2221 | static void airo_read_stats(struct net_device *dev) |
2223 | { | 2222 | { |
2223 | struct airo_info *ai = dev->priv; | ||
2224 | StatsRid stats_rid; | 2224 | StatsRid stats_rid; |
2225 | __le32 *vals = stats_rid.vals; | 2225 | __le32 *vals = stats_rid.vals; |
2226 | 2226 | ||
@@ -2232,23 +2232,24 @@ static void airo_read_stats(struct airo_info *ai) | |||
2232 | readStatsRid(ai, &stats_rid, RID_STATS, 0); | 2232 | readStatsRid(ai, &stats_rid, RID_STATS, 0); |
2233 | up(&ai->sem); | 2233 | up(&ai->sem); |
2234 | 2234 | ||
2235 | ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) + | 2235 | dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) + |
2236 | le32_to_cpu(vals[45]); | 2236 | le32_to_cpu(vals[45]); |
2237 | ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) + | 2237 | dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) + |
2238 | le32_to_cpu(vals[41]); | 2238 | le32_to_cpu(vals[41]); |
2239 | ai->stats.rx_bytes = le32_to_cpu(vals[92]); | 2239 | dev->stats.rx_bytes = le32_to_cpu(vals[92]); |
2240 | ai->stats.tx_bytes = le32_to_cpu(vals[91]); | 2240 | dev->stats.tx_bytes = le32_to_cpu(vals[91]); |
2241 | ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) + | 2241 | dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) + |
2242 | le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]); | 2242 | le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]); |
2243 | ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors; | 2243 | dev->stats.tx_errors = le32_to_cpu(vals[42]) + |
2244 | ai->stats.multicast = le32_to_cpu(vals[43]); | 2244 | dev->stats.tx_fifo_errors; |
2245 | ai->stats.collisions = le32_to_cpu(vals[89]); | 2245 | dev->stats.multicast = le32_to_cpu(vals[43]); |
2246 | dev->stats.collisions = le32_to_cpu(vals[89]); | ||
2246 | 2247 | ||
2247 | /* detailed rx_errors: */ | 2248 | /* detailed rx_errors: */ |
2248 | ai->stats.rx_length_errors = le32_to_cpu(vals[3]); | 2249 | dev->stats.rx_length_errors = le32_to_cpu(vals[3]); |
2249 | ai->stats.rx_crc_errors = le32_to_cpu(vals[4]); | 2250 | dev->stats.rx_crc_errors = le32_to_cpu(vals[4]); |
2250 | ai->stats.rx_frame_errors = le32_to_cpu(vals[2]); | 2251 | dev->stats.rx_frame_errors = le32_to_cpu(vals[2]); |
2251 | ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]); | 2252 | dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]); |
2252 | } | 2253 | } |
2253 | 2254 | ||
2254 | static struct net_device_stats *airo_get_stats(struct net_device *dev) | 2255 | static struct net_device_stats *airo_get_stats(struct net_device *dev) |
@@ -2261,10 +2262,10 @@ static struct net_device_stats *airo_get_stats(struct net_device *dev) | |||
2261 | set_bit(JOB_STATS, &local->jobs); | 2262 | set_bit(JOB_STATS, &local->jobs); |
2262 | wake_up_interruptible(&local->thr_wait); | 2263 | wake_up_interruptible(&local->thr_wait); |
2263 | } else | 2264 | } else |
2264 | airo_read_stats(local); | 2265 | airo_read_stats(dev); |
2265 | } | 2266 | } |
2266 | 2267 | ||
2267 | return &local->stats; | 2268 | return &dev->stats; |
2268 | } | 2269 | } |
2269 | 2270 | ||
2270 | static void airo_set_promisc(struct airo_info *ai) { | 2271 | static void airo_set_promisc(struct airo_info *ai) { |
@@ -3092,7 +3093,7 @@ static int airo_thread(void *data) { | |||
3092 | else if (test_bit(JOB_XMIT11, &ai->jobs)) | 3093 | else if (test_bit(JOB_XMIT11, &ai->jobs)) |
3093 | airo_end_xmit11(dev); | 3094 | airo_end_xmit11(dev); |
3094 | else if (test_bit(JOB_STATS, &ai->jobs)) | 3095 | else if (test_bit(JOB_STATS, &ai->jobs)) |
3095 | airo_read_stats(ai); | 3096 | airo_read_stats(dev); |
3096 | else if (test_bit(JOB_WSTATS, &ai->jobs)) | 3097 | else if (test_bit(JOB_WSTATS, &ai->jobs)) |
3097 | airo_read_wireless_stats(ai); | 3098 | airo_read_wireless_stats(ai); |
3098 | else if (test_bit(JOB_PROMISC, &ai->jobs)) | 3099 | else if (test_bit(JOB_PROMISC, &ai->jobs)) |
@@ -3288,7 +3289,7 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id) | |||
3288 | 3289 | ||
3289 | skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); | 3290 | skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); |
3290 | if ( !skb ) { | 3291 | if ( !skb ) { |
3291 | apriv->stats.rx_dropped++; | 3292 | dev->stats.rx_dropped++; |
3292 | goto badrx; | 3293 | goto badrx; |
3293 | } | 3294 | } |
3294 | skb_reserve(skb, 2); /* This way the IP header is aligned */ | 3295 | skb_reserve(skb, 2); /* This way the IP header is aligned */ |
@@ -3556,7 +3557,7 @@ static void mpi_receive_802_3(struct airo_info *ai) | |||
3556 | 3557 | ||
3557 | skb = dev_alloc_skb(len); | 3558 | skb = dev_alloc_skb(len); |
3558 | if (!skb) { | 3559 | if (!skb) { |
3559 | ai->stats.rx_dropped++; | 3560 | ai->dev->stats.rx_dropped++; |
3560 | goto badrx; | 3561 | goto badrx; |
3561 | } | 3562 | } |
3562 | buffer = skb_put(skb,len); | 3563 | buffer = skb_put(skb,len); |
@@ -3649,7 +3650,7 @@ void mpi_receive_802_11 (struct airo_info *ai) | |||
3649 | 3650 | ||
3650 | skb = dev_alloc_skb( len + hdrlen + 2 ); | 3651 | skb = dev_alloc_skb( len + hdrlen + 2 ); |
3651 | if ( !skb ) { | 3652 | if ( !skb ) { |
3652 | ai->stats.rx_dropped++; | 3653 | ai->dev->stats.rx_dropped++; |
3653 | goto badrx; | 3654 | goto badrx; |
3654 | } | 3655 | } |
3655 | buffer = (u16*)skb_put (skb, len + hdrlen); | 3656 | buffer = (u16*)skb_put (skb, len + hdrlen); |
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index dbdfc9e39d20..dec5e874a54d 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c | |||
@@ -125,7 +125,7 @@ static inline int arlan_drop_tx(struct net_device *dev) | |||
125 | { | 125 | { |
126 | struct arlan_private *priv = netdev_priv(dev); | 126 | struct arlan_private *priv = netdev_priv(dev); |
127 | 127 | ||
128 | priv->stats.tx_errors++; | 128 | dev->stats.tx_errors++; |
129 | if (priv->Conf->tx_delay_ms) | 129 | if (priv->Conf->tx_delay_ms) |
130 | { | 130 | { |
131 | priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1; | 131 | priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1; |
@@ -1269,7 +1269,7 @@ static void arlan_tx_done_interrupt(struct net_device *dev, int status) | |||
1269 | { | 1269 | { |
1270 | IFDEBUG(ARLAN_DEBUG_TX_CHAIN) | 1270 | IFDEBUG(ARLAN_DEBUG_TX_CHAIN) |
1271 | printk("arlan intr: transmit OK\n"); | 1271 | printk("arlan intr: transmit OK\n"); |
1272 | priv->stats.tx_packets++; | 1272 | dev->stats.tx_packets++; |
1273 | priv->bad = 0; | 1273 | priv->bad = 0; |
1274 | priv->reset = 0; | 1274 | priv->reset = 0; |
1275 | priv->retransmissions = 0; | 1275 | priv->retransmissions = 0; |
@@ -1496,7 +1496,7 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short | |||
1496 | if (skb == NULL) | 1496 | if (skb == NULL) |
1497 | { | 1497 | { |
1498 | printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); | 1498 | printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); |
1499 | priv->stats.rx_dropped++; | 1499 | dev->stats.rx_dropped++; |
1500 | break; | 1500 | break; |
1501 | } | 1501 | } |
1502 | skb_reserve(skb, 2); | 1502 | skb_reserve(skb, 2); |
@@ -1536,14 +1536,14 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short | |||
1536 | } | 1536 | } |
1537 | netif_rx(skb); | 1537 | netif_rx(skb); |
1538 | dev->last_rx = jiffies; | 1538 | dev->last_rx = jiffies; |
1539 | priv->stats.rx_packets++; | 1539 | dev->stats.rx_packets++; |
1540 | priv->stats.rx_bytes += pkt_len; | 1540 | dev->stats.rx_bytes += pkt_len; |
1541 | } | 1541 | } |
1542 | break; | 1542 | break; |
1543 | 1543 | ||
1544 | default: | 1544 | default: |
1545 | printk(KERN_ERR "arlan intr: received unknown status\n"); | 1545 | printk(KERN_ERR "arlan intr: received unknown status\n"); |
1546 | priv->stats.rx_crc_errors++; | 1546 | dev->stats.rx_crc_errors++; |
1547 | break; | 1547 | break; |
1548 | } | 1548 | } |
1549 | ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); | 1549 | ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); |
@@ -1719,23 +1719,23 @@ static struct net_device_stats *arlan_statistics(struct net_device *dev) | |||
1719 | 1719 | ||
1720 | /* Update the statistics from the device registers. */ | 1720 | /* Update the statistics from the device registers. */ |
1721 | 1721 | ||
1722 | READSHM(priv->stats.collisions, arlan->numReTransmissions, u_int); | 1722 | READSHM(dev->stats.collisions, arlan->numReTransmissions, u_int); |
1723 | READSHM(priv->stats.rx_crc_errors, arlan->numCRCErrors, u_int); | 1723 | READSHM(dev->stats.rx_crc_errors, arlan->numCRCErrors, u_int); |
1724 | READSHM(priv->stats.rx_dropped, arlan->numFramesDiscarded, u_int); | 1724 | READSHM(dev->stats.rx_dropped, arlan->numFramesDiscarded, u_int); |
1725 | READSHM(priv->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int); | 1725 | READSHM(dev->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int); |
1726 | READSHM(priv->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int); | 1726 | READSHM(dev->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int); |
1727 | READSHM(priv->stats.rx_over_errors, arlan->numRXOverruns, u_int); | 1727 | READSHM(dev->stats.rx_over_errors, arlan->numRXOverruns, u_int); |
1728 | READSHM(priv->stats.rx_packets, arlan->numDatagramsReceived, u_int); | 1728 | READSHM(dev->stats.rx_packets, arlan->numDatagramsReceived, u_int); |
1729 | READSHM(priv->stats.tx_aborted_errors, arlan->numAbortErrors, u_int); | 1729 | READSHM(dev->stats.tx_aborted_errors, arlan->numAbortErrors, u_int); |
1730 | READSHM(priv->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int); | 1730 | READSHM(dev->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int); |
1731 | READSHM(priv->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int); | 1731 | READSHM(dev->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int); |
1732 | READSHM(priv->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int); | 1732 | READSHM(dev->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int); |
1733 | READSHM(priv->stats.tx_packets, arlan->numDatagramsTransmitted, u_int); | 1733 | READSHM(dev->stats.tx_packets, arlan->numDatagramsTransmitted, u_int); |
1734 | READSHM(priv->stats.tx_window_errors, arlan->numHoldOffs, u_int); | 1734 | READSHM(dev->stats.tx_window_errors, arlan->numHoldOffs, u_int); |
1735 | 1735 | ||
1736 | ARLAN_DEBUG_EXIT("arlan_statistics"); | 1736 | ARLAN_DEBUG_EXIT("arlan_statistics"); |
1737 | 1737 | ||
1738 | return &priv->stats; | 1738 | return &dev->stats; |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | 1741 | ||
diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h index 3ed1df75900f..fb3ad51a1caf 100644 --- a/drivers/net/wireless/arlan.h +++ b/drivers/net/wireless/arlan.h | |||
@@ -330,7 +330,6 @@ struct TxParam | |||
330 | #define TX_RING_SIZE 2 | 330 | #define TX_RING_SIZE 2 |
331 | /* Information that need to be kept for each board. */ | 331 | /* Information that need to be kept for each board. */ |
332 | struct arlan_private { | 332 | struct arlan_private { |
333 | struct net_device_stats stats; | ||
334 | struct arlan_shmem __iomem * card; | 333 | struct arlan_shmem __iomem * card; |
335 | struct arlan_shmem * conf; | 334 | struct arlan_shmem * conf; |
336 | 335 | ||
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 3201c1604340..c76ada178781 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -458,13 +458,11 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
458 | 458 | ||
459 | /* Initialize driver private data */ | 459 | /* Initialize driver private data */ |
460 | SET_IEEE80211_DEV(hw, &pdev->dev); | 460 | SET_IEEE80211_DEV(hw, &pdev->dev); |
461 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; | 461 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
462 | IEEE80211_HW_SIGNAL_DBM | | ||
463 | IEEE80211_HW_NOISE_DBM; | ||
462 | hw->extra_tx_headroom = 2; | 464 | hw->extra_tx_headroom = 2; |
463 | hw->channel_change_time = 5000; | 465 | hw->channel_change_time = 5000; |
464 | /* these names are misleading */ | ||
465 | hw->max_rssi = -110; /* signal in dBm */ | ||
466 | hw->max_noise = -110; /* noise in dBm */ | ||
467 | hw->max_signal = 100; /* we will provide a percentage based on rssi */ | ||
468 | sc = hw->priv; | 466 | sc = hw->priv; |
469 | sc->hw = hw; | 467 | sc->hw = hw; |
470 | sc->pdev = pdev; | 468 | sc->pdev = pdev; |
@@ -1787,6 +1785,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1787 | 1785 | ||
1788 | spin_lock(&sc->rxbuflock); | 1786 | spin_lock(&sc->rxbuflock); |
1789 | do { | 1787 | do { |
1788 | rxs.flag = 0; | ||
1789 | |||
1790 | if (unlikely(list_empty(&sc->rxbuf))) { | 1790 | if (unlikely(list_empty(&sc->rxbuf))) { |
1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); | 1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); |
1792 | break; | 1792 | break; |
@@ -1893,20 +1893,9 @@ accept: | |||
1893 | rxs.freq = sc->curchan->center_freq; | 1893 | rxs.freq = sc->curchan->center_freq; |
1894 | rxs.band = sc->curband->band; | 1894 | rxs.band = sc->curband->band; |
1895 | 1895 | ||
1896 | /* | ||
1897 | * signal quality: | ||
1898 | * the names here are misleading and the usage of these | ||
1899 | * values by iwconfig makes it even worse | ||
1900 | */ | ||
1901 | /* noise floor in dBm, from the last noise calibration */ | ||
1902 | rxs.noise = sc->ah->ah_noise_floor; | 1896 | rxs.noise = sc->ah->ah_noise_floor; |
1903 | /* signal level in dBm */ | 1897 | rxs.signal = rxs.noise + rs.rs_rssi; |
1904 | rxs.ssi = rxs.noise + rs.rs_rssi; | 1898 | rxs.qual = rs.rs_rssi * 100 / 64; |
1905 | /* | ||
1906 | * "signal" is actually displayed as Link Quality by iwconfig | ||
1907 | * we provide a percentage based on rssi (assuming max rssi 64) | ||
1908 | */ | ||
1909 | rxs.signal = rs.rs_rssi * 100 / 64; | ||
1910 | 1899 | ||
1911 | rxs.antenna = rs.rs_antenna; | 1900 | rxs.antenna = rs.rs_antenna; |
1912 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1901 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 5fb1ae6ad3e2..77990b56860b 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -4119,6 +4119,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4121 | rs->rs_status = 0; | 4121 | rs->rs_status = 0; |
4122 | rs->rs_phyerr = 0; | ||
4122 | 4123 | ||
4123 | /* | 4124 | /* |
4124 | * Key table status | 4125 | * Key table status |
@@ -4145,7 +4146,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4145 | if (rx_status->rx_status_1 & | 4146 | if (rx_status->rx_status_1 & |
4146 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { | 4147 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { |
4147 | rs->rs_status |= AR5K_RXERR_PHY; | 4148 | rs->rs_status |= AR5K_RXERR_PHY; |
4148 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 4149 | rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, |
4149 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); | 4150 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); |
4150 | } | 4151 | } |
4151 | 4152 | ||
@@ -4193,6 +4194,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4193 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4194 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4194 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4195 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4195 | rs->rs_status = 0; | 4196 | rs->rs_status = 0; |
4197 | rs->rs_phyerr = 0; | ||
4196 | 4198 | ||
4197 | /* | 4199 | /* |
4198 | * Key table status | 4200 | * Key table status |
@@ -4215,7 +4217,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4215 | if (rx_status->rx_status_1 & | 4217 | if (rx_status->rx_status_1 & |
4216 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | 4218 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
4217 | rs->rs_status |= AR5K_RXERR_PHY; | 4219 | rs->rs_status |= AR5K_RXERR_PHY; |
4218 | rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, | 4220 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, |
4219 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | 4221 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); |
4220 | } | 4222 | } |
4221 | 4223 | ||
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index ef2da4023d68..f978a9d5190b 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -433,7 +433,6 @@ struct atmel_private { | |||
433 | struct net_device *dev; | 433 | struct net_device *dev; |
434 | struct device *sys_dev; | 434 | struct device *sys_dev; |
435 | struct iw_statistics wstats; | 435 | struct iw_statistics wstats; |
436 | struct net_device_stats stats; // device stats | ||
437 | spinlock_t irqlock, timerlock; // spinlocks | 436 | spinlock_t irqlock, timerlock; // spinlocks |
438 | enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type; | 437 | enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type; |
439 | enum { | 438 | enum { |
@@ -694,9 +693,9 @@ static void tx_done_irq(struct atmel_private *priv) | |||
694 | 693 | ||
695 | if (type == TX_PACKET_TYPE_DATA) { | 694 | if (type == TX_PACKET_TYPE_DATA) { |
696 | if (status == TX_STATUS_SUCCESS) | 695 | if (status == TX_STATUS_SUCCESS) |
697 | priv->stats.tx_packets++; | 696 | priv->dev->stats.tx_packets++; |
698 | else | 697 | else |
699 | priv->stats.tx_errors++; | 698 | priv->dev->stats.tx_errors++; |
700 | netif_wake_queue(priv->dev); | 699 | netif_wake_queue(priv->dev); |
701 | } | 700 | } |
702 | } | 701 | } |
@@ -792,13 +791,13 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) | |||
792 | 791 | ||
793 | if (priv->card && priv->present_callback && | 792 | if (priv->card && priv->present_callback && |
794 | !(*priv->present_callback)(priv->card)) { | 793 | !(*priv->present_callback)(priv->card)) { |
795 | priv->stats.tx_errors++; | 794 | dev->stats.tx_errors++; |
796 | dev_kfree_skb(skb); | 795 | dev_kfree_skb(skb); |
797 | return 0; | 796 | return 0; |
798 | } | 797 | } |
799 | 798 | ||
800 | if (priv->station_state != STATION_STATE_READY) { | 799 | if (priv->station_state != STATION_STATE_READY) { |
801 | priv->stats.tx_errors++; | 800 | dev->stats.tx_errors++; |
802 | dev_kfree_skb(skb); | 801 | dev_kfree_skb(skb); |
803 | return 0; | 802 | return 0; |
804 | } | 803 | } |
@@ -815,7 +814,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) | |||
815 | initial + 18 (+30-12) */ | 814 | initial + 18 (+30-12) */ |
816 | 815 | ||
817 | if (!(buff = find_tx_buff(priv, len + 18))) { | 816 | if (!(buff = find_tx_buff(priv, len + 18))) { |
818 | priv->stats.tx_dropped++; | 817 | dev->stats.tx_dropped++; |
819 | spin_unlock_irqrestore(&priv->irqlock, flags); | 818 | spin_unlock_irqrestore(&priv->irqlock, flags); |
820 | spin_unlock_bh(&priv->timerlock); | 819 | spin_unlock_bh(&priv->timerlock); |
821 | netif_stop_queue(dev); | 820 | netif_stop_queue(dev); |
@@ -851,7 +850,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) | |||
851 | /* low bit of first byte of destination tells us if broadcast */ | 850 | /* low bit of first byte of destination tells us if broadcast */ |
852 | tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA); | 851 | tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA); |
853 | dev->trans_start = jiffies; | 852 | dev->trans_start = jiffies; |
854 | priv->stats.tx_bytes += len; | 853 | dev->stats.tx_bytes += len; |
855 | 854 | ||
856 | spin_unlock_irqrestore(&priv->irqlock, flags); | 855 | spin_unlock_irqrestore(&priv->irqlock, flags); |
857 | spin_unlock_bh(&priv->timerlock); | 856 | spin_unlock_bh(&priv->timerlock); |
@@ -895,7 +894,7 @@ static void fast_rx_path(struct atmel_private *priv, | |||
895 | } | 894 | } |
896 | 895 | ||
897 | if (!(skb = dev_alloc_skb(msdu_size + 14))) { | 896 | if (!(skb = dev_alloc_skb(msdu_size + 14))) { |
898 | priv->stats.rx_dropped++; | 897 | priv->dev->stats.rx_dropped++; |
899 | return; | 898 | return; |
900 | } | 899 | } |
901 | 900 | ||
@@ -908,7 +907,7 @@ static void fast_rx_path(struct atmel_private *priv, | |||
908 | crc = crc32_le(crc, skbp + 12, msdu_size); | 907 | crc = crc32_le(crc, skbp + 12, msdu_size); |
909 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4); | 908 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4); |
910 | if ((crc ^ 0xffffffff) != netcrc) { | 909 | if ((crc ^ 0xffffffff) != netcrc) { |
911 | priv->stats.rx_crc_errors++; | 910 | priv->dev->stats.rx_crc_errors++; |
912 | dev_kfree_skb(skb); | 911 | dev_kfree_skb(skb); |
913 | return; | 912 | return; |
914 | } | 913 | } |
@@ -924,8 +923,8 @@ static void fast_rx_path(struct atmel_private *priv, | |||
924 | skb->protocol = eth_type_trans(skb, priv->dev); | 923 | skb->protocol = eth_type_trans(skb, priv->dev); |
925 | skb->ip_summed = CHECKSUM_NONE; | 924 | skb->ip_summed = CHECKSUM_NONE; |
926 | netif_rx(skb); | 925 | netif_rx(skb); |
927 | priv->stats.rx_bytes += 12 + msdu_size; | 926 | priv->dev->stats.rx_bytes += 12 + msdu_size; |
928 | priv->stats.rx_packets++; | 927 | priv->dev->stats.rx_packets++; |
929 | } | 928 | } |
930 | 929 | ||
931 | /* Test to see if the packet in card memory at packet_loc has a valid CRC | 930 | /* Test to see if the packet in card memory at packet_loc has a valid CRC |
@@ -991,7 +990,7 @@ static void frag_rx_path(struct atmel_private *priv, | |||
991 | crc = crc32_le(crc, &priv->rx_buf[12], msdu_size); | 990 | crc = crc32_le(crc, &priv->rx_buf[12], msdu_size); |
992 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); | 991 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); |
993 | if ((crc ^ 0xffffffff) != netcrc) { | 992 | if ((crc ^ 0xffffffff) != netcrc) { |
994 | priv->stats.rx_crc_errors++; | 993 | priv->dev->stats.rx_crc_errors++; |
995 | memset(priv->frag_source, 0xff, 6); | 994 | memset(priv->frag_source, 0xff, 6); |
996 | } | 995 | } |
997 | } | 996 | } |
@@ -1009,7 +1008,7 @@ static void frag_rx_path(struct atmel_private *priv, | |||
1009 | msdu_size); | 1008 | msdu_size); |
1010 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); | 1009 | atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); |
1011 | if ((crc ^ 0xffffffff) != netcrc) { | 1010 | if ((crc ^ 0xffffffff) != netcrc) { |
1012 | priv->stats.rx_crc_errors++; | 1011 | priv->dev->stats.rx_crc_errors++; |
1013 | memset(priv->frag_source, 0xff, 6); | 1012 | memset(priv->frag_source, 0xff, 6); |
1014 | more_frags = 1; /* don't send broken assembly */ | 1013 | more_frags = 1; /* don't send broken assembly */ |
1015 | } | 1014 | } |
@@ -1021,7 +1020,7 @@ static void frag_rx_path(struct atmel_private *priv, | |||
1021 | if (!more_frags) { /* last one */ | 1020 | if (!more_frags) { /* last one */ |
1022 | memset(priv->frag_source, 0xff, 6); | 1021 | memset(priv->frag_source, 0xff, 6); |
1023 | if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { | 1022 | if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { |
1024 | priv->stats.rx_dropped++; | 1023 | priv->dev->stats.rx_dropped++; |
1025 | } else { | 1024 | } else { |
1026 | skb_reserve(skb, 2); | 1025 | skb_reserve(skb, 2); |
1027 | memcpy(skb_put(skb, priv->frag_len + 12), | 1026 | memcpy(skb_put(skb, priv->frag_len + 12), |
@@ -1031,8 +1030,8 @@ static void frag_rx_path(struct atmel_private *priv, | |||
1031 | skb->protocol = eth_type_trans(skb, priv->dev); | 1030 | skb->protocol = eth_type_trans(skb, priv->dev); |
1032 | skb->ip_summed = CHECKSUM_NONE; | 1031 | skb->ip_summed = CHECKSUM_NONE; |
1033 | netif_rx(skb); | 1032 | netif_rx(skb); |
1034 | priv->stats.rx_bytes += priv->frag_len + 12; | 1033 | priv->dev->stats.rx_bytes += priv->frag_len + 12; |
1035 | priv->stats.rx_packets++; | 1034 | priv->dev->stats.rx_packets++; |
1036 | } | 1035 | } |
1037 | } | 1036 | } |
1038 | } else | 1037 | } else |
@@ -1057,7 +1056,7 @@ static void rx_done_irq(struct atmel_private *priv) | |||
1057 | if (status == 0xc1) /* determined by experiment */ | 1056 | if (status == 0xc1) /* determined by experiment */ |
1058 | priv->wstats.discard.nwid++; | 1057 | priv->wstats.discard.nwid++; |
1059 | else | 1058 | else |
1060 | priv->stats.rx_errors++; | 1059 | priv->dev->stats.rx_errors++; |
1061 | goto next; | 1060 | goto next; |
1062 | } | 1061 | } |
1063 | 1062 | ||
@@ -1065,7 +1064,7 @@ static void rx_done_irq(struct atmel_private *priv) | |||
1065 | rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head)); | 1064 | rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head)); |
1066 | 1065 | ||
1067 | if (msdu_size < 30) { | 1066 | if (msdu_size < 30) { |
1068 | priv->stats.rx_errors++; | 1067 | priv->dev->stats.rx_errors++; |
1069 | goto next; | 1068 | goto next; |
1070 | } | 1069 | } |
1071 | 1070 | ||
@@ -1123,7 +1122,7 @@ static void rx_done_irq(struct atmel_private *priv) | |||
1123 | msdu_size -= 4; | 1122 | msdu_size -= 4; |
1124 | crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size); | 1123 | crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size); |
1125 | if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) { | 1124 | if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) { |
1126 | priv->stats.rx_crc_errors++; | 1125 | priv->dev->stats.rx_crc_errors++; |
1127 | goto next; | 1126 | goto next; |
1128 | } | 1127 | } |
1129 | } | 1128 | } |
@@ -1250,12 +1249,6 @@ static irqreturn_t service_interrupt(int irq, void *dev_id) | |||
1250 | } | 1249 | } |
1251 | } | 1250 | } |
1252 | 1251 | ||
1253 | static struct net_device_stats *atmel_get_stats(struct net_device *dev) | ||
1254 | { | ||
1255 | struct atmel_private *priv = netdev_priv(dev); | ||
1256 | return &priv->stats; | ||
1257 | } | ||
1258 | |||
1259 | static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev) | 1252 | static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev) |
1260 | { | 1253 | { |
1261 | struct atmel_private *priv = netdev_priv(dev); | 1254 | struct atmel_private *priv = netdev_priv(dev); |
@@ -1518,8 +1511,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, | |||
1518 | priv->crc_ok_cnt = priv->crc_ko_cnt = 0; | 1511 | priv->crc_ok_cnt = priv->crc_ko_cnt = 0; |
1519 | } else | 1512 | } else |
1520 | priv->probe_crc = 0; | 1513 | priv->probe_crc = 0; |
1521 | memset(&priv->stats, 0, sizeof(priv->stats)); | ||
1522 | memset(&priv->wstats, 0, sizeof(priv->wstats)); | ||
1523 | priv->last_qual = jiffies; | 1514 | priv->last_qual = jiffies; |
1524 | priv->last_beacon_timestamp = 0; | 1515 | priv->last_beacon_timestamp = 0; |
1525 | memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); | 1516 | memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); |
@@ -1568,7 +1559,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, | |||
1568 | dev->change_mtu = atmel_change_mtu; | 1559 | dev->change_mtu = atmel_change_mtu; |
1569 | dev->set_mac_address = atmel_set_mac_address; | 1560 | dev->set_mac_address = atmel_set_mac_address; |
1570 | dev->hard_start_xmit = start_tx; | 1561 | dev->hard_start_xmit = start_tx; |
1571 | dev->get_stats = atmel_get_stats; | ||
1572 | dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; | 1562 | dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; |
1573 | dev->do_ioctl = atmel_ioctl; | 1563 | dev->do_ioctl = atmel_ioctl; |
1574 | dev->irq = irq; | 1564 | dev->irq = irq; |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7d034df250bd..0c2bc061e8f3 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -939,22 +939,6 @@ static inline bool __b43_warn_on_dummy(bool x) { return x; } | |||
939 | # define B43_WARN_ON(x) __b43_warn_on_dummy(unlikely(!!(x))) | 939 | # define B43_WARN_ON(x) __b43_warn_on_dummy(unlikely(!!(x))) |
940 | #endif | 940 | #endif |
941 | 941 | ||
942 | /** Limit a value between two limits */ | ||
943 | #ifdef limit_value | ||
944 | # undef limit_value | ||
945 | #endif | ||
946 | #define limit_value(value, min, max) \ | ||
947 | ({ \ | ||
948 | typeof(value) __value = (value); \ | ||
949 | typeof(value) __min = (min); \ | ||
950 | typeof(value) __max = (max); \ | ||
951 | if (__value < __min) \ | ||
952 | __value = __min; \ | ||
953 | else if (__value > __max) \ | ||
954 | __value = __max; \ | ||
955 | __value; \ | ||
956 | }) | ||
957 | |||
958 | /* Convert an integer to a Q5.2 value */ | 942 | /* Convert an integer to a Q5.2 value */ |
959 | #define INT_TO_Q52(i) ((i) << 2) | 943 | #define INT_TO_Q52(i) ((i) << 2) |
960 | /* Convert a Q5.2 value to an integer (precision loss!) */ | 944 | /* Convert a Q5.2 value to an integer (precision loss!) */ |
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 4ce1e3561205..9c854d6aae36 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c | |||
@@ -199,7 +199,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev) | |||
199 | if (lb_gain > 10) { | 199 | if (lb_gain > 10) { |
200 | radio_pctl_reg = 0; | 200 | radio_pctl_reg = 0; |
201 | pga = abs(10 - lb_gain) / 6; | 201 | pga = abs(10 - lb_gain) / 6; |
202 | pga = limit_value(pga, 0, 15); | 202 | pga = clamp_val(pga, 0, 15); |
203 | } else { | 203 | } else { |
204 | int cmp_val; | 204 | int cmp_val; |
205 | int tmp; | 205 | int tmp; |
@@ -321,7 +321,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev, | |||
321 | phy->lna_lod_gain = 1; | 321 | phy->lna_lod_gain = 1; |
322 | trsw_rx_gain -= 8; | 322 | trsw_rx_gain -= 8; |
323 | } | 323 | } |
324 | trsw_rx_gain = limit_value(trsw_rx_gain, 0, 0x2D); | 324 | trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D); |
325 | phy->pga_gain = trsw_rx_gain / 3; | 325 | phy->pga_gain = trsw_rx_gain / 3; |
326 | if (phy->pga_gain >= 5) { | 326 | if (phy->pga_gain >= 5) { |
327 | phy->pga_gain -= 5; | 327 | phy->pga_gain -= 5; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c6e79a15d3cb..fc23ba5309bd 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1182,10 +1182,10 @@ static void handle_irq_noise(struct b43_wldev *dev) | |||
1182 | /* Get the noise samples. */ | 1182 | /* Get the noise samples. */ |
1183 | B43_WARN_ON(dev->noisecalc.nr_samples >= 8); | 1183 | B43_WARN_ON(dev->noisecalc.nr_samples >= 8); |
1184 | i = dev->noisecalc.nr_samples; | 1184 | i = dev->noisecalc.nr_samples; |
1185 | noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 1185 | noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
1186 | noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 1186 | noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
1187 | noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 1187 | noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
1188 | noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 1188 | noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
1189 | dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; | 1189 | dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; |
1190 | dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; | 1190 | dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; |
1191 | dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; | 1191 | dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; |
@@ -4466,10 +4466,10 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4466 | 4466 | ||
4467 | /* fill hw info */ | 4467 | /* fill hw info */ |
4468 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 4468 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
4469 | IEEE80211_HW_RX_INCLUDES_FCS; | 4469 | IEEE80211_HW_RX_INCLUDES_FCS | |
4470 | hw->max_signal = 100; | 4470 | IEEE80211_HW_SIGNAL_DBM | |
4471 | hw->max_rssi = -110; | 4471 | IEEE80211_HW_NOISE_DBM; |
4472 | hw->max_noise = -110; | 4472 | |
4473 | hw->queues = b43_modparam_qos ? 4 : 1; | 4473 | hw->queues = b43_modparam_qos ? 4 : 1; |
4474 | SET_IEEE80211_DEV(hw, dev->dev); | 4474 | SET_IEEE80211_DEV(hw, dev->dev); |
4475 | if (is_valid_ether_addr(sprom->et1mac)) | 4475 | if (is_valid_ether_addr(sprom->et1mac)) |
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c index 8695eb223476..644eed993bea 100644 --- a/drivers/net/wireless/b43/nphy.c +++ b/drivers/net/wireless/b43/nphy.c | |||
@@ -29,8 +29,6 @@ | |||
29 | #include "nphy.h" | 29 | #include "nphy.h" |
30 | #include "tables_nphy.h" | 30 | #include "tables_nphy.h" |
31 | 31 | ||
32 | #include <linux/delay.h> | ||
33 | |||
34 | 32 | ||
35 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 33 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) |
36 | {//TODO | 34 | {//TODO |
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 8b3c24da8db9..305d4cd6fd03 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/bitrev.h> | ||
31 | 32 | ||
32 | #include "b43.h" | 33 | #include "b43.h" |
33 | #include "phy.h" | 34 | #include "phy.h" |
@@ -83,25 +84,9 @@ const u8 b43_radio_channel_codes_bg[] = { | |||
83 | 72, 84, | 84 | 72, 84, |
84 | }; | 85 | }; |
85 | 86 | ||
87 | #define bitrev4(tmp) (bitrev8(tmp) >> 4) | ||
86 | static void b43_phy_initg(struct b43_wldev *dev); | 88 | static void b43_phy_initg(struct b43_wldev *dev); |
87 | 89 | ||
88 | /* Reverse the bits of a 4bit value. | ||
89 | * Example: 1101 is flipped 1011 | ||
90 | */ | ||
91 | static u16 flip_4bit(u16 value) | ||
92 | { | ||
93 | u16 flipped = 0x0000; | ||
94 | |||
95 | B43_WARN_ON(value & ~0x000F); | ||
96 | |||
97 | flipped |= (value & 0x0001) << 3; | ||
98 | flipped |= (value & 0x0002) << 1; | ||
99 | flipped |= (value & 0x0004) >> 1; | ||
100 | flipped |= (value & 0x0008) >> 3; | ||
101 | |||
102 | return flipped; | ||
103 | } | ||
104 | |||
105 | static void generate_rfatt_list(struct b43_wldev *dev, | 90 | static void generate_rfatt_list(struct b43_wldev *dev, |
106 | struct b43_rfatt_list *list) | 91 | struct b43_rfatt_list *list) |
107 | { | 92 | { |
@@ -1415,7 +1400,7 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
1415 | * the value 0x7FFFFFFF here. I think that is some weird | 1400 | * the value 0x7FFFFFFF here. I think that is some weird |
1416 | * compiler optimization in the original driver. | 1401 | * compiler optimization in the original driver. |
1417 | * Essentially, what we do here is resetting all NRSSI LT | 1402 | * Essentially, what we do here is resetting all NRSSI LT |
1418 | * entries to -32 (see the limit_value() in nrssi_hw_update()) | 1403 | * entries to -32 (see the clamp_val() in nrssi_hw_update()) |
1419 | */ | 1404 | */ |
1420 | b43_nrssi_hw_update(dev, 0xFFFF); //FIXME? | 1405 | b43_nrssi_hw_update(dev, 0xFFFF); //FIXME? |
1421 | b43_calc_nrssi_threshold(dev); | 1406 | b43_calc_nrssi_threshold(dev); |
@@ -1477,13 +1462,13 @@ static s8 b43_phy_estimate_power_out(struct b43_wldev *dev, s8 tssi) | |||
1477 | switch (phy->type) { | 1462 | switch (phy->type) { |
1478 | case B43_PHYTYPE_A: | 1463 | case B43_PHYTYPE_A: |
1479 | tmp += 0x80; | 1464 | tmp += 0x80; |
1480 | tmp = limit_value(tmp, 0x00, 0xFF); | 1465 | tmp = clamp_val(tmp, 0x00, 0xFF); |
1481 | dbm = phy->tssi2dbm[tmp]; | 1466 | dbm = phy->tssi2dbm[tmp]; |
1482 | //TODO: There's a FIXME on the specs | 1467 | //TODO: There's a FIXME on the specs |
1483 | break; | 1468 | break; |
1484 | case B43_PHYTYPE_B: | 1469 | case B43_PHYTYPE_B: |
1485 | case B43_PHYTYPE_G: | 1470 | case B43_PHYTYPE_G: |
1486 | tmp = limit_value(tmp, 0x00, 0x3F); | 1471 | tmp = clamp_val(tmp, 0x00, 0x3F); |
1487 | dbm = phy->tssi2dbm[tmp]; | 1472 | dbm = phy->tssi2dbm[tmp]; |
1488 | break; | 1473 | break; |
1489 | default: | 1474 | default: |
@@ -1542,8 +1527,8 @@ void b43_put_attenuation_into_ranges(struct b43_wldev *dev, | |||
1542 | break; | 1527 | break; |
1543 | } | 1528 | } |
1544 | 1529 | ||
1545 | *_rfatt = limit_value(rfatt, rf_min, rf_max); | 1530 | *_rfatt = clamp_val(rfatt, rf_min, rf_max); |
1546 | *_bbatt = limit_value(bbatt, bb_min, bb_max); | 1531 | *_bbatt = clamp_val(bbatt, bb_min, bb_max); |
1547 | } | 1532 | } |
1548 | 1533 | ||
1549 | /* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ | 1534 | /* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ |
@@ -1638,7 +1623,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev) | |||
1638 | /* Get desired power (in Q5.2) */ | 1623 | /* Get desired power (in Q5.2) */ |
1639 | desired_pwr = INT_TO_Q52(phy->power_level); | 1624 | desired_pwr = INT_TO_Q52(phy->power_level); |
1640 | /* And limit it. max_pwr already is Q5.2 */ | 1625 | /* And limit it. max_pwr already is Q5.2 */ |
1641 | desired_pwr = limit_value(desired_pwr, 0, max_pwr); | 1626 | desired_pwr = clamp_val(desired_pwr, 0, max_pwr); |
1642 | if (b43_debug(dev, B43_DBG_XMITPOWER)) { | 1627 | if (b43_debug(dev, B43_DBG_XMITPOWER)) { |
1643 | b43dbg(dev->wl, | 1628 | b43dbg(dev->wl, |
1644 | "Current TX power output: " Q52_FMT | 1629 | "Current TX power output: " Q52_FMT |
@@ -1748,7 +1733,7 @@ static inline | |||
1748 | f = q; | 1733 | f = q; |
1749 | i++; | 1734 | i++; |
1750 | } while (delta >= 2); | 1735 | } while (delta >= 2); |
1751 | entry[index] = limit_value(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); | 1736 | entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); |
1752 | return 0; | 1737 | return 0; |
1753 | } | 1738 | } |
1754 | 1739 | ||
@@ -2274,7 +2259,7 @@ void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) | |||
2274 | for (i = 0; i < 64; i++) { | 2259 | for (i = 0; i < 64; i++) { |
2275 | tmp = b43_nrssi_hw_read(dev, i); | 2260 | tmp = b43_nrssi_hw_read(dev, i); |
2276 | tmp -= val; | 2261 | tmp -= val; |
2277 | tmp = limit_value(tmp, -32, 31); | 2262 | tmp = clamp_val(tmp, -32, 31); |
2278 | b43_nrssi_hw_write(dev, i, tmp); | 2263 | b43_nrssi_hw_write(dev, i, tmp); |
2279 | } | 2264 | } |
2280 | } | 2265 | } |
@@ -2291,7 +2276,7 @@ void b43_nrssi_mem_update(struct b43_wldev *dev) | |||
2291 | tmp = (i - delta) * phy->nrssislope; | 2276 | tmp = (i - delta) * phy->nrssislope; |
2292 | tmp /= 0x10000; | 2277 | tmp /= 0x10000; |
2293 | tmp += 0x3A; | 2278 | tmp += 0x3A; |
2294 | tmp = limit_value(tmp, 0, 0x3F); | 2279 | tmp = clamp_val(tmp, 0, 0x3F); |
2295 | phy->nrssi_lt[i] = tmp; | 2280 | phy->nrssi_lt[i] = tmp; |
2296 | } | 2281 | } |
2297 | } | 2282 | } |
@@ -2728,7 +2713,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) | |||
2728 | } else | 2713 | } else |
2729 | threshold = phy->nrssi[1] - 5; | 2714 | threshold = phy->nrssi[1] - 5; |
2730 | 2715 | ||
2731 | threshold = limit_value(threshold, 0, 0x3E); | 2716 | threshold = clamp_val(threshold, 0, 0x3E); |
2732 | b43_phy_read(dev, 0x0020); /* dummy read */ | 2717 | b43_phy_read(dev, 0x0020); /* dummy read */ |
2733 | b43_phy_write(dev, 0x0020, | 2718 | b43_phy_write(dev, 0x0020, |
2734 | (((u16) threshold) << 8) | 0x001C); | 2719 | (((u16) threshold) << 8) | 0x001C); |
@@ -2779,7 +2764,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) | |||
2779 | else | 2764 | else |
2780 | a += 32; | 2765 | a += 32; |
2781 | a = a >> 6; | 2766 | a = a >> 6; |
2782 | a = limit_value(a, -31, 31); | 2767 | a = clamp_val(a, -31, 31); |
2783 | 2768 | ||
2784 | b = b * (phy->nrssi[1] - phy->nrssi[0]); | 2769 | b = b * (phy->nrssi[1] - phy->nrssi[0]); |
2785 | b += (phy->nrssi[0] << 6); | 2770 | b += (phy->nrssi[0] << 6); |
@@ -2788,7 +2773,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) | |||
2788 | else | 2773 | else |
2789 | b += 32; | 2774 | b += 32; |
2790 | b = b >> 6; | 2775 | b = b >> 6; |
2791 | b = limit_value(b, -31, 31); | 2776 | b = clamp_val(b, -31, 31); |
2792 | 2777 | ||
2793 | tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000; | 2778 | tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000; |
2794 | tmp_u16 |= ((u32) b & 0x0000003F); | 2779 | tmp_u16 |= ((u32) b & 0x0000003F); |
@@ -2891,13 +2876,13 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode) | |||
2891 | } | 2876 | } |
2892 | radio_stacksave(0x0078); | 2877 | radio_stacksave(0x0078); |
2893 | tmp = (b43_radio_read16(dev, 0x0078) & 0x001E); | 2878 | tmp = (b43_radio_read16(dev, 0x0078) & 0x001E); |
2894 | flipped = flip_4bit(tmp); | 2879 | B43_WARN_ON(tmp > 15); |
2880 | flipped = bitrev4(tmp); | ||
2895 | if (flipped < 10 && flipped >= 8) | 2881 | if (flipped < 10 && flipped >= 8) |
2896 | flipped = 7; | 2882 | flipped = 7; |
2897 | else if (flipped >= 10) | 2883 | else if (flipped >= 10) |
2898 | flipped -= 3; | 2884 | flipped -= 3; |
2899 | flipped = flip_4bit(flipped); | 2885 | flipped = (bitrev4(flipped) << 1) | 0x0020; |
2900 | flipped = (flipped << 1) | 0x0020; | ||
2901 | b43_radio_write16(dev, 0x0078, flipped); | 2886 | b43_radio_write16(dev, 0x0078, flipped); |
2902 | 2887 | ||
2903 | b43_calc_nrssi_threshold(dev); | 2888 | b43_calc_nrssi_threshold(dev); |
@@ -3530,7 +3515,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev) | |||
3530 | tmp1 >>= 9; | 3515 | tmp1 >>= 9; |
3531 | 3516 | ||
3532 | for (i = 0; i < 16; i++) { | 3517 | for (i = 0; i < 16; i++) { |
3533 | radio78 = ((flip_4bit(i) << 1) | 0x20); | 3518 | radio78 = (bitrev4(i) << 1) | 0x0020; |
3534 | b43_radio_write16(dev, 0x78, radio78); | 3519 | b43_radio_write16(dev, 0x78, radio78); |
3535 | udelay(10); | 3520 | udelay(10); |
3536 | for (j = 0; j < 16; j++) { | 3521 | for (j = 0; j < 16; j++) { |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 88491947a209..afce9338d83a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -581,12 +581,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
581 | // and also find out what the maximum possible value is. | 581 | // and also find out what the maximum possible value is. |
582 | // Fill status.ssi and status.signal fields. | 582 | // Fill status.ssi and status.signal fields. |
583 | } else { | 583 | } else { |
584 | status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi, | 584 | status.signal = b43_rssi_postprocess(dev, rxhdr->jssi, |
585 | (phystat0 & B43_RX_PHYST0_OFDM), | 585 | (phystat0 & B43_RX_PHYST0_OFDM), |
586 | (phystat0 & B43_RX_PHYST0_GAINCTL), | 586 | (phystat0 & B43_RX_PHYST0_GAINCTL), |
587 | (phystat3 & B43_RX_PHYST3_TRSTATE)); | 587 | (phystat3 & B43_RX_PHYST3_TRSTATE)); |
588 | /* the next line looks wrong, but is what mac80211 wants */ | 588 | status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI; |
589 | status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI; | ||
590 | } | 589 | } |
591 | 590 | ||
592 | if (phystat0 & B43_RX_PHYST0_OFDM) | 591 | if (phystat0 & B43_RX_PHYST0_OFDM) |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index ded3cd31b3df..c40078e1fff9 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -823,23 +823,6 @@ void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) | |||
823 | # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) | 823 | # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) |
824 | #endif /* DEBUG */ | 824 | #endif /* DEBUG */ |
825 | 825 | ||
826 | |||
827 | /** Limit a value between two limits */ | ||
828 | #ifdef limit_value | ||
829 | # undef limit_value | ||
830 | #endif | ||
831 | #define limit_value(value, min, max) \ | ||
832 | ({ \ | ||
833 | typeof(value) __value = (value); \ | ||
834 | typeof(value) __min = (min); \ | ||
835 | typeof(value) __max = (max); \ | ||
836 | if (__value < __min) \ | ||
837 | __value = __min; \ | ||
838 | else if (__value > __max) \ | ||
839 | __value = __max; \ | ||
840 | __value; \ | ||
841 | }) | ||
842 | |||
843 | /* Macros for printing a value in Q5.2 format */ | 826 | /* Macros for printing a value in Q5.2 format */ |
844 | #define Q52_FMT "%u.%u" | 827 | #define Q52_FMT "%u.%u" |
845 | #define Q52_ARG(q52) ((q52) / 4), (((q52) & 3) * 100 / 4) | 828 | #define Q52_ARG(q52) ((q52) / 4), (((q52) & 3) * 100 / 4) |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1ccc51e90a8e..7755c59e0803 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -846,10 +846,10 @@ static void handle_irq_noise(struct b43legacy_wldev *dev) | |||
846 | /* Get the noise samples. */ | 846 | /* Get the noise samples. */ |
847 | B43legacy_WARN_ON(dev->noisecalc.nr_samples >= 8); | 847 | B43legacy_WARN_ON(dev->noisecalc.nr_samples >= 8); |
848 | i = dev->noisecalc.nr_samples; | 848 | i = dev->noisecalc.nr_samples; |
849 | noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 849 | noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
850 | noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 850 | noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
851 | noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 851 | noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
852 | noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); | 852 | noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); |
853 | dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; | 853 | dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; |
854 | dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; | 854 | dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; |
855 | dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; | 855 | dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; |
@@ -3718,10 +3718,9 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3718 | 3718 | ||
3719 | /* fill hw info */ | 3719 | /* fill hw info */ |
3720 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 3720 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
3721 | IEEE80211_HW_RX_INCLUDES_FCS; | 3721 | IEEE80211_HW_RX_INCLUDES_FCS | |
3722 | hw->max_signal = 100; | 3722 | IEEE80211_HW_SIGNAL_DBM | |
3723 | hw->max_rssi = -110; | 3723 | IEEE80211_HW_NOISE_DBM; |
3724 | hw->max_noise = -110; | ||
3725 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3724 | hw->queues = 1; /* FIXME: hardware has more queues */ |
3726 | SET_IEEE80211_DEV(hw, dev->dev); | 3725 | SET_IEEE80211_DEV(hw, dev->dev); |
3727 | if (is_valid_ether_addr(sprom->et1mac)) | 3726 | if (is_valid_ether_addr(sprom->et1mac)) |
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 8e5c09b81871..768cccb9b1ba 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c | |||
@@ -1088,7 +1088,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev) | |||
1088 | * the value 0x7FFFFFFF here. I think that is some weird | 1088 | * the value 0x7FFFFFFF here. I think that is some weird |
1089 | * compiler optimization in the original driver. | 1089 | * compiler optimization in the original driver. |
1090 | * Essentially, what we do here is resetting all NRSSI LT | 1090 | * Essentially, what we do here is resetting all NRSSI LT |
1091 | * entries to -32 (see the limit_value() in nrssi_hw_update()) | 1091 | * entries to -32 (see the clamp_val() in nrssi_hw_update()) |
1092 | */ | 1092 | */ |
1093 | b43legacy_nrssi_hw_update(dev, 0xFFFF); | 1093 | b43legacy_nrssi_hw_update(dev, 0xFFFF); |
1094 | b43legacy_calc_nrssi_threshold(dev); | 1094 | b43legacy_calc_nrssi_threshold(dev); |
@@ -1756,7 +1756,7 @@ static s8 b43legacy_phy_estimate_power_out(struct b43legacy_wldev *dev, s8 tssi) | |||
1756 | switch (phy->type) { | 1756 | switch (phy->type) { |
1757 | case B43legacy_PHYTYPE_B: | 1757 | case B43legacy_PHYTYPE_B: |
1758 | case B43legacy_PHYTYPE_G: | 1758 | case B43legacy_PHYTYPE_G: |
1759 | tmp = limit_value(tmp, 0x00, 0x3F); | 1759 | tmp = clamp_val(tmp, 0x00, 0x3F); |
1760 | dbm = phy->tssi2dbm[tmp]; | 1760 | dbm = phy->tssi2dbm[tmp]; |
1761 | break; | 1761 | break; |
1762 | default: | 1762 | default: |
@@ -1859,7 +1859,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
1859 | 1859 | ||
1860 | /* find the desired power in Q5.2 - power_level is in dBm | 1860 | /* find the desired power in Q5.2 - power_level is in dBm |
1861 | * and limit it - max_pwr is already in Q5.2 */ | 1861 | * and limit it - max_pwr is already in Q5.2 */ |
1862 | desired_pwr = limit_value(phy->power_level << 2, 0, max_pwr); | 1862 | desired_pwr = clamp_val(phy->power_level << 2, 0, max_pwr); |
1863 | if (b43legacy_debug(dev, B43legacy_DBG_XMITPOWER)) | 1863 | if (b43legacy_debug(dev, B43legacy_DBG_XMITPOWER)) |
1864 | b43legacydbg(dev->wl, "Current TX power output: " Q52_FMT | 1864 | b43legacydbg(dev->wl, "Current TX power output: " Q52_FMT |
1865 | " dBm, Desired TX power output: " Q52_FMT | 1865 | " dBm, Desired TX power output: " Q52_FMT |
@@ -1905,7 +1905,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
1905 | radio_attenuation++; | 1905 | radio_attenuation++; |
1906 | } | 1906 | } |
1907 | } | 1907 | } |
1908 | baseband_attenuation = limit_value(baseband_attenuation, 0, 11); | 1908 | baseband_attenuation = clamp_val(baseband_attenuation, 0, 11); |
1909 | 1909 | ||
1910 | txpower = phy->txctl1; | 1910 | txpower = phy->txctl1; |
1911 | if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) { | 1911 | if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) { |
@@ -1933,8 +1933,8 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
1933 | } | 1933 | } |
1934 | /* Save the control values */ | 1934 | /* Save the control values */ |
1935 | phy->txctl1 = txpower; | 1935 | phy->txctl1 = txpower; |
1936 | baseband_attenuation = limit_value(baseband_attenuation, 0, 11); | 1936 | baseband_attenuation = clamp_val(baseband_attenuation, 0, 11); |
1937 | radio_attenuation = limit_value(radio_attenuation, 0, 9); | 1937 | radio_attenuation = clamp_val(radio_attenuation, 0, 9); |
1938 | phy->rfatt = radio_attenuation; | 1938 | phy->rfatt = radio_attenuation; |
1939 | phy->bbatt = baseband_attenuation; | 1939 | phy->bbatt = baseband_attenuation; |
1940 | 1940 | ||
@@ -1979,7 +1979,7 @@ s8 b43legacy_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2) | |||
1979 | f = q; | 1979 | f = q; |
1980 | i++; | 1980 | i++; |
1981 | } while (delta >= 2); | 1981 | } while (delta >= 2); |
1982 | entry[index] = limit_value(b43legacy_tssi2dbm_ad(m1 * f, 8192), | 1982 | entry[index] = clamp_val(b43legacy_tssi2dbm_ad(m1 * f, 8192), |
1983 | -127, 128); | 1983 | -127, 128); |
1984 | return 0; | 1984 | return 0; |
1985 | } | 1985 | } |
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index 955832e8654f..2df545cfad14 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c | |||
@@ -357,7 +357,7 @@ void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val) | |||
357 | for (i = 0; i < 64; i++) { | 357 | for (i = 0; i < 64; i++) { |
358 | tmp = b43legacy_nrssi_hw_read(dev, i); | 358 | tmp = b43legacy_nrssi_hw_read(dev, i); |
359 | tmp -= val; | 359 | tmp -= val; |
360 | tmp = limit_value(tmp, -32, 31); | 360 | tmp = clamp_val(tmp, -32, 31); |
361 | b43legacy_nrssi_hw_write(dev, i, tmp); | 361 | b43legacy_nrssi_hw_write(dev, i, tmp); |
362 | } | 362 | } |
363 | } | 363 | } |
@@ -375,7 +375,7 @@ void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev) | |||
375 | tmp = (i - delta) * phy->nrssislope; | 375 | tmp = (i - delta) * phy->nrssislope; |
376 | tmp /= 0x10000; | 376 | tmp /= 0x10000; |
377 | tmp += 0x3A; | 377 | tmp += 0x3A; |
378 | tmp = limit_value(tmp, 0, 0x3F); | 378 | tmp = clamp_val(tmp, 0, 0x3F); |
379 | phy->nrssi_lt[i] = tmp; | 379 | phy->nrssi_lt[i] = tmp; |
380 | } | 380 | } |
381 | } | 381 | } |
@@ -839,7 +839,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) | |||
839 | } else | 839 | } else |
840 | threshold = phy->nrssi[1] - 5; | 840 | threshold = phy->nrssi[1] - 5; |
841 | 841 | ||
842 | threshold = limit_value(threshold, 0, 0x3E); | 842 | threshold = clamp_val(threshold, 0, 0x3E); |
843 | b43legacy_phy_read(dev, 0x0020); /* dummy read */ | 843 | b43legacy_phy_read(dev, 0x0020); /* dummy read */ |
844 | b43legacy_phy_write(dev, 0x0020, (((u16)threshold) << 8) | 844 | b43legacy_phy_write(dev, 0x0020, (((u16)threshold) << 8) |
845 | | 0x001C); | 845 | | 0x001C); |
@@ -892,7 +892,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) | |||
892 | else | 892 | else |
893 | a += 32; | 893 | a += 32; |
894 | a = a >> 6; | 894 | a = a >> 6; |
895 | a = limit_value(a, -31, 31); | 895 | a = clamp_val(a, -31, 31); |
896 | 896 | ||
897 | b = b * (phy->nrssi[1] - phy->nrssi[0]); | 897 | b = b * (phy->nrssi[1] - phy->nrssi[0]); |
898 | b += (phy->nrssi[0] << 6); | 898 | b += (phy->nrssi[0] << 6); |
@@ -901,7 +901,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) | |||
901 | else | 901 | else |
902 | b += 32; | 902 | b += 32; |
903 | b = b >> 6; | 903 | b = b >> 6; |
904 | b = limit_value(b, -31, 31); | 904 | b = clamp_val(b, -31, 31); |
905 | 905 | ||
906 | tmp_u16 = b43legacy_phy_read(dev, 0x048A) & 0xF000; | 906 | tmp_u16 = b43legacy_phy_read(dev, 0x048A) & 0xF000; |
907 | tmp_u16 |= ((u32)b & 0x0000003F); | 907 | tmp_u16 |= ((u32)b & 0x0000003F); |
@@ -1905,7 +1905,7 @@ void b43legacy_radio_set_txpower_a(struct b43legacy_wldev *dev, u16 txpower) | |||
1905 | u16 dac; | 1905 | u16 dac; |
1906 | u16 ilt; | 1906 | u16 ilt; |
1907 | 1907 | ||
1908 | txpower = limit_value(txpower, 0, 63); | 1908 | txpower = clamp_val(txpower, 0, 63); |
1909 | 1909 | ||
1910 | pamp = b43legacy_get_txgain_freq_power_amp(txpower); | 1910 | pamp = b43legacy_get_txgain_freq_power_amp(txpower); |
1911 | pamp <<= 5; | 1911 | pamp <<= 5; |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index fc83dab6e2c7..bed9e041d6c5 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -532,12 +532,12 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
532 | } | 532 | } |
533 | } | 533 | } |
534 | 534 | ||
535 | status.ssi = b43legacy_rssi_postprocess(dev, jssi, | 535 | status.signal = b43legacy_rssi_postprocess(dev, jssi, |
536 | (phystat0 & B43legacy_RX_PHYST0_OFDM), | 536 | (phystat0 & B43legacy_RX_PHYST0_OFDM), |
537 | (phystat0 & B43legacy_RX_PHYST0_GAINCTL), | 537 | (phystat0 & B43legacy_RX_PHYST0_GAINCTL), |
538 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); | 538 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); |
539 | status.noise = dev->stats.link_noise; | 539 | status.noise = dev->stats.link_noise; |
540 | status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; | 540 | status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI; |
541 | /* change to support A PHY */ | 541 | /* change to support A PHY */ |
542 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) | 542 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) |
543 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); | 543 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 995dd537083f..5f3e849043f7 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -96,13 +96,13 @@ config IWLWIFI_DEBUG | |||
96 | control which debug output is sent to the kernel log by setting the | 96 | control which debug output is sent to the kernel log by setting the |
97 | value in | 97 | value in |
98 | 98 | ||
99 | /sys/bus/pci/drivers/${DRIVER}/debug_level | 99 | /sys/class/net/wlan0/device/debug_level |
100 | 100 | ||
101 | This entry will only exist if this option is enabled. | 101 | This entry will only exist if this option is enabled. |
102 | 102 | ||
103 | To set a value, simply echo an 8-byte hex value to the same file: | 103 | To set a value, simply echo an 8-byte hex value to the same file: |
104 | 104 | ||
105 | % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level | 105 | % echo 0x43fff > /sys/class/net/wlan0/device/debug_level |
106 | 106 | ||
107 | You can find the list of debug mask values in: | 107 | You can find the list of debug mask values in: |
108 | drivers/net/wireless/iwlwifi/iwl-4965-debug.h | 108 | drivers/net/wireless/iwlwifi/iwl-4965-debug.h |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index b0b2b5ebfa61..5c73eede7193 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-$(CONFIG_IWLCORE) += iwlcore.o | 1 | obj-$(CONFIG_IWLCORE) += iwlcore.o |
2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o | 2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o |
3 | iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o | ||
3 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 4 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
4 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 5 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
5 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | 6 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o |
@@ -10,7 +11,7 @@ iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o | |||
10 | iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o | 11 | iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o |
11 | 12 | ||
12 | obj-$(CONFIG_IWL4965) += iwl4965.o | 13 | obj-$(CONFIG_IWL4965) += iwl4965.o |
13 | iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o | 14 | iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o |
14 | 15 | ||
15 | ifeq ($(CONFIG_IWL5000),y) | 16 | ifeq ($(CONFIG_IWL5000),y) |
16 | iwl4965-objs += iwl-5000.o | 17 | iwl4965-objs += iwl-5000.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 9df48b33f0ca..ad4e7b74ca24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -520,7 +520,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
520 | { | 520 | { |
521 | /* First cache any information we need before we overwrite | 521 | /* First cache any information we need before we overwrite |
522 | * the information provided in the skb from the hardware */ | 522 | * the information provided in the skb from the hardware */ |
523 | s8 signal = stats->ssi; | 523 | s8 signal = stats->signal; |
524 | s8 noise = 0; | 524 | s8 noise = 0; |
525 | int rate = stats->rate_idx; | 525 | int rate = stats->rate_idx; |
526 | u64 tsf = stats->mactime; | 526 | u64 tsf = stats->mactime; |
@@ -693,7 +693,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
693 | } | 693 | } |
694 | 694 | ||
695 | /* Convert 3945's rssi indicator to dBm */ | 695 | /* Convert 3945's rssi indicator to dBm */ |
696 | rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; | 696 | rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET; |
697 | 697 | ||
698 | /* Set default noise value to -127 */ | 698 | /* Set default noise value to -127 */ |
699 | if (priv->last_rx_noise == 0) | 699 | if (priv->last_rx_noise == 0) |
@@ -712,21 +712,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
712 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ | 712 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ |
713 | if (rx_stats_noise_diff) { | 713 | if (rx_stats_noise_diff) { |
714 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | 714 | snr = rx_stats_sig_avg / rx_stats_noise_diff; |
715 | rx_status.noise = rx_status.ssi - | 715 | rx_status.noise = rx_status.signal - |
716 | iwl3945_calc_db_from_ratio(snr); | 716 | iwl3945_calc_db_from_ratio(snr); |
717 | rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, | 717 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, |
718 | rx_status.noise); | 718 | rx_status.noise); |
719 | 719 | ||
720 | /* If noise info not available, calculate signal quality indicator (%) | 720 | /* If noise info not available, calculate signal quality indicator (%) |
721 | * using just the dBm signal level. */ | 721 | * using just the dBm signal level. */ |
722 | } else { | 722 | } else { |
723 | rx_status.noise = priv->last_rx_noise; | 723 | rx_status.noise = priv->last_rx_noise; |
724 | rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0); | 724 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); |
725 | } | 725 | } |
726 | 726 | ||
727 | 727 | ||
728 | IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", | 728 | IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", |
729 | rx_status.ssi, rx_status.noise, rx_status.signal, | 729 | rx_status.signal, rx_status.noise, rx_status.qual, |
730 | rx_stats_sig_avg, rx_stats_noise_diff); | 730 | rx_stats_sig_avg, rx_stats_noise_diff); |
731 | 731 | ||
732 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 732 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
@@ -736,8 +736,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
736 | IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", | 736 | IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", |
737 | network_packet ? '*' : ' ', | 737 | network_packet ? '*' : ' ', |
738 | le16_to_cpu(rx_hdr->channel), | 738 | le16_to_cpu(rx_hdr->channel), |
739 | rx_status.ssi, rx_status.ssi, | 739 | rx_status.signal, rx_status.signal, |
740 | rx_status.ssi, rx_status.rate_idx); | 740 | rx_status.noise, rx_status.rate_idx); |
741 | 741 | ||
742 | #ifdef CONFIG_IWL3945_DEBUG | 742 | #ifdef CONFIG_IWL3945_DEBUG |
743 | if (iwl3945_debug_level & (IWL_DL_RX)) | 743 | if (iwl3945_debug_level & (IWL_DL_RX)) |
@@ -748,7 +748,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
748 | if (network_packet) { | 748 | if (network_packet) { |
749 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); | 749 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); |
750 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); | 750 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); |
751 | priv->last_rx_rssi = rx_status.ssi; | 751 | priv->last_rx_rssi = rx_status.signal; |
752 | priv->last_rx_noise = rx_status.noise; | 752 | priv->last_rx_noise = rx_status.noise; |
753 | } | 753 | } |
754 | 754 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index fb96c62ad0ff..9fdc1405e853 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -886,6 +886,7 @@ struct iwl3945_priv { | |||
886 | struct work_struct report_work; | 886 | struct work_struct report_work; |
887 | struct work_struct request_scan; | 887 | struct work_struct request_scan; |
888 | struct work_struct beacon_update; | 888 | struct work_struct beacon_update; |
889 | struct work_struct set_monitor; | ||
889 | 890 | ||
890 | struct tasklet_struct irq_tasklet; | 891 | struct tasklet_struct irq_tasklet; |
891 | 892 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 29749e2a8ff0..ee55b283226b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -829,7 +829,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | |||
829 | #define IWL49_NUM_QUEUES 16 | 829 | #define IWL49_NUM_QUEUES 16 |
830 | 830 | ||
831 | /** | 831 | /** |
832 | * struct iwl4965_tfd_frame_data | 832 | * struct iwl_tfd_frame_data |
833 | * | 833 | * |
834 | * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. | 834 | * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. |
835 | * Each buffer must be on dword boundary. | 835 | * Each buffer must be on dword boundary. |
@@ -848,7 +848,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | |||
848 | * 31-20: Tx buffer 2 length (bytes) | 848 | * 31-20: Tx buffer 2 length (bytes) |
849 | * 19- 0: Tx buffer 2 address bits [35:16] | 849 | * 19- 0: Tx buffer 2 address bits [35:16] |
850 | */ | 850 | */ |
851 | struct iwl4965_tfd_frame_data { | 851 | struct iwl_tfd_frame_data { |
852 | __le32 tb1_addr; | 852 | __le32 tb1_addr; |
853 | 853 | ||
854 | __le32 val1; | 854 | __le32 val1; |
@@ -878,7 +878,7 @@ struct iwl4965_tfd_frame_data { | |||
878 | 878 | ||
879 | 879 | ||
880 | /** | 880 | /** |
881 | * struct iwl4965_tfd_frame | 881 | * struct iwl_tfd_frame |
882 | * | 882 | * |
883 | * Transmit Frame Descriptor (TFD) | 883 | * Transmit Frame Descriptor (TFD) |
884 | * | 884 | * |
@@ -905,7 +905,7 @@ struct iwl4965_tfd_frame_data { | |||
905 | * | 905 | * |
906 | * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. | 906 | * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. |
907 | */ | 907 | */ |
908 | struct iwl4965_tfd_frame { | 908 | struct iwl_tfd_frame { |
909 | __le32 val0; | 909 | __le32 val0; |
910 | /* __le32 rsvd1:24; */ | 910 | /* __le32 rsvd1:24; */ |
911 | /* __le32 num_tbs:5; */ | 911 | /* __le32 num_tbs:5; */ |
@@ -914,7 +914,7 @@ struct iwl4965_tfd_frame { | |||
914 | #define IWL_num_tbs_SYM val0 | 914 | #define IWL_num_tbs_SYM val0 |
915 | /* __le32 rsvd2:1; */ | 915 | /* __le32 rsvd2:1; */ |
916 | /* __le32 padding:2; */ | 916 | /* __le32 padding:2; */ |
917 | struct iwl4965_tfd_frame_data pa[10]; | 917 | struct iwl_tfd_frame_data pa[10]; |
918 | __le32 reserved; | 918 | __le32 reserved; |
919 | } __attribute__ ((packed)); | 919 | } __attribute__ ((packed)); |
920 | 920 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 24dee00b0e85..8e3660ebba7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -360,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
360 | unsigned long state; | 360 | unsigned long state; |
361 | DECLARE_MAC_BUF(mac); | 361 | DECLARE_MAC_BUF(mac); |
362 | 362 | ||
363 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 363 | spin_lock_bh(&sta->lock); |
364 | state = sta->ampdu_mlme.tid_state_tx[tid]; | 364 | state = sta->ampdu_mlme.tid_state_tx[tid]; |
365 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 365 | spin_unlock_bh(&sta->lock); |
366 | 366 | ||
367 | if (state == HT_AGG_STATE_IDLE && | 367 | if (state == HT_AGG_STATE_IDLE && |
368 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 368 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
@@ -662,7 +662,8 @@ static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, | |||
662 | } | 662 | } |
663 | } | 663 | } |
664 | 664 | ||
665 | static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) | 665 | static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, |
666 | int rate_type) | ||
666 | { | 667 | { |
667 | u8 high = IWL_RATE_INVALID; | 668 | u8 high = IWL_RATE_INVALID; |
668 | u8 low = IWL_RATE_INVALID; | 669 | u8 low = IWL_RATE_INVALID; |
@@ -763,7 +764,8 @@ static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
763 | goto out; | 764 | goto out; |
764 | } | 765 | } |
765 | 766 | ||
766 | high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type); | 767 | high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask, |
768 | tbl->lq_type); | ||
767 | low = high_low & 0xff; | 769 | low = high_low & 0xff; |
768 | 770 | ||
769 | if (low == IWL_RATE_INVALID) | 771 | if (low == IWL_RATE_INVALID) |
@@ -990,7 +992,7 @@ out: | |||
990 | * These control how long we stay using same modulation mode before | 992 | * These control how long we stay using same modulation mode before |
991 | * searching for a new mode. | 993 | * searching for a new mode. |
992 | */ | 994 | */ |
993 | static void rs_set_stay_in_table(u8 is_legacy, | 995 | static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, |
994 | struct iwl4965_lq_sta *lq_sta) | 996 | struct iwl4965_lq_sta *lq_sta) |
995 | { | 997 | { |
996 | IWL_DEBUG_RATE("we are staying in the same table\n"); | 998 | IWL_DEBUG_RATE("we are staying in the same table\n"); |
@@ -1079,7 +1081,8 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1079 | new_rate = high = low = start_hi = IWL_RATE_INVALID; | 1081 | new_rate = high = low = start_hi = IWL_RATE_INVALID; |
1080 | 1082 | ||
1081 | for (; ;) { | 1083 | for (; ;) { |
1082 | high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type); | 1084 | high_low = rs_get_adjacent_rate(priv, rate, rate_mask, |
1085 | tbl->lq_type); | ||
1083 | 1086 | ||
1084 | low = high_low & 0xff; | 1087 | low = high_low & 0xff; |
1085 | high = (high_low >> 8) & 0xff; | 1088 | high = (high_low >> 8) & 0xff; |
@@ -1565,7 +1568,9 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1565 | int i; | 1568 | int i; |
1566 | int active_tbl; | 1569 | int active_tbl; |
1567 | int flush_interval_passed = 0; | 1570 | int flush_interval_passed = 0; |
1571 | struct iwl_priv *priv; | ||
1568 | 1572 | ||
1573 | priv = lq_sta->drv; | ||
1569 | active_tbl = lq_sta->active_tbl; | 1574 | active_tbl = lq_sta->active_tbl; |
1570 | 1575 | ||
1571 | tbl = &(lq_sta->lq_info[active_tbl]); | 1576 | tbl = &(lq_sta->lq_info[active_tbl]); |
@@ -1838,7 +1843,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1838 | 1843 | ||
1839 | /* (Else) not in search of better modulation mode, try for better | 1844 | /* (Else) not in search of better modulation mode, try for better |
1840 | * starting rate, while staying in this mode. */ | 1845 | * starting rate, while staying in this mode. */ |
1841 | high_low = rs_get_adjacent_rate(index, rate_scale_index_msk, | 1846 | high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk, |
1842 | tbl->lq_type); | 1847 | tbl->lq_type); |
1843 | low = high_low & 0xff; | 1848 | low = high_low & 0xff; |
1844 | high = (high_low >> 8) & 0xff; | 1849 | high = (high_low >> 8) & 0xff; |
@@ -1998,7 +2003,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1998 | (lq_sta->action_counter >= 1)) { | 2003 | (lq_sta->action_counter >= 1)) { |
1999 | lq_sta->action_counter = 0; | 2004 | lq_sta->action_counter = 0; |
2000 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); | 2005 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); |
2001 | rs_set_stay_in_table(1, lq_sta); | 2006 | rs_set_stay_in_table(priv, 1, lq_sta); |
2002 | } | 2007 | } |
2003 | 2008 | ||
2004 | /* If we're in an HT mode, and all 3 mode switch actions | 2009 | /* If we're in an HT mode, and all 3 mode switch actions |
@@ -2015,7 +2020,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2015 | } | 2020 | } |
2016 | #endif /*CONFIG_IWL4965_HT */ | 2021 | #endif /*CONFIG_IWL4965_HT */ |
2017 | lq_sta->action_counter = 0; | 2022 | lq_sta->action_counter = 0; |
2018 | rs_set_stay_in_table(0, lq_sta); | 2023 | rs_set_stay_in_table(priv, 0, lq_sta); |
2019 | } | 2024 | } |
2020 | 2025 | ||
2021 | /* | 2026 | /* |
@@ -2169,11 +2174,13 @@ out: | |||
2169 | rcu_read_unlock(); | 2174 | rcu_read_unlock(); |
2170 | } | 2175 | } |
2171 | 2176 | ||
2172 | static void *rs_alloc_sta(void *priv, gfp_t gfp) | 2177 | static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) |
2173 | { | 2178 | { |
2174 | struct iwl4965_lq_sta *lq_sta; | 2179 | struct iwl4965_lq_sta *lq_sta; |
2180 | struct iwl_priv *priv; | ||
2175 | int i, j; | 2181 | int i, j; |
2176 | 2182 | ||
2183 | priv = (struct iwl_priv *)priv_rate; | ||
2177 | IWL_DEBUG_RATE("create station rate scale window\n"); | 2184 | IWL_DEBUG_RATE("create station rate scale window\n"); |
2178 | 2185 | ||
2179 | lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); | 2186 | lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); |
@@ -2443,10 +2450,12 @@ static void rs_clear(void *priv_rate) | |||
2443 | IWL_DEBUG_RATE("leave\n"); | 2450 | IWL_DEBUG_RATE("leave\n"); |
2444 | } | 2451 | } |
2445 | 2452 | ||
2446 | static void rs_free_sta(void *priv, void *priv_sta) | 2453 | static void rs_free_sta(void *priv_rate, void *priv_sta) |
2447 | { | 2454 | { |
2448 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2455 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2456 | struct iwl_priv *priv; | ||
2449 | 2457 | ||
2458 | priv = (struct iwl_priv *)priv_rate; | ||
2450 | IWL_DEBUG_RATE("enter\n"); | 2459 | IWL_DEBUG_RATE("enter\n"); |
2451 | kfree(lq_sta); | 2460 | kfree(lq_sta); |
2452 | IWL_DEBUG_RATE("leave\n"); | 2461 | IWL_DEBUG_RATE("leave\n"); |
@@ -2462,6 +2471,9 @@ static int open_file_generic(struct inode *inode, struct file *file) | |||
2462 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 2471 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, |
2463 | u32 *rate_n_flags, int index) | 2472 | u32 *rate_n_flags, int index) |
2464 | { | 2473 | { |
2474 | struct iwl_priv *priv; | ||
2475 | |||
2476 | priv = lq_sta->drv; | ||
2465 | if (lq_sta->dbg_fixed_rate) { | 2477 | if (lq_sta->dbg_fixed_rate) { |
2466 | if (index < 12) { | 2478 | if (index < 12) { |
2467 | *rate_n_flags = lq_sta->dbg_fixed_rate; | 2479 | *rate_n_flags = lq_sta->dbg_fixed_rate; |
@@ -2481,10 +2493,12 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | |||
2481 | const char __user *user_buf, size_t count, loff_t *ppos) | 2493 | const char __user *user_buf, size_t count, loff_t *ppos) |
2482 | { | 2494 | { |
2483 | struct iwl4965_lq_sta *lq_sta = file->private_data; | 2495 | struct iwl4965_lq_sta *lq_sta = file->private_data; |
2496 | struct iwl_priv *priv; | ||
2484 | char buf[64]; | 2497 | char buf[64]; |
2485 | int buf_size; | 2498 | int buf_size; |
2486 | u32 parsed_rate; | 2499 | u32 parsed_rate; |
2487 | 2500 | ||
2501 | priv = lq_sta->drv; | ||
2488 | memset(buf, 0, sizeof(buf)); | 2502 | memset(buf, 0, sizeof(buf)); |
2489 | buf_size = min(count, sizeof(buf) - 1); | 2503 | buf_size = min(count, sizeof(buf) - 1); |
2490 | if (copy_from_user(buf, user_buf, buf_size)) | 2504 | if (copy_from_user(buf, user_buf, buf_size)) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 5d675e39bab8..17847f981e11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -50,11 +50,10 @@ static struct iwl_mod_params iwl4965_mod_params = { | |||
50 | .num_of_queues = IWL49_NUM_QUEUES, | 50 | .num_of_queues = IWL49_NUM_QUEUES, |
51 | .enable_qos = 1, | 51 | .enable_qos = 1, |
52 | .amsdu_size_8K = 1, | 52 | .amsdu_size_8K = 1, |
53 | .restart_fw = 1, | ||
53 | /* the rest are 0 by default */ | 54 | /* the rest are 0 by default */ |
54 | }; | 55 | }; |
55 | 56 | ||
56 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv); | ||
57 | |||
58 | #ifdef CONFIG_IWL4965_HT | 57 | #ifdef CONFIG_IWL4965_HT |
59 | 58 | ||
60 | static const u16 default_tid_to_tx_fifo[] = { | 59 | static const u16 default_tid_to_tx_fifo[] = { |
@@ -224,6 +223,102 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
224 | return 0; | 223 | return 0; |
225 | } | 224 | } |
226 | 225 | ||
226 | /** | ||
227 | * iwl4965_set_ucode_ptrs - Set uCode address location | ||
228 | * | ||
229 | * Tell initialization uCode where to find runtime uCode. | ||
230 | * | ||
231 | * BSM registers initially contain pointers to initialization uCode. | ||
232 | * We need to replace them to load runtime uCode inst and data, | ||
233 | * and to save runtime data when powering down. | ||
234 | */ | ||
235 | static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) | ||
236 | { | ||
237 | dma_addr_t pinst; | ||
238 | dma_addr_t pdata; | ||
239 | unsigned long flags; | ||
240 | int ret = 0; | ||
241 | |||
242 | /* bits 35:4 for 4965 */ | ||
243 | pinst = priv->ucode_code.p_addr >> 4; | ||
244 | pdata = priv->ucode_data_backup.p_addr >> 4; | ||
245 | |||
246 | spin_lock_irqsave(&priv->lock, flags); | ||
247 | ret = iwl_grab_nic_access(priv); | ||
248 | if (ret) { | ||
249 | spin_unlock_irqrestore(&priv->lock, flags); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | /* Tell bootstrap uCode where to find image to load */ | ||
254 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
255 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
256 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, | ||
257 | priv->ucode_data.len); | ||
258 | |||
259 | /* Inst bytecount must be last to set up, bit 31 signals uCode | ||
260 | * that all new ptr/size info is in place */ | ||
261 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | ||
262 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | ||
263 | iwl_release_nic_access(priv); | ||
264 | |||
265 | spin_unlock_irqrestore(&priv->lock, flags); | ||
266 | |||
267 | IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); | ||
268 | |||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received | ||
274 | * | ||
275 | * Called after REPLY_ALIVE notification received from "initialize" uCode. | ||
276 | * | ||
277 | * The 4965 "initialize" ALIVE reply contains calibration data for: | ||
278 | * Voltage, temperature, and MIMO tx gain correction, now stored in priv | ||
279 | * (3945 does not contain this data). | ||
280 | * | ||
281 | * Tell "initialize" uCode to go ahead and load the runtime uCode. | ||
282 | */ | ||
283 | static void iwl4965_init_alive_start(struct iwl_priv *priv) | ||
284 | { | ||
285 | /* Check alive response for "valid" sign from uCode */ | ||
286 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
287 | /* We had an error bringing up the hardware, so take it | ||
288 | * all the way back down so we can try again */ | ||
289 | IWL_DEBUG_INFO("Initialize Alive failed.\n"); | ||
290 | goto restart; | ||
291 | } | ||
292 | |||
293 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | ||
294 | * This is a paranoid check, because we would not have gotten the | ||
295 | * "initialize" alive if code weren't properly loaded. */ | ||
296 | if (iwl_verify_ucode(priv)) { | ||
297 | /* Runtime instruction load was bad; | ||
298 | * take it all the way back down so we can try again */ | ||
299 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); | ||
300 | goto restart; | ||
301 | } | ||
302 | |||
303 | /* Calculate temperature */ | ||
304 | priv->temperature = iwl4965_get_temperature(priv); | ||
305 | |||
306 | /* Send pointers to protocol/runtime uCode image ... init code will | ||
307 | * load and launch runtime uCode, which will send us another "Alive" | ||
308 | * notification. */ | ||
309 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | ||
310 | if (iwl4965_set_ucode_ptrs(priv)) { | ||
311 | /* Runtime instruction load won't happen; | ||
312 | * take it all the way back down so we can try again */ | ||
313 | IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); | ||
314 | goto restart; | ||
315 | } | ||
316 | return; | ||
317 | |||
318 | restart: | ||
319 | queue_work(priv->workqueue, &priv->restart); | ||
320 | } | ||
321 | |||
227 | static int is_fat_channel(__le32 rxon_flags) | 322 | static int is_fat_channel(__le32 rxon_flags) |
228 | { | 323 | { |
229 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || | 324 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || |
@@ -372,178 +467,31 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) | |||
372 | return ret; | 467 | return ret; |
373 | } | 468 | } |
374 | 469 | ||
375 | static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | 470 | static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) |
376 | { | 471 | { |
377 | int ret; | ||
378 | unsigned long flags; | 472 | unsigned long flags; |
379 | unsigned int rb_size; | 473 | int ret; |
380 | 474 | ||
381 | spin_lock_irqsave(&priv->lock, flags); | 475 | spin_lock_irqsave(&priv->lock, flags); |
476 | |||
382 | ret = iwl_grab_nic_access(priv); | 477 | ret = iwl_grab_nic_access(priv); |
383 | if (ret) { | 478 | if (unlikely(ret)) { |
479 | IWL_ERROR("Tx fifo reset failed"); | ||
384 | spin_unlock_irqrestore(&priv->lock, flags); | 480 | spin_unlock_irqrestore(&priv->lock, flags); |
385 | return ret; | 481 | return ret; |
386 | } | 482 | } |
387 | 483 | ||
388 | if (priv->cfg->mod_params->amsdu_size_8K) | 484 | iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); |
389 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
390 | else | ||
391 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
392 | |||
393 | /* Stop Rx DMA */ | ||
394 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
395 | |||
396 | /* Reset driver's Rx queue write index */ | ||
397 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
398 | |||
399 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
400 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
401 | rxq->dma_addr >> 8); | ||
402 | |||
403 | /* Tell device where in DRAM to update its Rx status */ | ||
404 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
405 | (priv->shared_phys + | ||
406 | offsetof(struct iwl4965_shared, rb_closed)) >> 4); | ||
407 | |||
408 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | ||
409 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
410 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
411 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
412 | rb_size | | ||
413 | /* 0x10 << 4 | */ | ||
414 | (RX_QUEUE_SIZE_LOG << | ||
415 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | ||
416 | |||
417 | /* | ||
418 | * iwl_write32(priv,CSR_INT_COAL_REG,0); | ||
419 | */ | ||
420 | |||
421 | iwl_release_nic_access(priv); | ||
422 | spin_unlock_irqrestore(&priv->lock, flags); | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | /* Tell 4965 where to find the "keep warm" buffer */ | ||
428 | static int iwl4965_kw_init(struct iwl_priv *priv) | ||
429 | { | ||
430 | unsigned long flags; | ||
431 | int rc; | ||
432 | |||
433 | spin_lock_irqsave(&priv->lock, flags); | ||
434 | rc = iwl_grab_nic_access(priv); | ||
435 | if (rc) | ||
436 | goto out; | ||
437 | |||
438 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, | ||
439 | priv->kw.dma_addr >> 4); | ||
440 | iwl_release_nic_access(priv); | 485 | iwl_release_nic_access(priv); |
441 | out: | ||
442 | spin_unlock_irqrestore(&priv->lock, flags); | 486 | spin_unlock_irqrestore(&priv->lock, flags); |
443 | return rc; | ||
444 | } | ||
445 | |||
446 | static int iwl4965_kw_alloc(struct iwl_priv *priv) | ||
447 | { | ||
448 | struct pci_dev *dev = priv->pci_dev; | ||
449 | struct iwl4965_kw *kw = &priv->kw; | ||
450 | |||
451 | kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ | ||
452 | kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); | ||
453 | if (!kw->v_addr) | ||
454 | return -ENOMEM; | ||
455 | 487 | ||
456 | return 0; | 488 | return 0; |
457 | } | 489 | } |
458 | 490 | ||
459 | /** | ||
460 | * iwl4965_kw_free - Free the "keep warm" buffer | ||
461 | */ | ||
462 | static void iwl4965_kw_free(struct iwl_priv *priv) | ||
463 | { | ||
464 | struct pci_dev *dev = priv->pci_dev; | ||
465 | struct iwl4965_kw *kw = &priv->kw; | ||
466 | |||
467 | if (kw->v_addr) { | ||
468 | pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); | ||
469 | memset(kw, 0, sizeof(*kw)); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * iwl4965_txq_ctx_reset - Reset TX queue context | ||
475 | * Destroys all DMA structures and initialise them again | ||
476 | * | ||
477 | * @param priv | ||
478 | * @return error code | ||
479 | */ | ||
480 | static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) | ||
481 | { | ||
482 | int rc = 0; | ||
483 | int txq_id, slots_num; | ||
484 | unsigned long flags; | ||
485 | |||
486 | iwl4965_kw_free(priv); | ||
487 | |||
488 | /* Free all tx/cmd queues and keep-warm buffer */ | ||
489 | iwl4965_hw_txq_ctx_free(priv); | ||
490 | |||
491 | /* Alloc keep-warm buffer */ | ||
492 | rc = iwl4965_kw_alloc(priv); | ||
493 | if (rc) { | ||
494 | IWL_ERROR("Keep Warm allocation failed"); | ||
495 | goto error_kw; | ||
496 | } | ||
497 | |||
498 | spin_lock_irqsave(&priv->lock, flags); | ||
499 | |||
500 | rc = iwl_grab_nic_access(priv); | ||
501 | if (unlikely(rc)) { | ||
502 | IWL_ERROR("TX reset failed"); | ||
503 | spin_unlock_irqrestore(&priv->lock, flags); | ||
504 | goto error_reset; | ||
505 | } | ||
506 | |||
507 | /* Turn off all Tx DMA channels */ | ||
508 | iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); | ||
509 | iwl_release_nic_access(priv); | ||
510 | spin_unlock_irqrestore(&priv->lock, flags); | ||
511 | |||
512 | /* Tell 4965 where to find the keep-warm buffer */ | ||
513 | rc = iwl4965_kw_init(priv); | ||
514 | if (rc) { | ||
515 | IWL_ERROR("kw_init failed\n"); | ||
516 | goto error_reset; | ||
517 | } | ||
518 | |||
519 | /* Alloc and init all (default 16) Tx queues, | ||
520 | * including the command queue (#4) */ | ||
521 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
522 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | ||
523 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
524 | rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | ||
525 | txq_id); | ||
526 | if (rc) { | ||
527 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | ||
528 | goto error; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | return rc; | ||
533 | |||
534 | error: | ||
535 | iwl4965_hw_txq_ctx_free(priv); | ||
536 | error_reset: | ||
537 | iwl4965_kw_free(priv); | ||
538 | error_kw: | ||
539 | return rc; | ||
540 | } | ||
541 | static int iwl4965_apm_init(struct iwl_priv *priv) | 491 | static int iwl4965_apm_init(struct iwl_priv *priv) |
542 | { | 492 | { |
543 | unsigned long flags; | ||
544 | int ret = 0; | 493 | int ret = 0; |
545 | 494 | ||
546 | spin_lock_irqsave(&priv->lock, flags); | ||
547 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 495 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
548 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | 496 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
549 | 497 | ||
@@ -575,7 +523,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv) | |||
575 | 523 | ||
576 | iwl_release_nic_access(priv); | 524 | iwl_release_nic_access(priv); |
577 | out: | 525 | out: |
578 | spin_unlock_irqrestore(&priv->lock, flags); | ||
579 | return ret; | 526 | return ret; |
580 | } | 527 | } |
581 | 528 | ||
@@ -621,59 +568,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) | |||
621 | spin_unlock_irqrestore(&priv->lock, flags); | 568 | spin_unlock_irqrestore(&priv->lock, flags); |
622 | } | 569 | } |
623 | 570 | ||
624 | |||
625 | int iwl4965_hw_nic_init(struct iwl_priv *priv) | ||
626 | { | ||
627 | unsigned long flags; | ||
628 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
629 | int ret; | ||
630 | |||
631 | /* nic_init */ | ||
632 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
633 | |||
634 | spin_lock_irqsave(&priv->lock, flags); | ||
635 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | ||
636 | spin_unlock_irqrestore(&priv->lock, flags); | ||
637 | |||
638 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
639 | |||
640 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
641 | |||
642 | iwl4965_hw_card_show_info(priv); | ||
643 | |||
644 | /* end nic_init */ | ||
645 | |||
646 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
647 | if (!rxq->bd) { | ||
648 | ret = iwl4965_rx_queue_alloc(priv); | ||
649 | if (ret) { | ||
650 | IWL_ERROR("Unable to initialize Rx queue\n"); | ||
651 | return -ENOMEM; | ||
652 | } | ||
653 | } else | ||
654 | iwl4965_rx_queue_reset(priv, rxq); | ||
655 | |||
656 | iwl4965_rx_replenish(priv); | ||
657 | |||
658 | iwl4965_rx_init(priv, rxq); | ||
659 | |||
660 | spin_lock_irqsave(&priv->lock, flags); | ||
661 | |||
662 | rxq->need_update = 1; | ||
663 | iwl4965_rx_queue_update_write_ptr(priv, rxq); | ||
664 | |||
665 | spin_unlock_irqrestore(&priv->lock, flags); | ||
666 | |||
667 | /* Allocate and init all Tx and Command queues */ | ||
668 | ret = iwl4965_txq_ctx_reset(priv); | ||
669 | if (ret) | ||
670 | return ret; | ||
671 | |||
672 | set_bit(STATUS_INIT, &priv->status); | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) | 571 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) |
678 | { | 572 | { |
679 | int rc = 0; | 573 | int rc = 0; |
@@ -734,7 +628,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
734 | } | 628 | } |
735 | 629 | ||
736 | /* Deallocate memory for all Tx queues */ | 630 | /* Deallocate memory for all Tx queues */ |
737 | iwl4965_hw_txq_ctx_free(priv); | 631 | iwl_hw_txq_ctx_free(priv); |
738 | } | 632 | } |
739 | 633 | ||
740 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) | 634 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) |
@@ -984,7 +878,7 @@ static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) | |||
984 | * NOTE: Acquire priv->lock before calling this function ! | 878 | * NOTE: Acquire priv->lock before calling this function ! |
985 | */ | 879 | */ |
986 | static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, | 880 | static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, |
987 | struct iwl4965_tx_queue *txq, | 881 | struct iwl_tx_queue *txq, |
988 | int tx_fifo_id, int scd_retry) | 882 | int tx_fifo_id, int scd_retry) |
989 | { | 883 | { |
990 | int txq_id = txq->q.id; | 884 | int txq_id = txq->q.id; |
@@ -1188,82 +1082,6 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
1188 | return 0; | 1082 | return 0; |
1189 | } | 1083 | } |
1190 | 1084 | ||
1191 | /** | ||
1192 | * iwl4965_hw_txq_ctx_free - Free TXQ Context | ||
1193 | * | ||
1194 | * Destroy all TX DMA queues and structures | ||
1195 | */ | ||
1196 | void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) | ||
1197 | { | ||
1198 | int txq_id; | ||
1199 | |||
1200 | /* Tx queues */ | ||
1201 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | ||
1202 | iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); | ||
1203 | |||
1204 | /* Keep-warm buffer */ | ||
1205 | iwl4965_kw_free(priv); | ||
1206 | } | ||
1207 | |||
1208 | /** | ||
1209 | * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
1210 | * | ||
1211 | * Does NOT advance any TFD circular buffer read/write indexes | ||
1212 | * Does NOT free the TFD itself (which is within circular buffer) | ||
1213 | */ | ||
1214 | int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
1215 | { | ||
1216 | struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0]; | ||
1217 | struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | ||
1218 | struct pci_dev *dev = priv->pci_dev; | ||
1219 | int i; | ||
1220 | int counter = 0; | ||
1221 | int index, is_odd; | ||
1222 | |||
1223 | /* Host command buffers stay mapped in memory, nothing to clean */ | ||
1224 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | ||
1225 | return 0; | ||
1226 | |||
1227 | /* Sanity check on number of chunks */ | ||
1228 | counter = IWL_GET_BITS(*bd, num_tbs); | ||
1229 | if (counter > MAX_NUM_OF_TBS) { | ||
1230 | IWL_ERROR("Too many chunks: %i\n", counter); | ||
1231 | /* @todo issue fatal error, it is quite serious situation */ | ||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | /* Unmap chunks, if any. | ||
1236 | * TFD info for odd chunks is different format than for even chunks. */ | ||
1237 | for (i = 0; i < counter; i++) { | ||
1238 | index = i / 2; | ||
1239 | is_odd = i & 0x1; | ||
1240 | |||
1241 | if (is_odd) | ||
1242 | pci_unmap_single( | ||
1243 | dev, | ||
1244 | IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | | ||
1245 | (IWL_GET_BITS(bd->pa[index], | ||
1246 | tb2_addr_hi20) << 16), | ||
1247 | IWL_GET_BITS(bd->pa[index], tb2_len), | ||
1248 | PCI_DMA_TODEVICE); | ||
1249 | |||
1250 | else if (i > 0) | ||
1251 | pci_unmap_single(dev, | ||
1252 | le32_to_cpu(bd->pa[index].tb1_addr), | ||
1253 | IWL_GET_BITS(bd->pa[index], tb1_len), | ||
1254 | PCI_DMA_TODEVICE); | ||
1255 | |||
1256 | /* Free SKB, if any, for this chunk */ | ||
1257 | if (txq->txb[txq->q.read_ptr].skb[i]) { | ||
1258 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; | ||
1259 | |||
1260 | dev_kfree_skb(skb); | ||
1261 | txq->txb[txq->q.read_ptr].skb[i] = NULL; | ||
1262 | } | ||
1263 | } | ||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | /* set card power command */ | 1085 | /* set card power command */ |
1268 | static int iwl4965_set_power(struct iwl_priv *priv, | 1086 | static int iwl4965_set_power(struct iwl_priv *priv, |
1269 | void *cmd) | 1087 | void *cmd) |
@@ -2186,7 +2004,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
2186 | tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); | 2004 | tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); |
2187 | } | 2005 | } |
2188 | 2006 | ||
2189 | int iwl4965_hw_get_rx_read(struct iwl_priv *priv) | 2007 | static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) |
2190 | { | 2008 | { |
2191 | struct iwl4965_shared *s = priv->shared_virt; | 2009 | struct iwl4965_shared *s = priv->shared_virt; |
2192 | return le32_to_cpu(s->rb_closed) & 0xFFF; | 2010 | return le32_to_cpu(s->rb_closed) & 0xFFF; |
@@ -2229,46 +2047,11 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
2229 | return (sizeof(*tx_beacon_cmd) + frame_size); | 2047 | return (sizeof(*tx_beacon_cmd) + frame_size); |
2230 | } | 2048 | } |
2231 | 2049 | ||
2232 | /* | ||
2233 | * Tell 4965 where to find circular buffer of Tx Frame Descriptors for | ||
2234 | * given Tx queue, and enable the DMA channel used for that queue. | ||
2235 | * | ||
2236 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
2237 | * channels supported in hardware. | ||
2238 | */ | ||
2239 | int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
2240 | { | ||
2241 | int rc; | ||
2242 | unsigned long flags; | ||
2243 | int txq_id = txq->q.id; | ||
2244 | |||
2245 | spin_lock_irqsave(&priv->lock, flags); | ||
2246 | rc = iwl_grab_nic_access(priv); | ||
2247 | if (rc) { | ||
2248 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2249 | return rc; | ||
2250 | } | ||
2251 | |||
2252 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
2253 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
2254 | txq->q.dma_addr >> 8); | ||
2255 | |||
2256 | /* Enable DMA channel, using same id as for TFD queue */ | ||
2257 | iwl_write_direct32( | ||
2258 | priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), | ||
2259 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
2260 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); | ||
2261 | iwl_release_nic_access(priv); | ||
2262 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2263 | |||
2264 | return 0; | ||
2265 | } | ||
2266 | |||
2267 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | 2050 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, |
2268 | dma_addr_t addr, u16 len) | 2051 | dma_addr_t addr, u16 len) |
2269 | { | 2052 | { |
2270 | int index, is_odd; | 2053 | int index, is_odd; |
2271 | struct iwl4965_tfd_frame *tfd = ptr; | 2054 | struct iwl_tfd_frame *tfd = ptr; |
2272 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); | 2055 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); |
2273 | 2056 | ||
2274 | /* Each TFD can point to a maximum 20 Tx buffers */ | 2057 | /* Each TFD can point to a maximum 20 Tx buffers */ |
@@ -2298,18 +2081,6 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | |||
2298 | return 0; | 2081 | return 0; |
2299 | } | 2082 | } |
2300 | 2083 | ||
2301 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv) | ||
2302 | { | ||
2303 | u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION); | ||
2304 | |||
2305 | IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n", | ||
2306 | ((hw_version >> 8) & 0x0F), | ||
2307 | ((hw_version >> 8) >> 4), (hw_version & 0x00FF)); | ||
2308 | |||
2309 | IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n", | ||
2310 | &priv->eeprom[EEPROM_4965_BOARD_PBA]); | ||
2311 | } | ||
2312 | |||
2313 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) | 2084 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) |
2314 | { | 2085 | { |
2315 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, | 2086 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, |
@@ -2320,6 +2091,8 @@ static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) | |||
2320 | 2091 | ||
2321 | memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); | 2092 | memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); |
2322 | 2093 | ||
2094 | priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed); | ||
2095 | |||
2323 | return 0; | 2096 | return 0; |
2324 | } | 2097 | } |
2325 | 2098 | ||
@@ -2336,7 +2109,7 @@ static void iwl4965_free_shared_mem(struct iwl_priv *priv) | |||
2336 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 2109 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
2337 | */ | 2110 | */ |
2338 | static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | 2111 | static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, |
2339 | struct iwl4965_tx_queue *txq, | 2112 | struct iwl_tx_queue *txq, |
2340 | u16 byte_cnt) | 2113 | u16 byte_cnt) |
2341 | { | 2114 | { |
2342 | int len; | 2115 | int len; |
@@ -2516,9 +2289,10 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv) | |||
2516 | priv->last_rx_noise); | 2289 | priv->last_rx_noise); |
2517 | } | 2290 | } |
2518 | 2291 | ||
2519 | void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) | 2292 | void iwl4965_hw_rx_statistics(struct iwl_priv *priv, |
2293 | struct iwl_rx_mem_buffer *rxb) | ||
2520 | { | 2294 | { |
2521 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2295 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2522 | int change; | 2296 | int change; |
2523 | s32 temp; | 2297 | s32 temp; |
2524 | 2298 | ||
@@ -2588,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv, | |||
2588 | struct ieee80211_rx_status *stats, | 2362 | struct ieee80211_rx_status *stats, |
2589 | u32 ampdu_status) | 2363 | u32 ampdu_status) |
2590 | { | 2364 | { |
2591 | s8 signal = stats->ssi; | 2365 | s8 signal = stats->signal; |
2592 | s8 noise = 0; | 2366 | s8 noise = 0; |
2593 | int rate = stats->rate_idx; | 2367 | int rate = stats->rate_idx; |
2594 | u64 tsf = stats->mactime; | 2368 | u64 tsf = stats->mactime; |
@@ -2742,7 +2516,7 @@ static int iwl4965_set_decrypted_flag(struct iwl_priv *priv, | |||
2742 | return 0; | 2516 | return 0; |
2743 | } | 2517 | } |
2744 | 2518 | ||
2745 | static u32 iwl4965_translate_rx_status(u32 decrypt_in) | 2519 | static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
2746 | { | 2520 | { |
2747 | u32 decrypt_out = 0; | 2521 | u32 decrypt_out = 0; |
2748 | 2522 | ||
@@ -2803,10 +2577,10 @@ static u32 iwl4965_translate_rx_status(u32 decrypt_in) | |||
2803 | 2577 | ||
2804 | static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | 2578 | static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, |
2805 | int include_phy, | 2579 | int include_phy, |
2806 | struct iwl4965_rx_mem_buffer *rxb, | 2580 | struct iwl_rx_mem_buffer *rxb, |
2807 | struct ieee80211_rx_status *stats) | 2581 | struct ieee80211_rx_status *stats) |
2808 | { | 2582 | { |
2809 | struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 2583 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2810 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | 2584 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? |
2811 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; | 2585 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; |
2812 | struct ieee80211_hdr *hdr; | 2586 | struct ieee80211_hdr *hdr; |
@@ -2843,7 +2617,9 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2843 | rx_start->byte_count = amsdu->byte_count; | 2617 | rx_start->byte_count = amsdu->byte_count; |
2844 | rx_end = (__le32 *) (((u8 *) hdr) + len); | 2618 | rx_end = (__le32 *) (((u8 *) hdr) + len); |
2845 | } | 2619 | } |
2846 | if (len > priv->hw_params.max_pkt_size || len < 16) { | 2620 | /* In monitor mode allow 802.11 ACk frames (10 bytes) */ |
2621 | if (len > priv->hw_params.max_pkt_size || | ||
2622 | len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) { | ||
2847 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); | 2623 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); |
2848 | return; | 2624 | return; |
2849 | } | 2625 | } |
@@ -2854,7 +2630,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2854 | if (!include_phy) { | 2630 | if (!include_phy) { |
2855 | /* New status scheme, need to translate */ | 2631 | /* New status scheme, need to translate */ |
2856 | ampdu_status_legacy = ampdu_status; | 2632 | ampdu_status_legacy = ampdu_status; |
2857 | ampdu_status = iwl4965_translate_rx_status(ampdu_status); | 2633 | ampdu_status = iwl4965_translate_rx_status(priv, ampdu_status); |
2858 | } | 2634 | } |
2859 | 2635 | ||
2860 | /* start from MAC */ | 2636 | /* start from MAC */ |
@@ -2886,7 +2662,8 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2886 | } | 2662 | } |
2887 | 2663 | ||
2888 | /* Calc max signal level (dBm) among 3 possible receivers */ | 2664 | /* Calc max signal level (dBm) among 3 possible receivers */ |
2889 | static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp) | 2665 | static int iwl4965_calc_rssi(struct iwl_priv *priv, |
2666 | struct iwl4965_rx_phy_res *rx_resp) | ||
2890 | { | 2667 | { |
2891 | /* data from PHY/DSP regarding signal strength, etc., | 2668 | /* data from PHY/DSP regarding signal strength, etc., |
2892 | * contents are always there, not configurable by host. */ | 2669 | * contents are always there, not configurable by host. */ |
@@ -2930,7 +2707,7 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
2930 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 2707 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
2931 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 2708 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
2932 | 2709 | ||
2933 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 2710 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
2934 | } | 2711 | } |
2935 | 2712 | ||
2936 | static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | 2713 | static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) |
@@ -2963,7 +2740,7 @@ static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | |||
2963 | * proper operation with 4965. | 2740 | * proper operation with 4965. |
2964 | */ | 2741 | */ |
2965 | static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | 2742 | static void iwl4965_dbg_report_frame(struct iwl_priv *priv, |
2966 | struct iwl4965_rx_packet *pkt, | 2743 | struct iwl_rx_packet *pkt, |
2967 | struct ieee80211_hdr *header, int group100) | 2744 | struct ieee80211_hdr *header, int group100) |
2968 | { | 2745 | { |
2969 | u32 to_us; | 2746 | u32 to_us; |
@@ -2990,7 +2767,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2990 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); | 2767 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); |
2991 | u8 *data = IWL_RX_DATA(pkt); | 2768 | u8 *data = IWL_RX_DATA(pkt); |
2992 | 2769 | ||
2993 | if (likely(!(iwl_debug_level & IWL_DL_RX))) | 2770 | if (likely(!(priv->debug_level & IWL_DL_RX))) |
2994 | return; | 2771 | return; |
2995 | 2772 | ||
2996 | /* MAC header */ | 2773 | /* MAC header */ |
@@ -3093,11 +2870,11 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
3093 | } | 2870 | } |
3094 | } | 2871 | } |
3095 | if (print_dump) | 2872 | if (print_dump) |
3096 | iwl_print_hex_dump(IWL_DL_RX, data, length); | 2873 | iwl_print_hex_dump(priv, IWL_DL_RX, data, length); |
3097 | } | 2874 | } |
3098 | #else | 2875 | #else |
3099 | static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, | 2876 | static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, |
3100 | struct iwl4965_rx_packet *pkt, | 2877 | struct iwl_rx_packet *pkt, |
3101 | struct ieee80211_hdr *header, | 2878 | struct ieee80211_hdr *header, |
3102 | int group100) | 2879 | int group100) |
3103 | { | 2880 | { |
@@ -3109,11 +2886,11 @@ static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
3109 | /* Called for REPLY_RX (legacy ABG frames), or | 2886 | /* Called for REPLY_RX (legacy ABG frames), or |
3110 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 2887 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
3111 | static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | 2888 | static void iwl4965_rx_reply_rx(struct iwl_priv *priv, |
3112 | struct iwl4965_rx_mem_buffer *rxb) | 2889 | struct iwl_rx_mem_buffer *rxb) |
3113 | { | 2890 | { |
3114 | struct ieee80211_hdr *header; | 2891 | struct ieee80211_hdr *header; |
3115 | struct ieee80211_rx_status rx_status; | 2892 | struct ieee80211_rx_status rx_status; |
3116 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2893 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3117 | /* Use phy data (Rx signal strength, etc.) contained within | 2894 | /* Use phy data (Rx signal strength, etc.) contained within |
3118 | * this rx packet for legacy frames, | 2895 | * this rx packet for legacy frames, |
3119 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ | 2896 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ |
@@ -3186,7 +2963,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3186 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | 2963 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); |
3187 | 2964 | ||
3188 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 2965 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
3189 | rx_status.ssi = iwl4965_calc_rssi(rx_start); | 2966 | rx_status.signal = iwl4965_calc_rssi(priv, rx_start); |
3190 | 2967 | ||
3191 | /* Meaningful noise values are available only from beacon statistics, | 2968 | /* Meaningful noise values are available only from beacon statistics, |
3192 | * which are gathered only when associated, and indicate noise | 2969 | * which are gathered only when associated, and indicate noise |
@@ -3195,11 +2972,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3195 | if (iwl_is_associated(priv) && | 2972 | if (iwl_is_associated(priv) && |
3196 | !test_bit(STATUS_SCANNING, &priv->status)) { | 2973 | !test_bit(STATUS_SCANNING, &priv->status)) { |
3197 | rx_status.noise = priv->last_rx_noise; | 2974 | rx_status.noise = priv->last_rx_noise; |
3198 | rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, | 2975 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, |
3199 | rx_status.noise); | 2976 | rx_status.noise); |
3200 | } else { | 2977 | } else { |
3201 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 2978 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; |
3202 | rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0); | 2979 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0); |
3203 | } | 2980 | } |
3204 | 2981 | ||
3205 | /* Reset beacon noise level if not associated. */ | 2982 | /* Reset beacon noise level if not associated. */ |
@@ -3211,12 +2988,19 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3211 | iwl4965_dbg_report_frame(priv, pkt, header, 1); | 2988 | iwl4965_dbg_report_frame(priv, pkt, header, 1); |
3212 | 2989 | ||
3213 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", | 2990 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", |
3214 | rx_status.ssi, rx_status.noise, rx_status.signal, | 2991 | rx_status.signal, rx_status.noise, rx_status.signal, |
3215 | (unsigned long long)rx_status.mactime); | 2992 | (unsigned long long)rx_status.mactime); |
3216 | 2993 | ||
2994 | |||
2995 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
2996 | iwl4965_handle_data_packet(priv, 1, include_phy, | ||
2997 | rxb, &rx_status); | ||
2998 | return; | ||
2999 | } | ||
3000 | |||
3217 | network_packet = iwl4965_is_network_packet(priv, header); | 3001 | network_packet = iwl4965_is_network_packet(priv, header); |
3218 | if (network_packet) { | 3002 | if (network_packet) { |
3219 | priv->last_rx_rssi = rx_status.ssi; | 3003 | priv->last_rx_rssi = rx_status.signal; |
3220 | priv->last_beacon_time = priv->ucode_beacon_time; | 3004 | priv->last_beacon_time = priv->ucode_beacon_time; |
3221 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); | 3005 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); |
3222 | } | 3006 | } |
@@ -3278,19 +3062,19 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3278 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 3062 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
3279 | * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 3063 | * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
3280 | static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, | 3064 | static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, |
3281 | struct iwl4965_rx_mem_buffer *rxb) | 3065 | struct iwl_rx_mem_buffer *rxb) |
3282 | { | 3066 | { |
3283 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3067 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3284 | priv->last_phy_res[0] = 1; | 3068 | priv->last_phy_res[0] = 1; |
3285 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | 3069 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), |
3286 | sizeof(struct iwl4965_rx_phy_res)); | 3070 | sizeof(struct iwl4965_rx_phy_res)); |
3287 | } | 3071 | } |
3288 | static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, | 3072 | static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, |
3289 | struct iwl4965_rx_mem_buffer *rxb) | 3073 | struct iwl_rx_mem_buffer *rxb) |
3290 | 3074 | ||
3291 | { | 3075 | { |
3292 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 3076 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB |
3293 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3077 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3294 | struct iwl4965_missed_beacon_notif *missed_beacon; | 3078 | struct iwl4965_missed_beacon_notif *missed_beacon; |
3295 | 3079 | ||
3296 | missed_beacon = &pkt->u.missed_beacon; | 3080 | missed_beacon = &pkt->u.missed_beacon; |
@@ -3322,7 +3106,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, | |||
3322 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3106 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3323 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3107 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3324 | 3108 | ||
3325 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 3109 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
3326 | } | 3110 | } |
3327 | 3111 | ||
3328 | /** | 3112 | /** |
@@ -3332,7 +3116,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, | |||
3332 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. | 3116 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. |
3333 | */ | 3117 | */ |
3334 | static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, | 3118 | static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, |
3335 | struct iwl4965_ht_agg *agg, | 3119 | struct iwl_ht_agg *agg, |
3336 | struct iwl4965_compressed_ba_resp* | 3120 | struct iwl4965_compressed_ba_resp* |
3337 | ba_resp) | 3121 | ba_resp) |
3338 | 3122 | ||
@@ -3449,7 +3233,7 @@ int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, | |||
3449 | { | 3233 | { |
3450 | struct iwl4965_queue *q = &priv->txq[txq_id].q; | 3234 | struct iwl4965_queue *q = &priv->txq[txq_id].q; |
3451 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | 3235 | u8 *addr = priv->stations[sta_id].sta.sta.addr; |
3452 | struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; | 3236 | struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; |
3453 | 3237 | ||
3454 | switch (priv->stations[sta_id].tid[tid].agg.state) { | 3238 | switch (priv->stations[sta_id].tid[tid].agg.state) { |
3455 | case IWL_EMPTYING_HW_QUEUE_DELBA: | 3239 | case IWL_EMPTYING_HW_QUEUE_DELBA: |
@@ -3495,13 +3279,13 @@ static inline int iwl4965_queue_dec_wrap(int index, int n_bd) | |||
3495 | * of frames sent via aggregation. | 3279 | * of frames sent via aggregation. |
3496 | */ | 3280 | */ |
3497 | static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | 3281 | static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, |
3498 | struct iwl4965_rx_mem_buffer *rxb) | 3282 | struct iwl_rx_mem_buffer *rxb) |
3499 | { | 3283 | { |
3500 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3284 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3501 | struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 3285 | struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; |
3502 | int index; | 3286 | int index; |
3503 | struct iwl4965_tx_queue *txq = NULL; | 3287 | struct iwl_tx_queue *txq = NULL; |
3504 | struct iwl4965_ht_agg *agg; | 3288 | struct iwl_ht_agg *agg; |
3505 | DECLARE_MAC_BUF(mac); | 3289 | DECLARE_MAC_BUF(mac); |
3506 | 3290 | ||
3507 | /* "flow" corresponds to Tx queue */ | 3291 | /* "flow" corresponds to Tx queue */ |
@@ -3547,13 +3331,16 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
3547 | * block-ack window (we assume that they've been successfully | 3331 | * block-ack window (we assume that they've been successfully |
3548 | * transmitted ... if not, it's too late anyway). */ | 3332 | * transmitted ... if not, it's too late anyway). */ |
3549 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 3333 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
3334 | /* calculate mac80211 ampdu sw queue to wake */ | ||
3335 | int ampdu_q = | ||
3336 | scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; | ||
3550 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); | 3337 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); |
3551 | priv->stations[ba_resp->sta_id]. | 3338 | priv->stations[ba_resp->sta_id]. |
3552 | tid[ba_resp->tid].tfds_in_queue -= freed; | 3339 | tid[ba_resp->tid].tfds_in_queue -= freed; |
3553 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 3340 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
3554 | priv->mac80211_registered && | 3341 | priv->mac80211_registered && |
3555 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | 3342 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) |
3556 | ieee80211_wake_queue(priv->hw, scd_flow); | 3343 | ieee80211_wake_queue(priv->hw, ampdu_q); |
3557 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, | 3344 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, |
3558 | ba_resp->tid, scd_flow); | 3345 | ba_resp->tid, scd_flow); |
3559 | } | 3346 | } |
@@ -3714,103 +3501,6 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
3714 | 3501 | ||
3715 | #ifdef CONFIG_IWL4965_HT | 3502 | #ifdef CONFIG_IWL4965_HT |
3716 | 3503 | ||
3717 | static u8 iwl4965_is_channel_extension(struct iwl_priv *priv, | ||
3718 | enum ieee80211_band band, | ||
3719 | u16 channel, u8 extension_chan_offset) | ||
3720 | { | ||
3721 | const struct iwl_channel_info *ch_info; | ||
3722 | |||
3723 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
3724 | if (!is_channel_valid(ch_info)) | ||
3725 | return 0; | ||
3726 | |||
3727 | if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) | ||
3728 | return 0; | ||
3729 | |||
3730 | if ((ch_info->fat_extension_channel == extension_chan_offset) || | ||
3731 | (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) | ||
3732 | return 1; | ||
3733 | |||
3734 | return 0; | ||
3735 | } | ||
3736 | |||
3737 | static u8 iwl4965_is_fat_tx_allowed(struct iwl_priv *priv, | ||
3738 | struct ieee80211_ht_info *sta_ht_inf) | ||
3739 | { | ||
3740 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; | ||
3741 | |||
3742 | if ((!iwl_ht_conf->is_ht) || | ||
3743 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | ||
3744 | (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) | ||
3745 | return 0; | ||
3746 | |||
3747 | if (sta_ht_inf) { | ||
3748 | if ((!sta_ht_inf->ht_supported) || | ||
3749 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) | ||
3750 | return 0; | ||
3751 | } | ||
3752 | |||
3753 | return (iwl4965_is_channel_extension(priv, priv->band, | ||
3754 | iwl_ht_conf->control_channel, | ||
3755 | iwl_ht_conf->extension_chan_offset)); | ||
3756 | } | ||
3757 | |||
3758 | void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | ||
3759 | { | ||
3760 | struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; | ||
3761 | u32 val; | ||
3762 | |||
3763 | if (!ht_info->is_ht) | ||
3764 | return; | ||
3765 | |||
3766 | /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ | ||
3767 | if (iwl4965_is_fat_tx_allowed(priv, NULL)) | ||
3768 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
3769 | else | ||
3770 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | ||
3771 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | ||
3772 | |||
3773 | if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { | ||
3774 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", | ||
3775 | le16_to_cpu(rxon->channel), | ||
3776 | ht_info->control_channel); | ||
3777 | rxon->channel = cpu_to_le16(ht_info->control_channel); | ||
3778 | return; | ||
3779 | } | ||
3780 | |||
3781 | /* Note: control channel is opposite of extension channel */ | ||
3782 | switch (ht_info->extension_chan_offset) { | ||
3783 | case IWL_EXT_CHANNEL_OFFSET_ABOVE: | ||
3784 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
3785 | break; | ||
3786 | case IWL_EXT_CHANNEL_OFFSET_BELOW: | ||
3787 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
3788 | break; | ||
3789 | case IWL_EXT_CHANNEL_OFFSET_NONE: | ||
3790 | default: | ||
3791 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
3792 | break; | ||
3793 | } | ||
3794 | |||
3795 | val = ht_info->ht_protection; | ||
3796 | |||
3797 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); | ||
3798 | |||
3799 | iwl_set_rxon_chain(priv); | ||
3800 | |||
3801 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " | ||
3802 | "rxon flags 0x%X operation mode :0x%X " | ||
3803 | "extension channel offset 0x%x " | ||
3804 | "control chan %d\n", | ||
3805 | ht_info->supp_mcs_set[0], | ||
3806 | ht_info->supp_mcs_set[1], | ||
3807 | ht_info->supp_mcs_set[2], | ||
3808 | le32_to_cpu(rxon->flags), ht_info->ht_protection, | ||
3809 | ht_info->extension_chan_offset, | ||
3810 | ht_info->control_channel); | ||
3811 | return; | ||
3812 | } | ||
3813 | |||
3814 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | 3504 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, |
3815 | struct ieee80211_ht_info *sta_ht_inf) | 3505 | struct ieee80211_ht_info *sta_ht_inf) |
3816 | { | 3506 | { |
@@ -3846,7 +3536,7 @@ void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
3846 | sta_flags |= cpu_to_le32( | 3536 | sta_flags |= cpu_to_le32( |
3847 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | 3537 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); |
3848 | 3538 | ||
3849 | if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) | 3539 | if (iwl_is_fat_tx_allowed(priv, sta_ht_inf)) |
3850 | sta_flags |= STA_FLG_FAT_EN_MSK; | 3540 | sta_flags |= STA_FLG_FAT_EN_MSK; |
3851 | else | 3541 | else |
3852 | sta_flags &= ~STA_FLG_FAT_EN_MSK; | 3542 | sta_flags &= ~STA_FLG_FAT_EN_MSK; |
@@ -3874,7 +3564,7 @@ static int iwl4965_rx_agg_start(struct iwl_priv *priv, | |||
3874 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3564 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3875 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3565 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3876 | 3566 | ||
3877 | return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, | 3567 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, |
3878 | CMD_ASYNC); | 3568 | CMD_ASYNC); |
3879 | } | 3569 | } |
3880 | 3570 | ||
@@ -3895,7 +3585,7 @@ static int iwl4965_rx_agg_stop(struct iwl_priv *priv, | |||
3895 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3585 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3896 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3586 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3897 | 3587 | ||
3898 | return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, | 3588 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, |
3899 | CMD_ASYNC); | 3589 | CMD_ASYNC); |
3900 | } | 3590 | } |
3901 | 3591 | ||
@@ -3925,7 +3615,7 @@ static int iwl4965_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, | |||
3925 | int ssn = -1; | 3615 | int ssn = -1; |
3926 | int ret = 0; | 3616 | int ret = 0; |
3927 | unsigned long flags; | 3617 | unsigned long flags; |
3928 | struct iwl4965_tid_data *tid_data; | 3618 | struct iwl_tid_data *tid_data; |
3929 | DECLARE_MAC_BUF(mac); | 3619 | DECLARE_MAC_BUF(mac); |
3930 | 3620 | ||
3931 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | 3621 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) |
@@ -3978,7 +3668,7 @@ static int iwl4965_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid) | |||
3978 | { | 3668 | { |
3979 | struct iwl_priv *priv = hw->priv; | 3669 | struct iwl_priv *priv = hw->priv; |
3980 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 3670 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
3981 | struct iwl4965_tid_data *tid_data; | 3671 | struct iwl_tid_data *tid_data; |
3982 | int ret, write_ptr, read_ptr; | 3672 | int ret, write_ptr, read_ptr; |
3983 | unsigned long flags; | 3673 | unsigned long flags; |
3984 | DECLARE_MAC_BUF(mac); | 3674 | DECLARE_MAC_BUF(mac); |
@@ -4060,9 +3750,26 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
4060 | } | 3750 | } |
4061 | return 0; | 3751 | return 0; |
4062 | } | 3752 | } |
4063 | |||
4064 | #endif /* CONFIG_IWL4965_HT */ | 3753 | #endif /* CONFIG_IWL4965_HT */ |
4065 | 3754 | ||
3755 | |||
3756 | static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | ||
3757 | { | ||
3758 | struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; | ||
3759 | addsta->mode = cmd->mode; | ||
3760 | memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); | ||
3761 | memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); | ||
3762 | addsta->station_flags = cmd->station_flags; | ||
3763 | addsta->station_flags_msk = cmd->station_flags_msk; | ||
3764 | addsta->tid_disable_tx = cmd->tid_disable_tx; | ||
3765 | addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; | ||
3766 | addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; | ||
3767 | addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; | ||
3768 | addsta->reserved1 = __constant_cpu_to_le16(0); | ||
3769 | addsta->reserved2 = __constant_cpu_to_le32(0); | ||
3770 | |||
3771 | return (u16)sizeof(struct iwl4965_addsta_cmd); | ||
3772 | } | ||
4066 | /* Set up 4965-specific Rx frame reply handlers */ | 3773 | /* Set up 4965-specific Rx frame reply handlers */ |
4067 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) | 3774 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) |
4068 | { | 3775 | { |
@@ -4106,6 +3813,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { | |||
4106 | 3813 | ||
4107 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | 3814 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { |
4108 | .enqueue_hcmd = iwl4965_enqueue_hcmd, | 3815 | .enqueue_hcmd = iwl4965_enqueue_hcmd, |
3816 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, | ||
4109 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 3817 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB |
4110 | .chain_noise_reset = iwl4965_chain_noise_reset, | 3818 | .chain_noise_reset = iwl4965_chain_noise_reset, |
4111 | .gain_computation = iwl4965_gain_computation, | 3819 | .gain_computation = iwl4965_gain_computation, |
@@ -4116,11 +3824,13 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
4116 | .set_hw_params = iwl4965_hw_set_hw_params, | 3824 | .set_hw_params = iwl4965_hw_set_hw_params, |
4117 | .alloc_shared_mem = iwl4965_alloc_shared_mem, | 3825 | .alloc_shared_mem = iwl4965_alloc_shared_mem, |
4118 | .free_shared_mem = iwl4965_free_shared_mem, | 3826 | .free_shared_mem = iwl4965_free_shared_mem, |
3827 | .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, | ||
4119 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, | 3828 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, |
4120 | .hw_nic_init = iwl4965_hw_nic_init, | 3829 | .disable_tx_fifo = iwl4965_disable_tx_fifo, |
4121 | .rx_handler_setup = iwl4965_rx_handler_setup, | 3830 | .rx_handler_setup = iwl4965_rx_handler_setup, |
4122 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | 3831 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, |
4123 | .alive_notify = iwl4965_alive_notify, | 3832 | .alive_notify = iwl4965_alive_notify, |
3833 | .init_alive_start = iwl4965_init_alive_start, | ||
4124 | .load_ucode = iwl4965_load_bsm, | 3834 | .load_ucode = iwl4965_load_bsm, |
4125 | .apm_ops = { | 3835 | .apm_ops = { |
4126 | .init = iwl4965_apm_init, | 3836 | .init = iwl4965_apm_init, |
@@ -4183,4 +3893,5 @@ module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); | |||
4183 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); | 3893 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); |
4184 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); | 3894 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); |
4185 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | 3895 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); |
4186 | 3896 | module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444); | |
3897 | MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error"); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 0d8ef63f8713..b5e28b811796 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -86,7 +86,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv) | |||
86 | return ret; | 86 | return ret; |
87 | } | 87 | } |
88 | 88 | ||
89 | static void iwl5000_nic_init(struct iwl_priv *priv) | 89 | static void iwl5000_nic_config(struct iwl_priv *priv) |
90 | { | 90 | { |
91 | unsigned long flags; | 91 | unsigned long flags; |
92 | u16 radio_cfg; | 92 | u16 radio_cfg; |
@@ -362,6 +362,8 @@ static int iwl5000_alloc_shared_mem(struct iwl_priv *priv) | |||
362 | 362 | ||
363 | memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared)); | 363 | memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared)); |
364 | 364 | ||
365 | priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed); | ||
366 | |||
365 | return 0; | 367 | return 0; |
366 | } | 368 | } |
367 | 369 | ||
@@ -374,11 +376,17 @@ static void iwl5000_free_shared_mem(struct iwl_priv *priv) | |||
374 | priv->shared_phys); | 376 | priv->shared_phys); |
375 | } | 377 | } |
376 | 378 | ||
379 | static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv) | ||
380 | { | ||
381 | struct iwl5000_shared *s = priv->shared_virt; | ||
382 | return le32_to_cpu(s->rb_closed) & 0xFFF; | ||
383 | } | ||
384 | |||
377 | /** | 385 | /** |
378 | * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 386 | * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
379 | */ | 387 | */ |
380 | static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | 388 | static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, |
381 | struct iwl4965_tx_queue *txq, | 389 | struct iwl_tx_queue *txq, |
382 | u16 byte_cnt) | 390 | u16 byte_cnt) |
383 | { | 391 | { |
384 | struct iwl5000_shared *shared_data = priv->shared_virt; | 392 | struct iwl5000_shared *shared_data = priv->shared_virt; |
@@ -422,10 +430,40 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
422 | } | 430 | } |
423 | } | 431 | } |
424 | 432 | ||
433 | static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | ||
434 | { | ||
435 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); | ||
436 | memcpy(data, cmd, size); | ||
437 | return size; | ||
438 | } | ||
439 | |||
440 | |||
441 | static int iwl5000_disable_tx_fifo(struct iwl_priv *priv) | ||
442 | { | ||
443 | unsigned long flags; | ||
444 | int ret; | ||
445 | |||
446 | spin_lock_irqsave(&priv->lock, flags); | ||
447 | |||
448 | ret = iwl_grab_nic_access(priv); | ||
449 | if (unlikely(ret)) { | ||
450 | IWL_ERROR("Tx fifo reset failed"); | ||
451 | spin_unlock_irqrestore(&priv->lock, flags); | ||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | iwl_write_prph(priv, IWL50_SCD_TXFACT, 0); | ||
456 | iwl_release_nic_access(priv); | ||
457 | spin_unlock_irqrestore(&priv->lock, flags); | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
425 | static struct iwl_hcmd_ops iwl5000_hcmd = { | 462 | static struct iwl_hcmd_ops iwl5000_hcmd = { |
426 | }; | 463 | }; |
427 | 464 | ||
428 | static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { | 465 | static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { |
466 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, | ||
429 | #ifdef CONFIG_IWL5000_RUN_TIME_CALIB | 467 | #ifdef CONFIG_IWL5000_RUN_TIME_CALIB |
430 | .gain_computation = iwl5000_gain_computation, | 468 | .gain_computation = iwl5000_gain_computation, |
431 | .chain_noise_reset = iwl5000_chain_noise_reset, | 469 | .chain_noise_reset = iwl5000_chain_noise_reset, |
@@ -436,10 +474,12 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
436 | .set_hw_params = iwl5000_hw_set_hw_params, | 474 | .set_hw_params = iwl5000_hw_set_hw_params, |
437 | .alloc_shared_mem = iwl5000_alloc_shared_mem, | 475 | .alloc_shared_mem = iwl5000_alloc_shared_mem, |
438 | .free_shared_mem = iwl5000_free_shared_mem, | 476 | .free_shared_mem = iwl5000_free_shared_mem, |
477 | .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx, | ||
439 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, | 478 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, |
479 | .disable_tx_fifo = iwl5000_disable_tx_fifo, | ||
440 | .apm_ops = { | 480 | .apm_ops = { |
441 | .init = iwl5000_apm_init, | 481 | .init = iwl5000_apm_init, |
442 | .config = iwl5000_nic_init, | 482 | .config = iwl5000_nic_config, |
443 | .set_pwr_src = iwl4965_set_pwr_src, | 483 | .set_pwr_src = iwl4965_set_pwr_src, |
444 | }, | 484 | }, |
445 | .eeprom_ops = { | 485 | .eeprom_ops = { |
@@ -470,6 +510,7 @@ static struct iwl_mod_params iwl50_mod_params = { | |||
470 | .num_of_queues = IWL50_NUM_QUEUES, | 510 | .num_of_queues = IWL50_NUM_QUEUES, |
471 | .enable_qos = 1, | 511 | .enable_qos = 1, |
472 | .amsdu_size_8K = 1, | 512 | .amsdu_size_8K = 1, |
513 | .restart_fw = 1, | ||
473 | /* the rest are 0 by default */ | 514 | /* the rest are 0 by default */ |
474 | }; | 515 | }; |
475 | 516 | ||
@@ -515,5 +556,5 @@ module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444); | |||
515 | MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); | 556 | MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); |
516 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); | 557 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); |
517 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); | 558 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); |
518 | 559 | module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); | |
519 | 560 | MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); | |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 5afa7b79b59d..d16a853f376a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -769,6 +769,20 @@ struct iwl4965_keyinfo { | |||
769 | u8 key[16]; /* 16-byte unicast decryption key */ | 769 | u8 key[16]; /* 16-byte unicast decryption key */ |
770 | } __attribute__ ((packed)); | 770 | } __attribute__ ((packed)); |
771 | 771 | ||
772 | /* 5000 */ | ||
773 | struct iwl_keyinfo { | ||
774 | __le16 key_flags; | ||
775 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | ||
776 | u8 reserved1; | ||
777 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | ||
778 | u8 key_offset; | ||
779 | u8 reserved2; | ||
780 | u8 key[16]; /* 16-byte unicast decryption key */ | ||
781 | __le64 tx_secur_seq_cnt; | ||
782 | __le64 hw_tkip_mic_rx_key; | ||
783 | __le64 hw_tkip_mic_tx_key; | ||
784 | } __attribute__ ((packed)); | ||
785 | |||
772 | /** | 786 | /** |
773 | * struct sta_id_modify | 787 | * struct sta_id_modify |
774 | * @addr[ETH_ALEN]: station's MAC address | 788 | * @addr[ETH_ALEN]: station's MAC address |
@@ -844,6 +858,38 @@ struct iwl4965_addsta_cmd { | |||
844 | __le32 reserved2; | 858 | __le32 reserved2; |
845 | } __attribute__ ((packed)); | 859 | } __attribute__ ((packed)); |
846 | 860 | ||
861 | /* 5000 */ | ||
862 | struct iwl_addsta_cmd { | ||
863 | u8 mode; /* 1: modify existing, 0: add new station */ | ||
864 | u8 reserved[3]; | ||
865 | struct sta_id_modify sta; | ||
866 | struct iwl_keyinfo key; | ||
867 | __le32 station_flags; /* STA_FLG_* */ | ||
868 | __le32 station_flags_msk; /* STA_FLG_* */ | ||
869 | |||
870 | /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) | ||
871 | * corresponding to bit (e.g. bit 5 controls TID 5). | ||
872 | * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ | ||
873 | __le16 tid_disable_tx; | ||
874 | |||
875 | __le16 reserved1; | ||
876 | |||
877 | /* TID for which to add block-ack support. | ||
878 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
879 | u8 add_immediate_ba_tid; | ||
880 | |||
881 | /* TID for which to remove block-ack support. | ||
882 | * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ | ||
883 | u8 remove_immediate_ba_tid; | ||
884 | |||
885 | /* Starting Sequence Number for added block-ack support. | ||
886 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
887 | __le16 add_immediate_ba_ssn; | ||
888 | |||
889 | __le32 reserved2; | ||
890 | } __attribute__ ((packed)); | ||
891 | |||
892 | |||
847 | #define ADD_STA_SUCCESS_MSK 0x1 | 893 | #define ADD_STA_SUCCESS_MSK 0x1 |
848 | #define ADD_STA_NO_ROOM_IN_TABLE 0x2 | 894 | #define ADD_STA_NO_ROOM_IN_TABLE 0x2 |
849 | #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 | 895 | #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 |
@@ -2731,7 +2777,7 @@ struct iwl4965_led_cmd { | |||
2731 | * | 2777 | * |
2732 | *****************************************************************************/ | 2778 | *****************************************************************************/ |
2733 | 2779 | ||
2734 | struct iwl4965_rx_packet { | 2780 | struct iwl_rx_packet { |
2735 | __le32 len; | 2781 | __le32 len; |
2736 | struct iwl_cmd_header hdr; | 2782 | struct iwl_cmd_header hdr; |
2737 | union { | 2783 | union { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c4b5c1a100f2..d3cbad2bf877 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -46,11 +46,6 @@ MODULE_VERSION(IWLWIFI_VERSION); | |||
46 | MODULE_AUTHOR(DRV_COPYRIGHT); | 46 | MODULE_AUTHOR(DRV_COPYRIGHT); |
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | 48 | ||
49 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
50 | u32 iwl_debug_level; | ||
51 | EXPORT_SYMBOL(iwl_debug_level); | ||
52 | #endif | ||
53 | |||
54 | #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ | 49 | #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ |
55 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | 50 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ |
56 | IWL_RATE_SISO_##s##M_PLCP, \ | 51 | IWL_RATE_SISO_##s##M_PLCP, \ |
@@ -121,6 +116,100 @@ void iwl_hw_detect(struct iwl_priv *priv) | |||
121 | } | 116 | } |
122 | EXPORT_SYMBOL(iwl_hw_detect); | 117 | EXPORT_SYMBOL(iwl_hw_detect); |
123 | 118 | ||
119 | /* Tell nic where to find the "keep warm" buffer */ | ||
120 | int iwl_kw_init(struct iwl_priv *priv) | ||
121 | { | ||
122 | unsigned long flags; | ||
123 | int ret; | ||
124 | |||
125 | spin_lock_irqsave(&priv->lock, flags); | ||
126 | ret = iwl_grab_nic_access(priv); | ||
127 | if (ret) | ||
128 | goto out; | ||
129 | |||
130 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, | ||
131 | priv->kw.dma_addr >> 4); | ||
132 | iwl_release_nic_access(priv); | ||
133 | out: | ||
134 | spin_unlock_irqrestore(&priv->lock, flags); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | int iwl_kw_alloc(struct iwl_priv *priv) | ||
139 | { | ||
140 | struct pci_dev *dev = priv->pci_dev; | ||
141 | struct iwl_kw *kw = &priv->kw; | ||
142 | |||
143 | kw->size = IWL_KW_SIZE; | ||
144 | kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); | ||
145 | if (!kw->v_addr) | ||
146 | return -ENOMEM; | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * iwl_kw_free - Free the "keep warm" buffer | ||
153 | */ | ||
154 | void iwl_kw_free(struct iwl_priv *priv) | ||
155 | { | ||
156 | struct pci_dev *dev = priv->pci_dev; | ||
157 | struct iwl_kw *kw = &priv->kw; | ||
158 | |||
159 | if (kw->v_addr) { | ||
160 | pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); | ||
161 | memset(kw, 0, sizeof(*kw)); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | int iwl_hw_nic_init(struct iwl_priv *priv) | ||
166 | { | ||
167 | unsigned long flags; | ||
168 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
169 | int ret; | ||
170 | |||
171 | /* nic_init */ | ||
172 | spin_lock_irqsave(&priv->lock, flags); | ||
173 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
174 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | ||
175 | spin_unlock_irqrestore(&priv->lock, flags); | ||
176 | |||
177 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
178 | |||
179 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
180 | |||
181 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
182 | if (!rxq->bd) { | ||
183 | ret = iwl_rx_queue_alloc(priv); | ||
184 | if (ret) { | ||
185 | IWL_ERROR("Unable to initialize Rx queue\n"); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | } else | ||
189 | iwl_rx_queue_reset(priv, rxq); | ||
190 | |||
191 | iwl_rx_replenish(priv); | ||
192 | |||
193 | iwl_rx_init(priv, rxq); | ||
194 | |||
195 | spin_lock_irqsave(&priv->lock, flags); | ||
196 | |||
197 | rxq->need_update = 1; | ||
198 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
199 | |||
200 | spin_unlock_irqrestore(&priv->lock, flags); | ||
201 | |||
202 | /* Allocate and init all Tx and Command queues */ | ||
203 | ret = iwl_txq_ctx_reset(priv); | ||
204 | if (ret) | ||
205 | return ret; | ||
206 | |||
207 | set_bit(STATUS_INIT, &priv->status); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | EXPORT_SYMBOL(iwl_hw_nic_init); | ||
212 | |||
124 | /** | 213 | /** |
125 | * iwlcore_clear_stations_table - Clear the driver's station table | 214 | * iwlcore_clear_stations_table - Clear the driver's station table |
126 | * | 215 | * |
@@ -259,6 +348,12 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
259 | if (priv->hw_params.tx_chains_num >= 3) | 348 | if (priv->hw_params.tx_chains_num >= 3) |
260 | ht_info->supp_mcs_set[2] = 0xFF; | 349 | ht_info->supp_mcs_set[2] = 0xFF; |
261 | } | 350 | } |
351 | #else | ||
352 | static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | ||
353 | struct ieee80211_ht_info *ht_info, | ||
354 | enum ieee80211_band band) | ||
355 | { | ||
356 | } | ||
262 | #endif /* CONFIG_IWL4965_HT */ | 357 | #endif /* CONFIG_IWL4965_HT */ |
263 | 358 | ||
264 | static void iwlcore_init_hw_rates(struct iwl_priv *priv, | 359 | static void iwlcore_init_hw_rates(struct iwl_priv *priv, |
@@ -428,6 +523,105 @@ static u8 is_single_rx_stream(struct iwl_priv *priv) | |||
428 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || | 523 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || |
429 | priv->ps_mode == IWL_MIMO_PS_STATIC; | 524 | priv->ps_mode == IWL_MIMO_PS_STATIC; |
430 | } | 525 | } |
526 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, | ||
527 | enum ieee80211_band band, | ||
528 | u16 channel, u8 extension_chan_offset) | ||
529 | { | ||
530 | const struct iwl_channel_info *ch_info; | ||
531 | |||
532 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
533 | if (!is_channel_valid(ch_info)) | ||
534 | return 0; | ||
535 | |||
536 | if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) | ||
537 | return 0; | ||
538 | |||
539 | if ((ch_info->fat_extension_channel == extension_chan_offset) || | ||
540 | (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) | ||
541 | return 1; | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | ||
547 | struct ieee80211_ht_info *sta_ht_inf) | ||
548 | { | ||
549 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; | ||
550 | |||
551 | if ((!iwl_ht_conf->is_ht) || | ||
552 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | ||
553 | (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) | ||
554 | return 0; | ||
555 | |||
556 | if (sta_ht_inf) { | ||
557 | if ((!sta_ht_inf->ht_supported) || | ||
558 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | return iwl_is_channel_extension(priv, priv->band, | ||
563 | iwl_ht_conf->control_channel, | ||
564 | iwl_ht_conf->extension_chan_offset); | ||
565 | } | ||
566 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); | ||
567 | |||
568 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | ||
569 | { | ||
570 | struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; | ||
571 | u32 val; | ||
572 | |||
573 | if (!ht_info->is_ht) | ||
574 | return; | ||
575 | |||
576 | /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ | ||
577 | if (iwl_is_fat_tx_allowed(priv, NULL)) | ||
578 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
579 | else | ||
580 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | ||
581 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | ||
582 | |||
583 | if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { | ||
584 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", | ||
585 | le16_to_cpu(rxon->channel), | ||
586 | ht_info->control_channel); | ||
587 | rxon->channel = cpu_to_le16(ht_info->control_channel); | ||
588 | return; | ||
589 | } | ||
590 | |||
591 | /* Note: control channel is opposite of extension channel */ | ||
592 | switch (ht_info->extension_chan_offset) { | ||
593 | case IWL_EXT_CHANNEL_OFFSET_ABOVE: | ||
594 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
595 | break; | ||
596 | case IWL_EXT_CHANNEL_OFFSET_BELOW: | ||
597 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
598 | break; | ||
599 | case IWL_EXT_CHANNEL_OFFSET_NONE: | ||
600 | default: | ||
601 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
602 | break; | ||
603 | } | ||
604 | |||
605 | val = ht_info->ht_protection; | ||
606 | |||
607 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); | ||
608 | |||
609 | iwl_set_rxon_chain(priv); | ||
610 | |||
611 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " | ||
612 | "rxon flags 0x%X operation mode :0x%X " | ||
613 | "extension channel offset 0x%x " | ||
614 | "control chan %d\n", | ||
615 | ht_info->supp_mcs_set[0], | ||
616 | ht_info->supp_mcs_set[1], | ||
617 | ht_info->supp_mcs_set[2], | ||
618 | le32_to_cpu(rxon->flags), ht_info->ht_protection, | ||
619 | ht_info->extension_chan_offset, | ||
620 | ht_info->control_channel); | ||
621 | return; | ||
622 | } | ||
623 | EXPORT_SYMBOL(iwl_set_rxon_ht); | ||
624 | |||
431 | #else | 625 | #else |
432 | static inline u8 is_single_rx_stream(struct iwl_priv *priv) | 626 | static inline u8 is_single_rx_stream(struct iwl_priv *priv) |
433 | { | 627 | { |
@@ -552,18 +746,10 @@ static void iwlcore_init_hw(struct iwl_priv *priv) | |||
552 | struct ieee80211_hw *hw = priv->hw; | 746 | struct ieee80211_hw *hw = priv->hw; |
553 | hw->rate_control_algorithm = "iwl-4965-rs"; | 747 | hw->rate_control_algorithm = "iwl-4965-rs"; |
554 | 748 | ||
555 | /* Tell mac80211 and its clients (e.g. Wireless Extensions) | 749 | /* Tell mac80211 our characteristics */ |
556 | * the range of signal quality values that we'll provide. | 750 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
557 | * Negative values for level/noise indicate that we'll provide dBm. | 751 | IEEE80211_HW_SIGNAL_DBM | |
558 | * For WE, at least, non-0 values here *enable* display of values | 752 | IEEE80211_HW_NOISE_DBM; |
559 | * in app (iwconfig). */ | ||
560 | hw->max_rssi = -20; /* signal level, negative indicates dBm */ | ||
561 | hw->max_noise = -20; /* noise level, negative indicates dBm */ | ||
562 | hw->max_signal = 100; /* link quality indication (%) */ | ||
563 | |||
564 | /* Tell mac80211 our Tx characteristics */ | ||
565 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | ||
566 | |||
567 | /* Default value; 4 EDCA QOS priorities */ | 753 | /* Default value; 4 EDCA QOS priorities */ |
568 | hw->queues = 4; | 754 | hw->queues = 4; |
569 | #ifdef CONFIG_IWL4965_HT | 755 | #ifdef CONFIG_IWL4965_HT |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 369f1821584f..e139c8ffa9a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -87,6 +87,7 @@ struct iwl_hcmd_ops { | |||
87 | }; | 87 | }; |
88 | struct iwl_hcmd_utils_ops { | 88 | struct iwl_hcmd_utils_ops { |
89 | int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 89 | int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
90 | u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); | ||
90 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | 91 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB |
91 | void (*gain_computation)(struct iwl_priv *priv, | 92 | void (*gain_computation)(struct iwl_priv *priv, |
92 | u32 *average_noise, | 93 | u32 *average_noise, |
@@ -102,13 +103,16 @@ struct iwl_lib_ops { | |||
102 | /* ucode shared memory */ | 103 | /* ucode shared memory */ |
103 | int (*alloc_shared_mem)(struct iwl_priv *priv); | 104 | int (*alloc_shared_mem)(struct iwl_priv *priv); |
104 | void (*free_shared_mem)(struct iwl_priv *priv); | 105 | void (*free_shared_mem)(struct iwl_priv *priv); |
106 | int (*shared_mem_rx_idx)(struct iwl_priv *priv); | ||
105 | void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, | 107 | void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, |
106 | struct iwl4965_tx_queue *txq, | 108 | struct iwl_tx_queue *txq, |
107 | u16 byte_cnt); | 109 | u16 byte_cnt); |
108 | /* setup Rx handler */ | 110 | /* setup Rx handler */ |
109 | void (*rx_handler_setup)(struct iwl_priv *priv); | 111 | void (*rx_handler_setup)(struct iwl_priv *priv); |
110 | /* nic init */ | 112 | /* nic Tx fifo handling */ |
111 | int (*hw_nic_init)(struct iwl_priv *priv); | 113 | int (*disable_tx_fifo)(struct iwl_priv *priv); |
114 | /* alive notification after init uCode load */ | ||
115 | void (*init_alive_start)(struct iwl_priv *priv); | ||
112 | /* alive notification */ | 116 | /* alive notification */ |
113 | int (*alive_notify)(struct iwl_priv *priv); | 117 | int (*alive_notify)(struct iwl_priv *priv); |
114 | /* check validity of rtc data address */ | 118 | /* check validity of rtc data address */ |
@@ -145,6 +149,7 @@ struct iwl_mod_params { | |||
145 | int enable_qos; /* def: 1 = use quality of service */ | 149 | int enable_qos; /* def: 1 = use quality of service */ |
146 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ | 150 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ |
147 | int antenna; /* def: 0 = both antennas (use diversity) */ | 151 | int antenna; /* def: 0 = both antennas (use diversity) */ |
152 | int restart_fw; /* def: 1 = restart firmware */ | ||
148 | }; | 153 | }; |
149 | 154 | ||
150 | struct iwl_cfg { | 155 | struct iwl_cfg { |
@@ -172,6 +177,39 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, | |||
172 | u16 channel); | 177 | u16 channel); |
173 | void iwlcore_free_geos(struct iwl_priv *priv); | 178 | void iwlcore_free_geos(struct iwl_priv *priv); |
174 | int iwl_setup(struct iwl_priv *priv); | 179 | int iwl_setup(struct iwl_priv *priv); |
180 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); | ||
181 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | ||
182 | struct ieee80211_ht_info *sta_ht_inf); | ||
183 | int iwl_hw_nic_init(struct iwl_priv *priv); | ||
184 | |||
185 | /* "keep warm" functions */ | ||
186 | int iwl_kw_init(struct iwl_priv *priv); | ||
187 | int iwl_kw_alloc(struct iwl_priv *priv); | ||
188 | void iwl_kw_free(struct iwl_priv *priv); | ||
189 | |||
190 | /***************************************************** | ||
191 | * RX | ||
192 | ******************************************************/ | ||
193 | void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
194 | int iwl_rx_queue_alloc(struct iwl_priv *priv); | ||
195 | void iwl_rx_handle(struct iwl_priv *priv); | ||
196 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | ||
197 | struct iwl_rx_queue *q); | ||
198 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
199 | void iwl_rx_replenish(struct iwl_priv *priv); | ||
200 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
201 | /* FIXME: remove when TX is moved to iwl core */ | ||
202 | int iwl_rx_queue_restock(struct iwl_priv *priv); | ||
203 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | ||
204 | void iwl_rx_allocate(struct iwl_priv *priv); | ||
205 | |||
206 | /***************************************************** | ||
207 | * TX | ||
208 | ******************************************************/ | ||
209 | int iwl_txq_ctx_reset(struct iwl_priv *priv); | ||
210 | /* FIXME: remove when free Tx is fully merged into iwlcore */ | ||
211 | int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | ||
212 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | ||
175 | 213 | ||
176 | /***************************************************** | 214 | /***************************************************** |
177 | * S e n d i n g H o s t C o m m a n d s * | 215 | * S e n d i n g H o s t C o m m a n d s * |
@@ -265,4 +303,5 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | |||
265 | return priv->cfg->ops->hcmd->rxon_assoc(priv); | 303 | return priv->cfg->ops->hcmd->rxon_assoc(priv); |
266 | } | 304 | } |
267 | 305 | ||
306 | |||
268 | #endif /* __iwl_core_h__ */ | 307 | #endif /* __iwl_core_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index c60724c21db8..2f24594c5fea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -30,26 +30,16 @@ | |||
30 | #define __iwl_debug_h__ | 30 | #define __iwl_debug_h__ |
31 | 31 | ||
32 | #ifdef CONFIG_IWLWIFI_DEBUG | 32 | #ifdef CONFIG_IWLWIFI_DEBUG |
33 | extern u32 iwl_debug_level; | ||
34 | #define IWL_DEBUG(level, fmt, args...) \ | 33 | #define IWL_DEBUG(level, fmt, args...) \ |
35 | do { if (iwl_debug_level & (level)) \ | 34 | do { if (priv->debug_level & (level)) \ |
36 | printk(KERN_ERR DRV_NAME": %c %s " fmt, \ | 35 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ |
37 | in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) | 36 | in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) |
38 | 37 | ||
39 | #define IWL_DEBUG_LIMIT(level, fmt, args...) \ | 38 | #define IWL_DEBUG_LIMIT(level, fmt, args...) \ |
40 | do { if ((iwl_debug_level & (level)) && net_ratelimit()) \ | 39 | do { if ((priv->debug_level & (level)) && net_ratelimit()) \ |
41 | printk(KERN_ERR DRV_NAME": %c %s " fmt, \ | 40 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ |
42 | in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) | 41 | in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) |
43 | 42 | ||
44 | static inline void iwl_print_hex_dump(int level, void *p, u32 len) | ||
45 | { | ||
46 | if (!(iwl_debug_level & level)) | ||
47 | return; | ||
48 | |||
49 | print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
50 | p, len, 1); | ||
51 | } | ||
52 | |||
53 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 43 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
54 | struct iwl_debugfs { | 44 | struct iwl_debugfs { |
55 | const char *name; | 45 | const char *name; |
@@ -57,6 +47,7 @@ struct iwl_debugfs { | |||
57 | struct dentry *dir_data; | 47 | struct dentry *dir_data; |
58 | struct dir_data_files{ | 48 | struct dir_data_files{ |
59 | struct dentry *file_sram; | 49 | struct dentry *file_sram; |
50 | struct dentry *file_eeprom; | ||
60 | struct dentry *file_stations; | 51 | struct dentry *file_stations; |
61 | struct dentry *file_rx_statistics; | 52 | struct dentry *file_rx_statistics; |
62 | struct dentry *file_tx_statistics; | 53 | struct dentry *file_tx_statistics; |
@@ -76,9 +67,6 @@ static inline void IWL_DEBUG(int level, const char *fmt, ...) | |||
76 | static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) | 67 | static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) |
77 | { | 68 | { |
78 | } | 69 | } |
79 | static inline void iwl_print_hex_dump(int level, void *p, u32 len) | ||
80 | { | ||
81 | } | ||
82 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 70 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
83 | 71 | ||
84 | 72 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 30914453de1e..ad25806dfaf1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -206,7 +206,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
206 | size_t count, loff_t *ppos) | 206 | size_t count, loff_t *ppos) |
207 | { | 207 | { |
208 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 208 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
209 | struct iwl4965_station_entry *station; | 209 | struct iwl_station_entry *station; |
210 | int max_sta = priv->hw_params.max_stations; | 210 | int max_sta = priv->hw_params.max_stations; |
211 | char *buf; | 211 | char *buf; |
212 | int i, j, pos = 0; | 212 | int i, j, pos = 0; |
@@ -277,8 +277,48 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
277 | return ret; | 277 | return ret; |
278 | } | 278 | } |
279 | 279 | ||
280 | static ssize_t iwl_dbgfs_eeprom_read(struct file *file, | ||
281 | char __user *user_buf, | ||
282 | size_t count, | ||
283 | loff_t *ppos) | ||
284 | { | ||
285 | ssize_t ret; | ||
286 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
287 | int pos = 0, ofs = 0, buf_size = 0; | ||
288 | const u8 *ptr; | ||
289 | char *buf; | ||
290 | size_t eeprom_len = priv->cfg->eeprom_size; | ||
291 | buf_size = 4 * eeprom_len + 256; | ||
292 | |||
293 | if (eeprom_len % 16) { | ||
294 | IWL_ERROR("EEPROM size is not multiple of 16.\n"); | ||
295 | return -ENODATA; | ||
296 | } | ||
297 | |||
298 | /* 4 characters for byte 0xYY */ | ||
299 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
300 | if (!buf) { | ||
301 | IWL_ERROR("Can not allocate Buffer\n"); | ||
302 | return -ENOMEM; | ||
303 | } | ||
304 | |||
305 | ptr = priv->eeprom; | ||
306 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | ||
307 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | ||
308 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, | ||
309 | buf_size - pos, 0); | ||
310 | pos += strlen(buf); | ||
311 | if (buf_size - pos > 0) | ||
312 | buf[pos++] = '\n'; | ||
313 | } | ||
314 | |||
315 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
316 | kfree(buf); | ||
317 | return ret; | ||
318 | } | ||
280 | 319 | ||
281 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 320 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
321 | DEBUGFS_READ_FILE_OPS(eeprom); | ||
282 | DEBUGFS_READ_FILE_OPS(stations); | 322 | DEBUGFS_READ_FILE_OPS(stations); |
283 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 323 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
284 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 324 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
@@ -304,6 +344,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
304 | } | 344 | } |
305 | 345 | ||
306 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); | 346 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); |
347 | DEBUGFS_ADD_FILE(eeprom, data); | ||
307 | DEBUGFS_ADD_FILE(sram, data); | 348 | DEBUGFS_ADD_FILE(sram, data); |
308 | DEBUGFS_ADD_FILE(stations, data); | 349 | DEBUGFS_ADD_FILE(stations, data); |
309 | DEBUGFS_ADD_FILE(rx_statistics, data); | 350 | DEBUGFS_ADD_FILE(rx_statistics, data); |
@@ -327,6 +368,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
327 | if (!(priv->dbgfs)) | 368 | if (!(priv->dbgfs)) |
328 | return; | 369 | return; |
329 | 370 | ||
371 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); | ||
330 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); | 372 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); |
331 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); | 373 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); |
332 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); | 374 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 78aba21bc18f..5dccc5a8fa94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -91,7 +91,7 @@ extern struct iwl_cfg iwl5350_agn_cfg; | |||
91 | #define DEFAULT_SHORT_RETRY_LIMIT 7U | 91 | #define DEFAULT_SHORT_RETRY_LIMIT 7U |
92 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 92 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
93 | 93 | ||
94 | struct iwl4965_rx_mem_buffer { | 94 | struct iwl_rx_mem_buffer { |
95 | dma_addr_t dma_addr; | 95 | dma_addr_t dma_addr; |
96 | struct sk_buff *skb; | 96 | struct sk_buff *skb; |
97 | struct list_head list; | 97 | struct list_head list; |
@@ -124,7 +124,7 @@ struct iwl4965_tx_info { | |||
124 | }; | 124 | }; |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * struct iwl4965_tx_queue - Tx Queue for DMA | 127 | * struct iwl_tx_queue - Tx Queue for DMA |
128 | * @q: generic Rx/Tx queue descriptor | 128 | * @q: generic Rx/Tx queue descriptor |
129 | * @bd: base of circular buffer of TFDs | 129 | * @bd: base of circular buffer of TFDs |
130 | * @cmd: array of command/Tx buffers | 130 | * @cmd: array of command/Tx buffers |
@@ -136,9 +136,9 @@ struct iwl4965_tx_info { | |||
136 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame | 136 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame |
137 | * descriptors) and required locking structures. | 137 | * descriptors) and required locking structures. |
138 | */ | 138 | */ |
139 | struct iwl4965_tx_queue { | 139 | struct iwl_tx_queue { |
140 | struct iwl4965_queue q; | 140 | struct iwl4965_queue q; |
141 | struct iwl4965_tfd_frame *bd; | 141 | struct iwl_tfd_frame *bd; |
142 | struct iwl_cmd *cmd; | 142 | struct iwl_cmd *cmd; |
143 | dma_addr_t dma_addr_cmd; | 143 | dma_addr_t dma_addr_cmd; |
144 | struct iwl4965_tx_info *txb; | 144 | struct iwl4965_tx_info *txb; |
@@ -319,7 +319,7 @@ struct iwl_cmd { | |||
319 | struct iwl_cmd_meta meta; /* driver data */ | 319 | struct iwl_cmd_meta meta; /* driver data */ |
320 | struct iwl_cmd_header hdr; /* uCode API */ | 320 | struct iwl_cmd_header hdr; /* uCode API */ |
321 | union { | 321 | union { |
322 | struct iwl4965_addsta_cmd addsta; | 322 | struct iwl_addsta_cmd addsta; |
323 | struct iwl4965_led_cmd led; | 323 | struct iwl4965_led_cmd led; |
324 | u32 flags; | 324 | u32 flags; |
325 | u8 val8; | 325 | u8 val8; |
@@ -358,7 +358,7 @@ struct iwl_host_cmd { | |||
358 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 358 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
359 | 359 | ||
360 | /** | 360 | /** |
361 | * struct iwl4965_rx_queue - Rx queue | 361 | * struct iwl_rx_queue - Rx queue |
362 | * @processed: Internal index to last handled Rx packet | 362 | * @processed: Internal index to last handled Rx packet |
363 | * @read: Shared index to newest available Rx buffer | 363 | * @read: Shared index to newest available Rx buffer |
364 | * @write: Shared index to oldest written Rx packet | 364 | * @write: Shared index to oldest written Rx packet |
@@ -367,13 +367,13 @@ struct iwl_host_cmd { | |||
367 | * @rx_used: List of Rx buffers with no SKB | 367 | * @rx_used: List of Rx buffers with no SKB |
368 | * @need_update: flag to indicate we need to update read/write index | 368 | * @need_update: flag to indicate we need to update read/write index |
369 | * | 369 | * |
370 | * NOTE: rx_free and rx_used are used as a FIFO for iwl4965_rx_mem_buffers | 370 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers |
371 | */ | 371 | */ |
372 | struct iwl4965_rx_queue { | 372 | struct iwl_rx_queue { |
373 | __le32 *bd; | 373 | __le32 *bd; |
374 | dma_addr_t dma_addr; | 374 | dma_addr_t dma_addr; |
375 | struct iwl4965_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; | 375 | struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; |
376 | struct iwl4965_rx_mem_buffer *queue[RX_QUEUE_SIZE]; | 376 | struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; |
377 | u32 processed; | 377 | u32 processed; |
378 | u32 read; | 378 | u32 read; |
379 | u32 write; | 379 | u32 write; |
@@ -401,7 +401,7 @@ struct iwl4965_rx_queue { | |||
401 | 401 | ||
402 | #ifdef CONFIG_IWL4965_HT | 402 | #ifdef CONFIG_IWL4965_HT |
403 | /** | 403 | /** |
404 | * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack | 404 | * struct iwl_ht_agg -- aggregation status while waiting for block-ack |
405 | * @txq_id: Tx queue used for Tx attempt | 405 | * @txq_id: Tx queue used for Tx attempt |
406 | * @frame_count: # frames attempted by Tx command | 406 | * @frame_count: # frames attempted by Tx command |
407 | * @wait_for_ba: Expect block-ack before next Tx reply | 407 | * @wait_for_ba: Expect block-ack before next Tx reply |
@@ -414,7 +414,7 @@ struct iwl4965_rx_queue { | |||
414 | * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info | 414 | * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info |
415 | * until block ack arrives. | 415 | * until block ack arrives. |
416 | */ | 416 | */ |
417 | struct iwl4965_ht_agg { | 417 | struct iwl_ht_agg { |
418 | u16 txq_id; | 418 | u16 txq_id; |
419 | u16 frame_count; | 419 | u16 frame_count; |
420 | u16 wait_for_ba; | 420 | u16 wait_for_ba; |
@@ -430,15 +430,15 @@ struct iwl4965_ht_agg { | |||
430 | 430 | ||
431 | #endif /* CONFIG_IWL4965_HT */ | 431 | #endif /* CONFIG_IWL4965_HT */ |
432 | 432 | ||
433 | struct iwl4965_tid_data { | 433 | struct iwl_tid_data { |
434 | u16 seq_number; | 434 | u16 seq_number; |
435 | u16 tfds_in_queue; | 435 | u16 tfds_in_queue; |
436 | #ifdef CONFIG_IWL4965_HT | 436 | #ifdef CONFIG_IWL4965_HT |
437 | struct iwl4965_ht_agg agg; | 437 | struct iwl_ht_agg agg; |
438 | #endif /* CONFIG_IWL4965_HT */ | 438 | #endif /* CONFIG_IWL4965_HT */ |
439 | }; | 439 | }; |
440 | 440 | ||
441 | struct iwl4965_hw_key { | 441 | struct iwl_hw_key { |
442 | enum ieee80211_key_alg alg; | 442 | enum ieee80211_key_alg alg; |
443 | int keylen; | 443 | int keylen; |
444 | u8 keyidx; | 444 | u8 keyidx; |
@@ -454,7 +454,6 @@ union iwl4965_ht_rate_supp { | |||
454 | }; | 454 | }; |
455 | }; | 455 | }; |
456 | 456 | ||
457 | #ifdef CONFIG_IWL4965_HT | ||
458 | #define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) | 457 | #define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) |
459 | #define CFG_HT_MPDU_DENSITY_2USEC (0x5) | 458 | #define CFG_HT_MPDU_DENSITY_2USEC (0x5) |
460 | #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC | 459 | #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC |
@@ -477,7 +476,6 @@ struct iwl_ht_info { | |||
477 | u8 ht_protection; | 476 | u8 ht_protection; |
478 | u8 non_GF_STA_present; | 477 | u8 non_GF_STA_present; |
479 | }; | 478 | }; |
480 | #endif /*CONFIG_IWL4965_HT */ | ||
481 | 479 | ||
482 | union iwl4965_qos_capabity { | 480 | union iwl4965_qos_capabity { |
483 | struct { | 481 | struct { |
@@ -510,12 +508,12 @@ struct iwl4965_qos_info { | |||
510 | #define STA_PS_STATUS_WAKE 0 | 508 | #define STA_PS_STATUS_WAKE 0 |
511 | #define STA_PS_STATUS_SLEEP 1 | 509 | #define STA_PS_STATUS_SLEEP 1 |
512 | 510 | ||
513 | struct iwl4965_station_entry { | 511 | struct iwl_station_entry { |
514 | struct iwl4965_addsta_cmd sta; | 512 | struct iwl_addsta_cmd sta; |
515 | struct iwl4965_tid_data tid[MAX_TID_COUNT]; | 513 | struct iwl_tid_data tid[MAX_TID_COUNT]; |
516 | u8 used; | 514 | u8 used; |
517 | u8 ps_status; | 515 | u8 ps_status; |
518 | struct iwl4965_hw_key keyinfo; | 516 | struct iwl_hw_key keyinfo; |
519 | }; | 517 | }; |
520 | 518 | ||
521 | /* one for each uCode image (inst/data, boot/init/runtime) */ | 519 | /* one for each uCode image (inst/data, boot/init/runtime) */ |
@@ -634,35 +632,26 @@ struct iwl_hw_params { | |||
634 | * for use by iwl-*.c | 632 | * for use by iwl-*.c |
635 | * | 633 | * |
636 | *****************************************************************************/ | 634 | *****************************************************************************/ |
637 | struct iwl4965_addsta_cmd; | 635 | struct iwl_addsta_cmd; |
638 | extern int iwl4965_send_add_station(struct iwl_priv *priv, | 636 | extern int iwl_send_add_sta(struct iwl_priv *priv, |
639 | struct iwl4965_addsta_cmd *sta, u8 flags); | 637 | struct iwl_addsta_cmd *sta, u8 flags); |
640 | extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | 638 | extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, |
641 | int is_ap, u8 flags, void *ht_data); | 639 | int is_ap, u8 flags, void *ht_data); |
642 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, | 640 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, |
643 | struct ieee80211_hdr *header); | 641 | struct ieee80211_hdr *header); |
644 | extern int iwl4965_power_init_handle(struct iwl_priv *priv); | 642 | extern int iwl4965_power_init_handle(struct iwl_priv *priv); |
645 | extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv, | 643 | extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv, |
646 | struct iwl4965_rx_mem_buffer *rxb, | 644 | struct iwl_rx_mem_buffer *rxb, |
647 | void *data, short len, | 645 | void *data, short len, |
648 | struct ieee80211_rx_status *stats, | 646 | struct ieee80211_rx_status *stats, |
649 | u16 phy_flags); | 647 | u16 phy_flags); |
650 | extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, | 648 | extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, |
651 | struct ieee80211_hdr *header); | 649 | struct ieee80211_hdr *header); |
652 | extern int iwl4965_rx_queue_alloc(struct iwl_priv *priv); | ||
653 | extern void iwl4965_rx_queue_reset(struct iwl_priv *priv, | ||
654 | struct iwl4965_rx_queue *rxq); | ||
655 | extern int iwl4965_calc_db_from_ratio(int sig_ratio); | 650 | extern int iwl4965_calc_db_from_ratio(int sig_ratio); |
656 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); | 651 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); |
657 | extern int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
658 | struct iwl4965_tx_queue *txq, int count, u32 id); | ||
659 | extern void iwl4965_rx_replenish(void *data); | ||
660 | extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); | ||
661 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | 652 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, |
662 | struct ieee80211_hdr *hdr, | 653 | struct ieee80211_hdr *hdr, |
663 | const u8 *dest, int left); | 654 | const u8 *dest, int left); |
664 | extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, | ||
665 | struct iwl4965_rx_queue *q); | ||
666 | extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr); | 655 | extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr); |
667 | extern void iwl4965_update_chain_flags(struct iwl_priv *priv); | 656 | extern void iwl4965_update_chain_flags(struct iwl_priv *priv); |
668 | int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); | 657 | int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); |
@@ -700,20 +689,14 @@ extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); | |||
700 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); | 689 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); |
701 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); | 690 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); |
702 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); | 691 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); |
703 | extern int iwl4965_hw_nic_init(struct iwl_priv *priv); | ||
704 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); | 692 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); |
705 | extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); | ||
706 | extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv); | 693 | extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv); |
707 | extern int iwl4965_hw_nic_reset(struct iwl_priv *priv); | 694 | extern int iwl4965_hw_nic_reset(struct iwl_priv *priv); |
708 | extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, | 695 | extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, |
709 | dma_addr_t addr, u16 len); | 696 | dma_addr_t addr, u16 len); |
710 | extern int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); | ||
711 | extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); | 697 | extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); |
712 | extern int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, | ||
713 | struct iwl4965_tx_queue *txq); | ||
714 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | 698 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, |
715 | struct iwl4965_frame *frame, u8 rate); | 699 | struct iwl4965_frame *frame, u8 rate); |
716 | extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); | ||
717 | extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | 700 | extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, |
718 | struct iwl_cmd *cmd, | 701 | struct iwl_cmd *cmd, |
719 | struct ieee80211_tx_control *ctrl, | 702 | struct ieee80211_tx_control *ctrl, |
@@ -722,7 +705,7 @@ extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
722 | extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv); | 705 | extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv); |
723 | extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); | 706 | extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); |
724 | extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | 707 | extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, |
725 | struct iwl4965_rx_mem_buffer *rxb); | 708 | struct iwl_rx_mem_buffer *rxb); |
726 | extern void iwl4965_disable_events(struct iwl_priv *priv); | 709 | extern void iwl4965_disable_events(struct iwl_priv *priv); |
727 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); | 710 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); |
728 | 711 | ||
@@ -746,7 +729,7 @@ extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); | |||
746 | * Forward declare iwl-4965.c functions for iwl-base.c | 729 | * Forward declare iwl-4965.c functions for iwl-base.c |
747 | */ | 730 | */ |
748 | extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | 731 | extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, |
749 | struct iwl4965_tx_queue *txq, | 732 | struct iwl_tx_queue *txq, |
750 | u16 byte_cnt); | 733 | u16 byte_cnt); |
751 | extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, | 734 | extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, |
752 | int is_ap); | 735 | int is_ap); |
@@ -778,9 +761,9 @@ static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, | |||
778 | #endif /*CONFIG_IWL4965_HT */ | 761 | #endif /*CONFIG_IWL4965_HT */ |
779 | /* Structures, enum, and defines specific to the 4965 */ | 762 | /* Structures, enum, and defines specific to the 4965 */ |
780 | 763 | ||
781 | #define IWL4965_KW_SIZE 0x1000 /*4k */ | 764 | #define IWL_KW_SIZE 0x1000 /*4k */ |
782 | 765 | ||
783 | struct iwl4965_kw { | 766 | struct iwl_kw { |
784 | dma_addr_t dma_addr; | 767 | dma_addr_t dma_addr; |
785 | void *v_addr; | 768 | void *v_addr; |
786 | size_t size; | 769 | size_t size; |
@@ -960,7 +943,7 @@ struct iwl_priv { | |||
960 | bool add_radiotap; | 943 | bool add_radiotap; |
961 | 944 | ||
962 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 945 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
963 | struct iwl4965_rx_mem_buffer *rxb); | 946 | struct iwl_rx_mem_buffer *rxb); |
964 | 947 | ||
965 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 948 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
966 | 949 | ||
@@ -1077,10 +1060,10 @@ struct iwl_priv { | |||
1077 | int activity_timer_active; | 1060 | int activity_timer_active; |
1078 | 1061 | ||
1079 | /* Rx and Tx DMA processing queues */ | 1062 | /* Rx and Tx DMA processing queues */ |
1080 | struct iwl4965_rx_queue rxq; | 1063 | struct iwl_rx_queue rxq; |
1081 | struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES]; | 1064 | struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; |
1082 | unsigned long txq_ctx_active_msk; | 1065 | unsigned long txq_ctx_active_msk; |
1083 | struct iwl4965_kw kw; /* keep warm address */ | 1066 | struct iwl_kw kw; /* keep warm address */ |
1084 | u32 scd_base_addr; /* scheduler sram base address */ | 1067 | u32 scd_base_addr; /* scheduler sram base address */ |
1085 | 1068 | ||
1086 | unsigned long status; | 1069 | unsigned long status; |
@@ -1113,7 +1096,7 @@ struct iwl_priv { | |||
1113 | /*station table variables */ | 1096 | /*station table variables */ |
1114 | spinlock_t sta_lock; | 1097 | spinlock_t sta_lock; |
1115 | int num_stations; | 1098 | int num_stations; |
1116 | struct iwl4965_station_entry stations[IWL_STATION_COUNT]; | 1099 | struct iwl_station_entry stations[IWL_STATION_COUNT]; |
1117 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; | 1100 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; |
1118 | u8 default_wep_key; | 1101 | u8 default_wep_key; |
1119 | u8 key_mapping_key; | 1102 | u8 key_mapping_key; |
@@ -1154,6 +1137,7 @@ struct iwl_priv { | |||
1154 | struct iwl_hw_params hw_params; | 1137 | struct iwl_hw_params hw_params; |
1155 | /* driver/uCode shared Tx Byte Counts and Rx status */ | 1138 | /* driver/uCode shared Tx Byte Counts and Rx status */ |
1156 | void *shared_virt; | 1139 | void *shared_virt; |
1140 | int rb_closed_offset; | ||
1157 | /* Physical Pointer to Tx Byte Counts and Rx status */ | 1141 | /* Physical Pointer to Tx Byte Counts and Rx status */ |
1158 | dma_addr_t shared_phys; | 1142 | dma_addr_t shared_phys; |
1159 | 1143 | ||
@@ -1179,6 +1163,7 @@ struct iwl_priv { | |||
1179 | struct work_struct report_work; | 1163 | struct work_struct report_work; |
1180 | struct work_struct request_scan; | 1164 | struct work_struct request_scan; |
1181 | struct work_struct beacon_update; | 1165 | struct work_struct beacon_update; |
1166 | struct work_struct set_monitor; | ||
1182 | 1167 | ||
1183 | struct tasklet_struct irq_tasklet; | 1168 | struct tasklet_struct irq_tasklet; |
1184 | 1169 | ||
@@ -1200,6 +1185,7 @@ struct iwl_priv { | |||
1200 | 1185 | ||
1201 | #ifdef CONFIG_IWLWIFI_DEBUG | 1186 | #ifdef CONFIG_IWLWIFI_DEBUG |
1202 | /* debugging info */ | 1187 | /* debugging info */ |
1188 | u32 debug_level; | ||
1203 | u32 framecnt_to_us; | 1189 | u32 framecnt_to_us; |
1204 | atomic_t restrict_refcnt; | 1190 | atomic_t restrict_refcnt; |
1205 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1191 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -1252,6 +1238,23 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) | |||
1252 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | 1238 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; |
1253 | } | 1239 | } |
1254 | 1240 | ||
1241 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1242 | static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, | ||
1243 | void *p, u32 len) | ||
1244 | { | ||
1245 | if (!(priv->debug_level & level)) | ||
1246 | return; | ||
1247 | |||
1248 | print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
1249 | p, len, 1); | ||
1250 | } | ||
1251 | #else | ||
1252 | static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, | ||
1253 | void *p, u32 len) | ||
1254 | { | ||
1255 | } | ||
1256 | #endif | ||
1257 | |||
1255 | extern const struct iwl_channel_info *iwl_get_channel_info( | 1258 | extern const struct iwl_channel_info *iwl_get_channel_info( |
1256 | const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); | 1259 | const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); |
1257 | 1260 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index acb5a8abd786..0412adf6ef8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(get_cmd_string); | |||
101 | static int iwl_generic_cmd_callback(struct iwl_priv *priv, | 101 | static int iwl_generic_cmd_callback(struct iwl_priv *priv, |
102 | struct iwl_cmd *cmd, struct sk_buff *skb) | 102 | struct iwl_cmd *cmd, struct sk_buff *skb) |
103 | { | 103 | { |
104 | struct iwl4965_rx_packet *pkt = NULL; | 104 | struct iwl_rx_packet *pkt = NULL; |
105 | 105 | ||
106 | if (!skb) { | 106 | if (!skb) { |
107 | IWL_ERROR("Error: Response NULL in %s.\n", | 107 | IWL_ERROR("Error: Response NULL in %s.\n", |
@@ -109,7 +109,7 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv, | |||
109 | return 1; | 109 | return 1; |
110 | } | 110 | } |
111 | 111 | ||
112 | pkt = (struct iwl4965_rx_packet *)skb->data; | 112 | pkt = (struct iwl_rx_packet *)skb->data; |
113 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 113 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
114 | IWL_ERROR("Bad return from %s (0x%08X)\n", | 114 | IWL_ERROR("Bad return from %s (0x%08X)\n", |
115 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); | 115 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c new file mode 100644 index 000000000000..a2eb90d40b7e --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -0,0 +1,422 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include <net/mac80211.h> | ||
31 | #include "iwl-eeprom.h" | ||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-core.h" | ||
34 | #include "iwl-sta.h" | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-helpers.h" | ||
37 | /************************** RX-FUNCTIONS ****************************/ | ||
38 | /* | ||
39 | * Rx theory of operation | ||
40 | * | ||
41 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
42 | * each of which point to Receive Buffers to be filled by the NIC. These get | ||
43 | * used not only for Rx frames, but for any command response or notification | ||
44 | * from the NIC. The driver and NIC manage the Rx buffers by means | ||
45 | * of indexes into the circular buffer. | ||
46 | * | ||
47 | * Rx Queue Indexes | ||
48 | * The host/firmware share two index registers for managing the Rx buffers. | ||
49 | * | ||
50 | * The READ index maps to the first position that the firmware may be writing | ||
51 | * to -- the driver can read up to (but not including) this position and get | ||
52 | * good data. | ||
53 | * The READ index is managed by the firmware once the card is enabled. | ||
54 | * | ||
55 | * The WRITE index maps to the last position the driver has read from -- the | ||
56 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
57 | * | ||
58 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
59 | * WRITE = READ. | ||
60 | * | ||
61 | * During initialization, the host sets up the READ queue position to the first | ||
62 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
63 | * | ||
64 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
65 | * and fire the RX interrupt. The driver can then query the READ index and | ||
66 | * process as many packets as possible, moving the WRITE index forward as it | ||
67 | * resets the Rx queue buffers with new memory. | ||
68 | * | ||
69 | * The management in the driver is as follows: | ||
70 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
71 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
72 | * to replenish the iwl->rxq->rx_free. | ||
73 | * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
74 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
75 | * 'processed' and 'read' driver indexes as well) | ||
76 | * + A received packet is processed and handed to the kernel network stack, | ||
77 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
78 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
79 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
80 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
81 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
82 | * | ||
83 | * | ||
84 | * Driver sequence: | ||
85 | * | ||
86 | * iwl_rx_queue_alloc() Allocates rx_free | ||
87 | * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
88 | * iwl_rx_queue_restock | ||
89 | * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
90 | * queue, updates firmware pointers, and updates | ||
91 | * the WRITE index. If insufficient rx_free buffers | ||
92 | * are available, schedules iwl_rx_replenish | ||
93 | * | ||
94 | * -- enable interrupts -- | ||
95 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | ||
96 | * READ INDEX, detaching the SKB from the pool. | ||
97 | * Moves the packet buffer from queue to rx_used. | ||
98 | * Calls iwl_rx_queue_restock to refill any empty | ||
99 | * slots. | ||
100 | * ... | ||
101 | * | ||
102 | */ | ||
103 | |||
104 | /** | ||
105 | * iwl_rx_queue_space - Return number of free slots available in queue. | ||
106 | */ | ||
107 | int iwl_rx_queue_space(const struct iwl_rx_queue *q) | ||
108 | { | ||
109 | int s = q->read - q->write; | ||
110 | if (s <= 0) | ||
111 | s += RX_QUEUE_SIZE; | ||
112 | /* keep some buffer to not confuse full and empty queue */ | ||
113 | s -= 2; | ||
114 | if (s < 0) | ||
115 | s = 0; | ||
116 | return s; | ||
117 | } | ||
118 | EXPORT_SYMBOL(iwl_rx_queue_space); | ||
119 | |||
120 | /** | ||
121 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
122 | */ | ||
123 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | ||
124 | { | ||
125 | u32 reg = 0; | ||
126 | int ret = 0; | ||
127 | unsigned long flags; | ||
128 | |||
129 | spin_lock_irqsave(&q->lock, flags); | ||
130 | |||
131 | if (q->need_update == 0) | ||
132 | goto exit_unlock; | ||
133 | |||
134 | /* If power-saving is in use, make sure device is awake */ | ||
135 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
136 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
137 | |||
138 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
139 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
140 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
141 | goto exit_unlock; | ||
142 | } | ||
143 | |||
144 | ret = iwl_grab_nic_access(priv); | ||
145 | if (ret) | ||
146 | goto exit_unlock; | ||
147 | |||
148 | /* Device expects a multiple of 8 */ | ||
149 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
150 | q->write & ~0x7); | ||
151 | iwl_release_nic_access(priv); | ||
152 | |||
153 | /* Else device is assumed to be awake */ | ||
154 | } else | ||
155 | /* Device expects a multiple of 8 */ | ||
156 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | ||
157 | |||
158 | |||
159 | q->need_update = 0; | ||
160 | |||
161 | exit_unlock: | ||
162 | spin_unlock_irqrestore(&q->lock, flags); | ||
163 | return ret; | ||
164 | } | ||
165 | EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); | ||
166 | /** | ||
167 | * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
168 | */ | ||
169 | static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, | ||
170 | dma_addr_t dma_addr) | ||
171 | { | ||
172 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * iwl_rx_queue_restock - refill RX queue from pre-allocated pool | ||
177 | * | ||
178 | * If there are slots in the RX queue that need to be restocked, | ||
179 | * and we have free pre-allocated buffers, fill the ranks as much | ||
180 | * as we can, pulling from rx_free. | ||
181 | * | ||
182 | * This moves the 'write' index forward to catch up with 'processed', and | ||
183 | * also updates the memory address in the firmware to reference the new | ||
184 | * target buffer. | ||
185 | */ | ||
186 | int iwl_rx_queue_restock(struct iwl_priv *priv) | ||
187 | { | ||
188 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
189 | struct list_head *element; | ||
190 | struct iwl_rx_mem_buffer *rxb; | ||
191 | unsigned long flags; | ||
192 | int write; | ||
193 | int ret = 0; | ||
194 | |||
195 | spin_lock_irqsave(&rxq->lock, flags); | ||
196 | write = rxq->write & ~0x7; | ||
197 | while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | ||
198 | /* Get next free Rx buffer, remove from free list */ | ||
199 | element = rxq->rx_free.next; | ||
200 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
201 | list_del(element); | ||
202 | |||
203 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
204 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr); | ||
205 | rxq->queue[rxq->write] = rxb; | ||
206 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | ||
207 | rxq->free_count--; | ||
208 | } | ||
209 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
210 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
211 | * refill it */ | ||
212 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
213 | queue_work(priv->workqueue, &priv->rx_replenish); | ||
214 | |||
215 | |||
216 | /* If we've added more space for the firmware to place data, tell it. | ||
217 | * Increment device's write pointer in multiples of 8. */ | ||
218 | if ((write != (rxq->write & ~0x7)) | ||
219 | || (abs(rxq->write - rxq->read) > 7)) { | ||
220 | spin_lock_irqsave(&rxq->lock, flags); | ||
221 | rxq->need_update = 1; | ||
222 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
223 | ret = iwl_rx_queue_update_write_ptr(priv, rxq); | ||
224 | } | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | EXPORT_SYMBOL(iwl_rx_queue_restock); | ||
229 | |||
230 | |||
231 | /** | ||
232 | * iwl_rx_replenish - Move all used packet from rx_used to rx_free | ||
233 | * | ||
234 | * When moving to rx_free an SKB is allocated for the slot. | ||
235 | * | ||
236 | * Also restock the Rx queue via iwl_rx_queue_restock. | ||
237 | * This is called as a scheduled work item (except for during initialization) | ||
238 | */ | ||
239 | void iwl_rx_allocate(struct iwl_priv *priv) | ||
240 | { | ||
241 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
242 | struct list_head *element; | ||
243 | struct iwl_rx_mem_buffer *rxb; | ||
244 | unsigned long flags; | ||
245 | spin_lock_irqsave(&rxq->lock, flags); | ||
246 | while (!list_empty(&rxq->rx_used)) { | ||
247 | element = rxq->rx_used.next; | ||
248 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
249 | |||
250 | /* Alloc a new receive buffer */ | ||
251 | rxb->skb = alloc_skb(priv->hw_params.rx_buf_size, | ||
252 | __GFP_NOWARN | GFP_ATOMIC); | ||
253 | if (!rxb->skb) { | ||
254 | if (net_ratelimit()) | ||
255 | printk(KERN_CRIT DRV_NAME | ||
256 | ": Can not allocate SKB buffers\n"); | ||
257 | /* We don't reschedule replenish work here -- we will | ||
258 | * call the restock method and if it still needs | ||
259 | * more buffers it will schedule replenish */ | ||
260 | break; | ||
261 | } | ||
262 | priv->alloc_rxb_skb++; | ||
263 | list_del(element); | ||
264 | |||
265 | /* Get physical address of RB/SKB */ | ||
266 | rxb->dma_addr = | ||
267 | pci_map_single(priv->pci_dev, rxb->skb->data, | ||
268 | priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); | ||
269 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
270 | rxq->free_count++; | ||
271 | } | ||
272 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
273 | } | ||
274 | EXPORT_SYMBOL(iwl_rx_allocate); | ||
275 | |||
276 | void iwl_rx_replenish(struct iwl_priv *priv) | ||
277 | { | ||
278 | unsigned long flags; | ||
279 | |||
280 | iwl_rx_allocate(priv); | ||
281 | |||
282 | spin_lock_irqsave(&priv->lock, flags); | ||
283 | iwl_rx_queue_restock(priv); | ||
284 | spin_unlock_irqrestore(&priv->lock, flags); | ||
285 | } | ||
286 | EXPORT_SYMBOL(iwl_rx_replenish); | ||
287 | |||
288 | |||
289 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | ||
290 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | ||
291 | * This free routine walks the list of POOL entries and if SKB is set to | ||
292 | * non NULL it is unmapped and freed | ||
293 | */ | ||
294 | void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
295 | { | ||
296 | int i; | ||
297 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | ||
298 | if (rxq->pool[i].skb != NULL) { | ||
299 | pci_unmap_single(priv->pci_dev, | ||
300 | rxq->pool[i].dma_addr, | ||
301 | priv->hw_params.rx_buf_size, | ||
302 | PCI_DMA_FROMDEVICE); | ||
303 | dev_kfree_skb(rxq->pool[i].skb); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
308 | rxq->dma_addr); | ||
309 | rxq->bd = NULL; | ||
310 | } | ||
311 | EXPORT_SYMBOL(iwl_rx_queue_free); | ||
312 | |||
313 | int iwl_rx_queue_alloc(struct iwl_priv *priv) | ||
314 | { | ||
315 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
316 | struct pci_dev *dev = priv->pci_dev; | ||
317 | int i; | ||
318 | |||
319 | spin_lock_init(&rxq->lock); | ||
320 | INIT_LIST_HEAD(&rxq->rx_free); | ||
321 | INIT_LIST_HEAD(&rxq->rx_used); | ||
322 | |||
323 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
324 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | ||
325 | if (!rxq->bd) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
329 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | ||
330 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
331 | |||
332 | /* Set us so that we have processed and used all buffers, but have | ||
333 | * not restocked the Rx queue with fresh buffers */ | ||
334 | rxq->read = rxq->write = 0; | ||
335 | rxq->free_count = 0; | ||
336 | rxq->need_update = 0; | ||
337 | return 0; | ||
338 | } | ||
339 | EXPORT_SYMBOL(iwl_rx_queue_alloc); | ||
340 | |||
341 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
342 | { | ||
343 | unsigned long flags; | ||
344 | int i; | ||
345 | spin_lock_irqsave(&rxq->lock, flags); | ||
346 | INIT_LIST_HEAD(&rxq->rx_free); | ||
347 | INIT_LIST_HEAD(&rxq->rx_used); | ||
348 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
349 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
350 | /* In the reset function, these buffers may have been allocated | ||
351 | * to an SKB, so we need to unmap and free potential storage */ | ||
352 | if (rxq->pool[i].skb != NULL) { | ||
353 | pci_unmap_single(priv->pci_dev, | ||
354 | rxq->pool[i].dma_addr, | ||
355 | priv->hw_params.rx_buf_size, | ||
356 | PCI_DMA_FROMDEVICE); | ||
357 | priv->alloc_rxb_skb--; | ||
358 | dev_kfree_skb(rxq->pool[i].skb); | ||
359 | rxq->pool[i].skb = NULL; | ||
360 | } | ||
361 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
362 | } | ||
363 | |||
364 | /* Set us so that we have processed and used all buffers, but have | ||
365 | * not restocked the Rx queue with fresh buffers */ | ||
366 | rxq->read = rxq->write = 0; | ||
367 | rxq->free_count = 0; | ||
368 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
369 | } | ||
370 | EXPORT_SYMBOL(iwl_rx_queue_reset); | ||
371 | |||
372 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
373 | { | ||
374 | int ret; | ||
375 | unsigned long flags; | ||
376 | unsigned int rb_size; | ||
377 | |||
378 | spin_lock_irqsave(&priv->lock, flags); | ||
379 | ret = iwl_grab_nic_access(priv); | ||
380 | if (ret) { | ||
381 | spin_unlock_irqrestore(&priv->lock, flags); | ||
382 | return ret; | ||
383 | } | ||
384 | |||
385 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
386 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
387 | else | ||
388 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
389 | |||
390 | /* Stop Rx DMA */ | ||
391 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
392 | |||
393 | /* Reset driver's Rx queue write index */ | ||
394 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
395 | |||
396 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
397 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
398 | rxq->dma_addr >> 8); | ||
399 | |||
400 | /* Tell device where in DRAM to update its Rx status */ | ||
401 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
402 | (priv->shared_phys + priv->rb_closed_offset) >> 4); | ||
403 | |||
404 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | ||
405 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
406 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
407 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
408 | rb_size | | ||
409 | /* 0x10 << 4 | */ | ||
410 | (RX_QUEUE_SIZE_LOG << | ||
411 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | ||
412 | |||
413 | /* | ||
414 | * iwl_write32(priv,CSR_INT_COAL_REG,0); | ||
415 | */ | ||
416 | |||
417 | iwl_release_nic_access(priv); | ||
418 | spin_unlock_irqrestore(&priv->lock, flags); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 31b37a1a6430..f2267047d102 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -70,6 +70,52 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) | |||
70 | } | 70 | } |
71 | EXPORT_SYMBOL(iwl_find_station); | 71 | EXPORT_SYMBOL(iwl_find_station); |
72 | 72 | ||
73 | int iwl_send_add_sta(struct iwl_priv *priv, | ||
74 | struct iwl_addsta_cmd *sta, u8 flags) | ||
75 | { | ||
76 | struct iwl_rx_packet *res = NULL; | ||
77 | int ret = 0; | ||
78 | u8 data[sizeof(*sta)]; | ||
79 | struct iwl_host_cmd cmd = { | ||
80 | .id = REPLY_ADD_STA, | ||
81 | .meta.flags = flags, | ||
82 | .data = data, | ||
83 | }; | ||
84 | |||
85 | if (!(flags & CMD_ASYNC)) | ||
86 | cmd.meta.flags |= CMD_WANT_SKB; | ||
87 | |||
88 | cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); | ||
89 | ret = iwl_send_cmd(priv, &cmd); | ||
90 | |||
91 | if (ret || (flags & CMD_ASYNC)) | ||
92 | return ret; | ||
93 | |||
94 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | ||
95 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
96 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
97 | res->hdr.flags); | ||
98 | ret = -EIO; | ||
99 | } | ||
100 | |||
101 | if (ret == 0) { | ||
102 | switch (res->u.add_sta.status) { | ||
103 | case ADD_STA_SUCCESS_MSK: | ||
104 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); | ||
105 | break; | ||
106 | default: | ||
107 | ret = -EIO; | ||
108 | IWL_WARNING("REPLY_ADD_STA failed\n"); | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | priv->alloc_rxb_skb--; | ||
114 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
115 | |||
116 | return ret; | ||
117 | } | ||
118 | EXPORT_SYMBOL(iwl_send_add_sta); | ||
73 | 119 | ||
74 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | 120 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) |
75 | { | 121 | { |
@@ -124,6 +170,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | |||
124 | else | 170 | else |
125 | return 0; | 171 | return 0; |
126 | } | 172 | } |
173 | EXPORT_SYMBOL(iwl_send_static_wepkey_cmd); | ||
127 | 174 | ||
128 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | 175 | int iwl_remove_default_wep_key(struct iwl_priv *priv, |
129 | struct ieee80211_key_conf *keyconf) | 176 | struct ieee80211_key_conf *keyconf) |
@@ -144,6 +191,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
144 | 191 | ||
145 | return ret; | 192 | return ret; |
146 | } | 193 | } |
194 | EXPORT_SYMBOL(iwl_remove_default_wep_key); | ||
147 | 195 | ||
148 | int iwl_set_default_wep_key(struct iwl_priv *priv, | 196 | int iwl_set_default_wep_key(struct iwl_priv *priv, |
149 | struct ieee80211_key_conf *keyconf) | 197 | struct ieee80211_key_conf *keyconf) |
@@ -171,6 +219,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
171 | 219 | ||
172 | return ret; | 220 | return ret; |
173 | } | 221 | } |
222 | EXPORT_SYMBOL(iwl_set_default_wep_key); | ||
174 | 223 | ||
175 | static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | 224 | static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, |
176 | struct ieee80211_key_conf *keyconf, | 225 | struct ieee80211_key_conf *keyconf, |
@@ -216,8 +265,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | |||
216 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 265 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
217 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 266 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
218 | 267 | ||
219 | ret = iwl4965_send_add_station(priv, | 268 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
220 | &priv->stations[sta_id].sta, CMD_ASYNC); | ||
221 | 269 | ||
222 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 270 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
223 | 271 | ||
@@ -265,8 +313,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
265 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 313 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
266 | 314 | ||
267 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); | 315 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); |
268 | return iwl4965_send_add_station(priv, | 316 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
269 | &priv->stations[sta_id].sta, CMD_ASYNC); | ||
270 | } | 317 | } |
271 | 318 | ||
272 | static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | 319 | static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, |
@@ -333,7 +380,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
333 | IWL_ERROR("index %d not used in uCode key table.\n", | 380 | IWL_ERROR("index %d not used in uCode key table.\n", |
334 | priv->stations[sta_id].sta.key.key_offset); | 381 | priv->stations[sta_id].sta.key.key_offset); |
335 | memset(&priv->stations[sta_id].keyinfo, 0, | 382 | memset(&priv->stations[sta_id].keyinfo, 0, |
336 | sizeof(struct iwl4965_hw_key)); | 383 | sizeof(struct iwl_hw_key)); |
337 | memset(&priv->stations[sta_id].sta.key, 0, | 384 | memset(&priv->stations[sta_id].sta.key, 0, |
338 | sizeof(struct iwl4965_keyinfo)); | 385 | sizeof(struct iwl4965_keyinfo)); |
339 | priv->stations[sta_id].sta.key.key_flags = | 386 | priv->stations[sta_id].sta.key.key_flags = |
@@ -343,10 +390,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
343 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 390 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
344 | 391 | ||
345 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | 392 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); |
346 | ret = iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); | 393 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); |
347 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 394 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
348 | return ret; | 395 | return ret; |
349 | } | 396 | } |
397 | EXPORT_SYMBOL(iwl_remove_dynamic_key); | ||
350 | 398 | ||
351 | int iwl_set_dynamic_key(struct iwl_priv *priv, | 399 | int iwl_set_dynamic_key(struct iwl_priv *priv, |
352 | struct ieee80211_key_conf *key, u8 sta_id) | 400 | struct ieee80211_key_conf *key, u8 sta_id) |
@@ -372,6 +420,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
372 | 420 | ||
373 | return ret; | 421 | return ret; |
374 | } | 422 | } |
423 | EXPORT_SYMBOL(iwl_set_dynamic_key); | ||
375 | 424 | ||
376 | #ifdef CONFIG_IWLWIFI_DEBUG | 425 | #ifdef CONFIG_IWLWIFI_DEBUG |
377 | static void iwl_dump_lq_cmd(struct iwl_priv *priv, | 426 | static void iwl_dump_lq_cmd(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c new file mode 100644 index 000000000000..a1e03ccd5147 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -0,0 +1,373 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include <net/mac80211.h> | ||
31 | #include "iwl-eeprom.h" | ||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-core.h" | ||
34 | #include "iwl-sta.h" | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-helpers.h" | ||
37 | |||
38 | /** | ||
39 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
40 | * | ||
41 | * Does NOT advance any TFD circular buffer read/write indexes | ||
42 | * Does NOT free the TFD itself (which is within circular buffer) | ||
43 | */ | ||
44 | int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
45 | { | ||
46 | struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; | ||
47 | struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | ||
48 | struct pci_dev *dev = priv->pci_dev; | ||
49 | int i; | ||
50 | int counter = 0; | ||
51 | int index, is_odd; | ||
52 | |||
53 | /* Host command buffers stay mapped in memory, nothing to clean */ | ||
54 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | ||
55 | return 0; | ||
56 | |||
57 | /* Sanity check on number of chunks */ | ||
58 | counter = IWL_GET_BITS(*bd, num_tbs); | ||
59 | if (counter > MAX_NUM_OF_TBS) { | ||
60 | IWL_ERROR("Too many chunks: %i\n", counter); | ||
61 | /* @todo issue fatal error, it is quite serious situation */ | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | /* Unmap chunks, if any. | ||
66 | * TFD info for odd chunks is different format than for even chunks. */ | ||
67 | for (i = 0; i < counter; i++) { | ||
68 | index = i / 2; | ||
69 | is_odd = i & 0x1; | ||
70 | |||
71 | if (is_odd) | ||
72 | pci_unmap_single( | ||
73 | dev, | ||
74 | IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | | ||
75 | (IWL_GET_BITS(bd->pa[index], | ||
76 | tb2_addr_hi20) << 16), | ||
77 | IWL_GET_BITS(bd->pa[index], tb2_len), | ||
78 | PCI_DMA_TODEVICE); | ||
79 | |||
80 | else if (i > 0) | ||
81 | pci_unmap_single(dev, | ||
82 | le32_to_cpu(bd->pa[index].tb1_addr), | ||
83 | IWL_GET_BITS(bd->pa[index], tb1_len), | ||
84 | PCI_DMA_TODEVICE); | ||
85 | |||
86 | /* Free SKB, if any, for this chunk */ | ||
87 | if (txq->txb[txq->q.read_ptr].skb[i]) { | ||
88 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; | ||
89 | |||
90 | dev_kfree_skb(skb); | ||
91 | txq->txb[txq->q.read_ptr].skb[i] = NULL; | ||
92 | } | ||
93 | } | ||
94 | return 0; | ||
95 | } | ||
96 | EXPORT_SYMBOL(iwl_hw_txq_free_tfd); | ||
97 | |||
98 | /** | ||
99 | * iwl_tx_queue_free - Deallocate DMA queue. | ||
100 | * @txq: Transmit queue to deallocate. | ||
101 | * | ||
102 | * Empty queue by removing and destroying all BD's. | ||
103 | * Free all buffers. | ||
104 | * 0-fill, but do not free "txq" descriptor structure. | ||
105 | */ | ||
106 | static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
107 | { | ||
108 | struct iwl4965_queue *q = &txq->q; | ||
109 | struct pci_dev *dev = priv->pci_dev; | ||
110 | int len; | ||
111 | |||
112 | if (q->n_bd == 0) | ||
113 | return; | ||
114 | |||
115 | /* first, empty all BD's */ | ||
116 | for (; q->write_ptr != q->read_ptr; | ||
117 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
118 | iwl_hw_txq_free_tfd(priv, txq); | ||
119 | |||
120 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
121 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
122 | len += IWL_MAX_SCAN_SIZE; | ||
123 | |||
124 | /* De-alloc array of command/tx buffers */ | ||
125 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
126 | |||
127 | /* De-alloc circular buffer of TFDs */ | ||
128 | if (txq->q.n_bd) | ||
129 | pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) * | ||
130 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
131 | |||
132 | /* De-alloc array of per-TFD driver data */ | ||
133 | kfree(txq->txb); | ||
134 | txq->txb = NULL; | ||
135 | |||
136 | /* 0-fill queue descriptor structure */ | ||
137 | memset(txq, 0, sizeof(*txq)); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * iwl_hw_txq_ctx_free - Free TXQ Context | ||
142 | * | ||
143 | * Destroy all TX DMA queues and structures | ||
144 | */ | ||
145 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | ||
146 | { | ||
147 | int txq_id; | ||
148 | |||
149 | /* Tx queues */ | ||
150 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | ||
151 | iwl_tx_queue_free(priv, &priv->txq[txq_id]); | ||
152 | |||
153 | /* Keep-warm buffer */ | ||
154 | iwl_kw_free(priv); | ||
155 | } | ||
156 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | ||
157 | |||
158 | /** | ||
159 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes | ||
160 | */ | ||
161 | static int iwl_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
162 | int count, int slots_num, u32 id) | ||
163 | { | ||
164 | q->n_bd = count; | ||
165 | q->n_window = slots_num; | ||
166 | q->id = id; | ||
167 | |||
168 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
169 | * and iwl_queue_dec_wrap are broken. */ | ||
170 | BUG_ON(!is_power_of_2(count)); | ||
171 | |||
172 | /* slots_num must be power-of-two size, otherwise | ||
173 | * get_cmd_index is broken. */ | ||
174 | BUG_ON(!is_power_of_2(slots_num)); | ||
175 | |||
176 | q->low_mark = q->n_window / 4; | ||
177 | if (q->low_mark < 4) | ||
178 | q->low_mark = 4; | ||
179 | |||
180 | q->high_mark = q->n_window / 8; | ||
181 | if (q->high_mark < 2) | ||
182 | q->high_mark = 2; | ||
183 | |||
184 | q->write_ptr = q->read_ptr = 0; | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
191 | */ | ||
192 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, | ||
193 | struct iwl_tx_queue *txq, u32 id) | ||
194 | { | ||
195 | struct pci_dev *dev = priv->pci_dev; | ||
196 | |||
197 | /* Driver private data, only for Tx (not command) queues, | ||
198 | * not shared with device. */ | ||
199 | if (id != IWL_CMD_QUEUE_NUM) { | ||
200 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
201 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
202 | if (!txq->txb) { | ||
203 | IWL_ERROR("kmalloc for auxiliary BD " | ||
204 | "structures failed\n"); | ||
205 | goto error; | ||
206 | } | ||
207 | } else | ||
208 | txq->txb = NULL; | ||
209 | |||
210 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
211 | * shared with device */ | ||
212 | txq->bd = pci_alloc_consistent(dev, | ||
213 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
214 | &txq->q.dma_addr); | ||
215 | |||
216 | if (!txq->bd) { | ||
217 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
218 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
219 | goto error; | ||
220 | } | ||
221 | txq->q.id = id; | ||
222 | |||
223 | return 0; | ||
224 | |||
225 | error: | ||
226 | kfree(txq->txb); | ||
227 | txq->txb = NULL; | ||
228 | |||
229 | return -ENOMEM; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
234 | * given Tx queue, and enable the DMA channel used for that queue. | ||
235 | * | ||
236 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
237 | * channels supported in hardware. | ||
238 | */ | ||
239 | static int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
240 | struct iwl_tx_queue *txq) | ||
241 | { | ||
242 | int rc; | ||
243 | unsigned long flags; | ||
244 | int txq_id = txq->q.id; | ||
245 | |||
246 | spin_lock_irqsave(&priv->lock, flags); | ||
247 | rc = iwl_grab_nic_access(priv); | ||
248 | if (rc) { | ||
249 | spin_unlock_irqrestore(&priv->lock, flags); | ||
250 | return rc; | ||
251 | } | ||
252 | |||
253 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
254 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
255 | txq->q.dma_addr >> 8); | ||
256 | |||
257 | /* Enable DMA channel, using same id as for TFD queue */ | ||
258 | iwl_write_direct32( | ||
259 | priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), | ||
260 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
261 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); | ||
262 | iwl_release_nic_access(priv); | ||
263 | spin_unlock_irqrestore(&priv->lock, flags); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
270 | */ | ||
271 | static int iwl_tx_queue_init(struct iwl_priv *priv, | ||
272 | struct iwl_tx_queue *txq, | ||
273 | int slots_num, u32 txq_id) | ||
274 | { | ||
275 | struct pci_dev *dev = priv->pci_dev; | ||
276 | int len; | ||
277 | int rc = 0; | ||
278 | |||
279 | /* | ||
280 | * Alloc buffer array for commands (Tx or other types of commands). | ||
281 | * For the command queue (#4), allocate command space + one big | ||
282 | * command for scan, since scan command is very huge; the system will | ||
283 | * not have two scans at the same time, so only one is needed. | ||
284 | * For normal Tx queues (all other queues), no super-size command | ||
285 | * space is needed. | ||
286 | */ | ||
287 | len = sizeof(struct iwl_cmd) * slots_num; | ||
288 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
289 | len += IWL_MAX_SCAN_SIZE; | ||
290 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
291 | if (!txq->cmd) | ||
292 | return -ENOMEM; | ||
293 | |||
294 | /* Alloc driver data array and TFD circular buffer */ | ||
295 | rc = iwl_tx_queue_alloc(priv, txq, txq_id); | ||
296 | if (rc) { | ||
297 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
298 | |||
299 | return -ENOMEM; | ||
300 | } | ||
301 | txq->need_update = 0; | ||
302 | |||
303 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
304 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
305 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
306 | |||
307 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
308 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
309 | |||
310 | /* Tell device where to find queue */ | ||
311 | iwl_hw_tx_queue_init(priv, txq); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * iwl_txq_ctx_reset - Reset TX queue context | ||
318 | * Destroys all DMA structures and initialise them again | ||
319 | * | ||
320 | * @param priv | ||
321 | * @return error code | ||
322 | */ | ||
323 | int iwl_txq_ctx_reset(struct iwl_priv *priv) | ||
324 | { | ||
325 | int ret = 0; | ||
326 | int txq_id, slots_num; | ||
327 | |||
328 | iwl_kw_free(priv); | ||
329 | |||
330 | /* Free all tx/cmd queues and keep-warm buffer */ | ||
331 | iwl_hw_txq_ctx_free(priv); | ||
332 | |||
333 | /* Alloc keep-warm buffer */ | ||
334 | ret = iwl_kw_alloc(priv); | ||
335 | if (ret) { | ||
336 | IWL_ERROR("Keep Warm allocation failed"); | ||
337 | goto error_kw; | ||
338 | } | ||
339 | |||
340 | /* Turn off all Tx DMA fifos */ | ||
341 | ret = priv->cfg->ops->lib->disable_tx_fifo(priv); | ||
342 | if (unlikely(ret)) | ||
343 | goto error_reset; | ||
344 | |||
345 | /* Tell nic where to find the keep-warm buffer */ | ||
346 | ret = iwl_kw_init(priv); | ||
347 | if (ret) { | ||
348 | IWL_ERROR("kw_init failed\n"); | ||
349 | goto error_reset; | ||
350 | } | ||
351 | |||
352 | /* Alloc and init all (default 16) Tx queues, | ||
353 | * including the command queue (#4) */ | ||
354 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
355 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | ||
356 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
357 | ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | ||
358 | txq_id); | ||
359 | if (ret) { | ||
360 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | ||
361 | goto error; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | return ret; | ||
366 | |||
367 | error: | ||
368 | iwl_hw_txq_ctx_free(priv); | ||
369 | error_reset: | ||
370 | iwl_kw_free(priv); | ||
371 | error_kw: | ||
372 | return ret; | ||
373 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 7040cde8bc28..c1234ff4fc98 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -6144,6 +6144,24 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
6144 | mutex_unlock(&priv->mutex); | 6144 | mutex_unlock(&priv->mutex); |
6145 | } | 6145 | } |
6146 | 6146 | ||
6147 | static void iwl3945_bg_set_monitor(struct work_struct *work) | ||
6148 | { | ||
6149 | struct iwl3945_priv *priv = container_of(work, | ||
6150 | struct iwl3945_priv, set_monitor); | ||
6151 | |||
6152 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | ||
6153 | |||
6154 | mutex_lock(&priv->mutex); | ||
6155 | |||
6156 | if (!iwl3945_is_ready(priv)) | ||
6157 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
6158 | else | ||
6159 | if (iwl3945_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) | ||
6160 | IWL_ERROR("iwl3945_set_mode() failed\n"); | ||
6161 | |||
6162 | mutex_unlock(&priv->mutex); | ||
6163 | } | ||
6164 | |||
6147 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 6165 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
6148 | 6166 | ||
6149 | static void iwl3945_bg_scan_check(struct work_struct *data) | 6167 | static void iwl3945_bg_scan_check(struct work_struct *data) |
@@ -6996,7 +7014,22 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6996 | * XXX: dummy | 7014 | * XXX: dummy |
6997 | * see also iwl3945_connection_init_rx_config | 7015 | * see also iwl3945_connection_init_rx_config |
6998 | */ | 7016 | */ |
6999 | *total_flags = 0; | 7017 | struct iwl3945_priv *priv = hw->priv; |
7018 | int new_flags = 0; | ||
7019 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | ||
7020 | if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | ||
7021 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | ||
7022 | IEEE80211_IF_TYPE_MNTR, | ||
7023 | changed_flags, *total_flags); | ||
7024 | /* queue work 'cuz mac80211 is holding a lock which | ||
7025 | * prevents us from issuing (synchronous) f/w cmds */ | ||
7026 | queue_work(priv->workqueue, &priv->set_monitor); | ||
7027 | new_flags &= FIF_PROMISC_IN_BSS | | ||
7028 | FIF_OTHER_BSS | | ||
7029 | FIF_ALLMULTI; | ||
7030 | } | ||
7031 | } | ||
7032 | *total_flags = new_flags; | ||
7000 | } | 7033 | } |
7001 | 7034 | ||
7002 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | 7035 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -7054,9 +7087,10 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
7054 | rc = -EAGAIN; | 7087 | rc = -EAGAIN; |
7055 | goto out_unlock; | 7088 | goto out_unlock; |
7056 | } | 7089 | } |
7057 | /* if we just finished scan ask for delay */ | 7090 | /* if we just finished scan ask for delay for a broadcast scan */ |
7058 | if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + | 7091 | if ((len == 0) && priv->last_scan_jiffies && |
7059 | IWL_DELAY_NEXT_SCAN, jiffies)) { | 7092 | time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, |
7093 | jiffies)) { | ||
7060 | rc = -EAGAIN; | 7094 | rc = -EAGAIN; |
7061 | goto out_unlock; | 7095 | goto out_unlock; |
7062 | } | 7096 | } |
@@ -7872,6 +7906,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | |||
7872 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); | 7906 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); |
7873 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); | 7907 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); |
7874 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 7908 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
7909 | INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor); | ||
7875 | INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate); | 7910 | INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate); |
7876 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 7911 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
7877 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 7912 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
@@ -7994,17 +8029,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7994 | 8029 | ||
7995 | priv->ibss_beacon = NULL; | 8030 | priv->ibss_beacon = NULL; |
7996 | 8031 | ||
7997 | /* Tell mac80211 and its clients (e.g. Wireless Extensions) | 8032 | /* Tell mac80211 our characteristics */ |
7998 | * the range of signal quality values that we'll provide. | 8033 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
7999 | * Negative values for level/noise indicate that we'll provide dBm. | 8034 | IEEE80211_HW_SIGNAL_DBM | |
8000 | * For WE, at least, non-0 values here *enable* display of values | 8035 | IEEE80211_HW_NOISE_DBM; |
8001 | * in app (iwconfig). */ | ||
8002 | hw->max_rssi = -20; /* signal level, negative indicates dBm */ | ||
8003 | hw->max_noise = -20; /* noise level, negative indicates dBm */ | ||
8004 | hw->max_signal = 100; /* link quality indication (%) */ | ||
8005 | |||
8006 | /* Tell mac80211 our Tx characteristics */ | ||
8007 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | ||
8008 | 8036 | ||
8009 | /* 4 EDCA QOS priorities */ | 8037 | /* 4 EDCA QOS priorities */ |
8010 | hw->queues = 4; | 8038 | hw->queues = 4; |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 4406fc72d881..55ca752ae9e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include "iwl-calib.h" | 54 | #include "iwl-calib.h" |
55 | 55 | ||
56 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | 56 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, |
57 | struct iwl4965_tx_queue *txq); | 57 | struct iwl_tx_queue *txq); |
58 | 58 | ||
59 | /****************************************************************************** | 59 | /****************************************************************************** |
60 | * | 60 | * |
@@ -145,6 +145,7 @@ static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) | |||
145 | return escaped; | 145 | return escaped; |
146 | } | 146 | } |
147 | 147 | ||
148 | |||
148 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | 149 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** |
149 | * DMA services | 150 | * DMA services |
150 | * | 151 | * |
@@ -206,173 +207,6 @@ static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) | |||
206 | return index & (q->n_window - 1); | 207 | return index & (q->n_window - 1); |
207 | } | 208 | } |
208 | 209 | ||
209 | /** | ||
210 | * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes | ||
211 | */ | ||
212 | static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
213 | int count, int slots_num, u32 id) | ||
214 | { | ||
215 | q->n_bd = count; | ||
216 | q->n_window = slots_num; | ||
217 | q->id = id; | ||
218 | |||
219 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
220 | * and iwl_queue_dec_wrap are broken. */ | ||
221 | BUG_ON(!is_power_of_2(count)); | ||
222 | |||
223 | /* slots_num must be power-of-two size, otherwise | ||
224 | * get_cmd_index is broken. */ | ||
225 | BUG_ON(!is_power_of_2(slots_num)); | ||
226 | |||
227 | q->low_mark = q->n_window / 4; | ||
228 | if (q->low_mark < 4) | ||
229 | q->low_mark = 4; | ||
230 | |||
231 | q->high_mark = q->n_window / 8; | ||
232 | if (q->high_mark < 2) | ||
233 | q->high_mark = 2; | ||
234 | |||
235 | q->write_ptr = q->read_ptr = 0; | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
242 | */ | ||
243 | static int iwl4965_tx_queue_alloc(struct iwl_priv *priv, | ||
244 | struct iwl4965_tx_queue *txq, u32 id) | ||
245 | { | ||
246 | struct pci_dev *dev = priv->pci_dev; | ||
247 | |||
248 | /* Driver private data, only for Tx (not command) queues, | ||
249 | * not shared with device. */ | ||
250 | if (id != IWL_CMD_QUEUE_NUM) { | ||
251 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
252 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
253 | if (!txq->txb) { | ||
254 | IWL_ERROR("kmalloc for auxiliary BD " | ||
255 | "structures failed\n"); | ||
256 | goto error; | ||
257 | } | ||
258 | } else | ||
259 | txq->txb = NULL; | ||
260 | |||
261 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
262 | * shared with device */ | ||
263 | txq->bd = pci_alloc_consistent(dev, | ||
264 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
265 | &txq->q.dma_addr); | ||
266 | |||
267 | if (!txq->bd) { | ||
268 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
269 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
270 | goto error; | ||
271 | } | ||
272 | txq->q.id = id; | ||
273 | |||
274 | return 0; | ||
275 | |||
276 | error: | ||
277 | if (txq->txb) { | ||
278 | kfree(txq->txb); | ||
279 | txq->txb = NULL; | ||
280 | } | ||
281 | |||
282 | return -ENOMEM; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
287 | */ | ||
288 | int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
289 | struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) | ||
290 | { | ||
291 | struct pci_dev *dev = priv->pci_dev; | ||
292 | int len; | ||
293 | int rc = 0; | ||
294 | |||
295 | /* | ||
296 | * Alloc buffer array for commands (Tx or other types of commands). | ||
297 | * For the command queue (#4), allocate command space + one big | ||
298 | * command for scan, since scan command is very huge; the system will | ||
299 | * not have two scans at the same time, so only one is needed. | ||
300 | * For normal Tx queues (all other queues), no super-size command | ||
301 | * space is needed. | ||
302 | */ | ||
303 | len = sizeof(struct iwl_cmd) * slots_num; | ||
304 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
305 | len += IWL_MAX_SCAN_SIZE; | ||
306 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
307 | if (!txq->cmd) | ||
308 | return -ENOMEM; | ||
309 | |||
310 | /* Alloc driver data array and TFD circular buffer */ | ||
311 | rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); | ||
312 | if (rc) { | ||
313 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
314 | |||
315 | return -ENOMEM; | ||
316 | } | ||
317 | txq->need_update = 0; | ||
318 | |||
319 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
320 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
321 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
322 | |||
323 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
324 | iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
325 | |||
326 | /* Tell device where to find queue */ | ||
327 | iwl4965_hw_tx_queue_init(priv, txq); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * iwl4965_tx_queue_free - Deallocate DMA queue. | ||
334 | * @txq: Transmit queue to deallocate. | ||
335 | * | ||
336 | * Empty queue by removing and destroying all BD's. | ||
337 | * Free all buffers. | ||
338 | * 0-fill, but do not free "txq" descriptor structure. | ||
339 | */ | ||
340 | void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
341 | { | ||
342 | struct iwl4965_queue *q = &txq->q; | ||
343 | struct pci_dev *dev = priv->pci_dev; | ||
344 | int len; | ||
345 | |||
346 | if (q->n_bd == 0) | ||
347 | return; | ||
348 | |||
349 | /* first, empty all BD's */ | ||
350 | for (; q->write_ptr != q->read_ptr; | ||
351 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
352 | iwl4965_hw_txq_free_tfd(priv, txq); | ||
353 | |||
354 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
355 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
356 | len += IWL_MAX_SCAN_SIZE; | ||
357 | |||
358 | /* De-alloc array of command/tx buffers */ | ||
359 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
360 | |||
361 | /* De-alloc circular buffer of TFDs */ | ||
362 | if (txq->q.n_bd) | ||
363 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * | ||
364 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
365 | |||
366 | /* De-alloc array of per-TFD driver data */ | ||
367 | if (txq->txb) { | ||
368 | kfree(txq->txb); | ||
369 | txq->txb = NULL; | ||
370 | } | ||
371 | |||
372 | /* 0-fill queue descriptor structure */ | ||
373 | memset(txq, 0, sizeof(*txq)); | ||
374 | } | ||
375 | |||
376 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 210 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
377 | 211 | ||
378 | /*************** STATION TABLE MANAGEMENT **** | 212 | /*************** STATION TABLE MANAGEMENT **** |
@@ -433,7 +267,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
433 | { | 267 | { |
434 | int i; | 268 | int i; |
435 | int index = IWL_INVALID_STATION; | 269 | int index = IWL_INVALID_STATION; |
436 | struct iwl4965_station_entry *station; | 270 | struct iwl_station_entry *station; |
437 | unsigned long flags_spin; | 271 | unsigned long flags_spin; |
438 | DECLARE_MAC_BUF(mac); | 272 | DECLARE_MAC_BUF(mac); |
439 | 273 | ||
@@ -476,7 +310,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
476 | priv->num_stations++; | 310 | priv->num_stations++; |
477 | 311 | ||
478 | /* Set up the REPLY_ADD_STA command to send to device */ | 312 | /* Set up the REPLY_ADD_STA command to send to device */ |
479 | memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); | 313 | memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); |
480 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | 314 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); |
481 | station->sta.mode = 0; | 315 | station->sta.mode = 0; |
482 | station->sta.sta.sta_id = index; | 316 | station->sta.sta.sta_id = index; |
@@ -493,7 +327,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
493 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 327 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
494 | 328 | ||
495 | /* Add station to device's station table */ | 329 | /* Add station to device's station table */ |
496 | iwl4965_send_add_station(priv, &station->sta, flags); | 330 | iwl_send_add_sta(priv, &station->sta, flags); |
497 | return index; | 331 | return index; |
498 | 332 | ||
499 | } | 333 | } |
@@ -513,9 +347,9 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
513 | */ | 347 | */ |
514 | int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | 348 | int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) |
515 | { | 349 | { |
516 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 350 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
517 | struct iwl4965_queue *q = &txq->q; | 351 | struct iwl4965_queue *q = &txq->q; |
518 | struct iwl4965_tfd_frame *tfd; | 352 | struct iwl_tfd_frame *tfd; |
519 | u32 *control_flags; | 353 | u32 *control_flags; |
520 | struct iwl_cmd *out_cmd; | 354 | struct iwl_cmd *out_cmd; |
521 | u32 idx; | 355 | u32 idx; |
@@ -902,8 +736,8 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv) | |||
902 | 736 | ||
903 | static int iwl4965_send_scan_abort(struct iwl_priv *priv) | 737 | static int iwl4965_send_scan_abort(struct iwl_priv *priv) |
904 | { | 738 | { |
905 | int rc = 0; | 739 | int ret = 0; |
906 | struct iwl4965_rx_packet *res; | 740 | struct iwl_rx_packet *res; |
907 | struct iwl_host_cmd cmd = { | 741 | struct iwl_host_cmd cmd = { |
908 | .id = REPLY_SCAN_ABORT_CMD, | 742 | .id = REPLY_SCAN_ABORT_CMD, |
909 | .meta.flags = CMD_WANT_SKB, | 743 | .meta.flags = CMD_WANT_SKB, |
@@ -917,13 +751,13 @@ static int iwl4965_send_scan_abort(struct iwl_priv *priv) | |||
917 | return 0; | 751 | return 0; |
918 | } | 752 | } |
919 | 753 | ||
920 | rc = iwl_send_cmd_sync(priv, &cmd); | 754 | ret = iwl_send_cmd_sync(priv, &cmd); |
921 | if (rc) { | 755 | if (ret) { |
922 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 756 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
923 | return rc; | 757 | return ret; |
924 | } | 758 | } |
925 | 759 | ||
926 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | 760 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
927 | if (res->u.status != CAN_ABORT_STATUS) { | 761 | if (res->u.status != CAN_ABORT_STATUS) { |
928 | /* The scan abort will return 1 for success or | 762 | /* The scan abort will return 1 for success or |
929 | * 2 for "failure". A failure condition can be | 763 | * 2 for "failure". A failure condition can be |
@@ -938,7 +772,7 @@ static int iwl4965_send_scan_abort(struct iwl_priv *priv) | |||
938 | 772 | ||
939 | dev_kfree_skb_any(cmd.meta.u.skb); | 773 | dev_kfree_skb_any(cmd.meta.u.skb); |
940 | 774 | ||
941 | return rc; | 775 | return ret; |
942 | } | 776 | } |
943 | 777 | ||
944 | /* | 778 | /* |
@@ -963,51 +797,6 @@ static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_fla | |||
963 | return iwl_send_cmd(priv, &cmd); | 797 | return iwl_send_cmd(priv, &cmd); |
964 | } | 798 | } |
965 | 799 | ||
966 | int iwl4965_send_add_station(struct iwl_priv *priv, | ||
967 | struct iwl4965_addsta_cmd *sta, u8 flags) | ||
968 | { | ||
969 | struct iwl4965_rx_packet *res = NULL; | ||
970 | int rc = 0; | ||
971 | struct iwl_host_cmd cmd = { | ||
972 | .id = REPLY_ADD_STA, | ||
973 | .len = sizeof(struct iwl4965_addsta_cmd), | ||
974 | .meta.flags = flags, | ||
975 | .data = sta, | ||
976 | }; | ||
977 | |||
978 | if (!(flags & CMD_ASYNC)) | ||
979 | cmd.meta.flags |= CMD_WANT_SKB; | ||
980 | |||
981 | rc = iwl_send_cmd(priv, &cmd); | ||
982 | |||
983 | if (rc || (flags & CMD_ASYNC)) | ||
984 | return rc; | ||
985 | |||
986 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | ||
987 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
988 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
989 | res->hdr.flags); | ||
990 | rc = -EIO; | ||
991 | } | ||
992 | |||
993 | if (rc == 0) { | ||
994 | switch (res->u.add_sta.status) { | ||
995 | case ADD_STA_SUCCESS_MSK: | ||
996 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); | ||
997 | break; | ||
998 | default: | ||
999 | rc = -EIO; | ||
1000 | IWL_WARNING("REPLY_ADD_STA failed\n"); | ||
1001 | break; | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | priv->alloc_rxb_skb--; | ||
1006 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
1007 | |||
1008 | return rc; | ||
1009 | } | ||
1010 | |||
1011 | static void iwl4965_clear_free_frames(struct iwl_priv *priv) | 800 | static void iwl4965_clear_free_frames(struct iwl_priv *priv) |
1012 | { | 801 | { |
1013 | struct list_head *element; | 802 | struct list_head *element; |
@@ -1783,7 +1572,7 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
1783 | struct sk_buff *skb_frag, | 1572 | struct sk_buff *skb_frag, |
1784 | int sta_id) | 1573 | int sta_id) |
1785 | { | 1574 | { |
1786 | struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; | 1575 | struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; |
1787 | struct iwl_wep_key *wepkey; | 1576 | struct iwl_wep_key *wepkey; |
1788 | int keyidx = 0; | 1577 | int keyidx = 0; |
1789 | 1578 | ||
@@ -1959,7 +1748,7 @@ static int iwl4965_get_sta_id(struct iwl_priv *priv, | |||
1959 | IWL_DEBUG_DROP("Station %s not in station map. " | 1748 | IWL_DEBUG_DROP("Station %s not in station map. " |
1960 | "Defaulting to broadcast...\n", | 1749 | "Defaulting to broadcast...\n", |
1961 | print_mac(mac, hdr->addr1)); | 1750 | print_mac(mac, hdr->addr1)); |
1962 | iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 1751 | iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
1963 | return priv->hw_params.bcast_sta_id; | 1752 | return priv->hw_params.bcast_sta_id; |
1964 | 1753 | ||
1965 | default: | 1754 | default: |
@@ -1975,10 +1764,10 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
1975 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | 1764 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) |
1976 | { | 1765 | { |
1977 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1766 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1978 | struct iwl4965_tfd_frame *tfd; | 1767 | struct iwl_tfd_frame *tfd; |
1979 | u32 *control_flags; | 1768 | u32 *control_flags; |
1980 | int txq_id = ctl->queue; | 1769 | int txq_id = ctl->queue; |
1981 | struct iwl4965_tx_queue *txq = NULL; | 1770 | struct iwl_tx_queue *txq = NULL; |
1982 | struct iwl4965_queue *q = NULL; | 1771 | struct iwl4965_queue *q = NULL; |
1983 | dma_addr_t phys_addr; | 1772 | dma_addr_t phys_addr; |
1984 | dma_addr_t txcmd_phys; | 1773 | dma_addr_t txcmd_phys; |
@@ -2175,10 +1964,10 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
2175 | txq->need_update = 0; | 1964 | txq->need_update = 0; |
2176 | } | 1965 | } |
2177 | 1966 | ||
2178 | iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, | 1967 | iwl_print_hex_dump(priv, IWL_DL_TX, out_cmd->cmd.payload, |
2179 | sizeof(out_cmd->cmd.tx)); | 1968 | sizeof(out_cmd->cmd.tx)); |
2180 | 1969 | ||
2181 | iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 1970 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, |
2182 | ieee80211_get_hdrlen(fc)); | 1971 | ieee80211_get_hdrlen(fc)); |
2183 | 1972 | ||
2184 | /* Set up entry for this TFD in Tx byte-count array */ | 1973 | /* Set up entry for this TFD in Tx byte-count array */ |
@@ -2441,7 +2230,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
2441 | u8 type) | 2230 | u8 type) |
2442 | { | 2231 | { |
2443 | struct iwl4965_spectrum_cmd spectrum; | 2232 | struct iwl4965_spectrum_cmd spectrum; |
2444 | struct iwl4965_rx_packet *res; | 2233 | struct iwl_rx_packet *res; |
2445 | struct iwl_host_cmd cmd = { | 2234 | struct iwl_host_cmd cmd = { |
2446 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, | 2235 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, |
2447 | .data = (void *)&spectrum, | 2236 | .data = (void *)&spectrum, |
@@ -2486,7 +2275,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
2486 | if (rc) | 2275 | if (rc) |
2487 | return rc; | 2276 | return rc; |
2488 | 2277 | ||
2489 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | 2278 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
2490 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 2279 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
2491 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); | 2280 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); |
2492 | rc = -EIO; | 2281 | rc = -EIO; |
@@ -2542,7 +2331,7 @@ static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv, | |||
2542 | */ | 2331 | */ |
2543 | int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | 2332 | int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) |
2544 | { | 2333 | { |
2545 | struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; | 2334 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
2546 | struct iwl4965_queue *q = &txq->q; | 2335 | struct iwl4965_queue *q = &txq->q; |
2547 | int nfreed = 0; | 2336 | int nfreed = 0; |
2548 | 2337 | ||
@@ -2559,7 +2348,7 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
2559 | if (txq_id != IWL_CMD_QUEUE_NUM) { | 2348 | if (txq_id != IWL_CMD_QUEUE_NUM) { |
2560 | iwl4965_txstatus_to_ieee(priv, | 2349 | iwl4965_txstatus_to_ieee(priv, |
2561 | &(txq->txb[txq->q.read_ptr])); | 2350 | &(txq->txb[txq->q.read_ptr])); |
2562 | iwl4965_hw_txq_free_tfd(priv, txq); | 2351 | iwl_hw_txq_free_tfd(priv, txq); |
2563 | } else if (nfreed > 1) { | 2352 | } else if (nfreed > 1) { |
2564 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | 2353 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, |
2565 | q->write_ptr, q->read_ptr); | 2354 | q->write_ptr, q->read_ptr); |
@@ -2568,12 +2357,6 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
2568 | nfreed++; | 2357 | nfreed++; |
2569 | } | 2358 | } |
2570 | 2359 | ||
2571 | /* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && | ||
2572 | (txq_id != IWL_CMD_QUEUE_NUM) && | ||
2573 | priv->mac80211_registered) | ||
2574 | ieee80211_wake_queue(priv->hw, txq_id); */ | ||
2575 | |||
2576 | |||
2577 | return nfreed; | 2360 | return nfreed; |
2578 | } | 2361 | } |
2579 | 2362 | ||
@@ -2623,7 +2406,7 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | |||
2623 | * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue | 2406 | * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue |
2624 | */ | 2407 | */ |
2625 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | 2408 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, |
2626 | struct iwl4965_ht_agg *agg, | 2409 | struct iwl_ht_agg *agg, |
2627 | struct iwl4965_tx_resp_agg *tx_resp, | 2410 | struct iwl4965_tx_resp_agg *tx_resp, |
2628 | u16 start_idx) | 2411 | u16 start_idx) |
2629 | { | 2412 | { |
@@ -2742,13 +2525,13 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
2742 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | 2525 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response |
2743 | */ | 2526 | */ |
2744 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | 2527 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, |
2745 | struct iwl4965_rx_mem_buffer *rxb) | 2528 | struct iwl_rx_mem_buffer *rxb) |
2746 | { | 2529 | { |
2747 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2530 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2748 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 2531 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
2749 | int txq_id = SEQ_TO_QUEUE(sequence); | 2532 | int txq_id = SEQ_TO_QUEUE(sequence); |
2750 | int index = SEQ_TO_INDEX(sequence); | 2533 | int index = SEQ_TO_INDEX(sequence); |
2751 | struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; | 2534 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
2752 | struct ieee80211_tx_status *tx_status; | 2535 | struct ieee80211_tx_status *tx_status; |
2753 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 2536 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
2754 | u32 status = le32_to_cpu(tx_resp->status); | 2537 | u32 status = le32_to_cpu(tx_resp->status); |
@@ -2781,7 +2564,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2781 | 2564 | ||
2782 | if (txq->sched_retry) { | 2565 | if (txq->sched_retry) { |
2783 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); | 2566 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); |
2784 | struct iwl4965_ht_agg *agg = NULL; | 2567 | struct iwl_ht_agg *agg = NULL; |
2785 | 2568 | ||
2786 | if (!qc) | 2569 | if (!qc) |
2787 | return; | 2570 | return; |
@@ -2797,7 +2580,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2797 | } | 2580 | } |
2798 | 2581 | ||
2799 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { | 2582 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { |
2800 | int freed; | 2583 | int freed, ampdu_q; |
2801 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | 2584 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); |
2802 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | 2585 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " |
2803 | "%d index %d\n", scd_ssn , index); | 2586 | "%d index %d\n", scd_ssn , index); |
@@ -2806,9 +2589,15 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2806 | 2589 | ||
2807 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 2590 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
2808 | txq_id >= 0 && priv->mac80211_registered && | 2591 | txq_id >= 0 && priv->mac80211_registered && |
2809 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | 2592 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { |
2810 | ieee80211_wake_queue(priv->hw, txq_id); | 2593 | /* calculate mac80211 ampdu sw queue to wake */ |
2811 | 2594 | ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + | |
2595 | priv->hw->queues; | ||
2596 | if (agg->state == IWL_AGG_OFF) | ||
2597 | ieee80211_wake_queue(priv->hw, txq_id); | ||
2598 | else | ||
2599 | ieee80211_wake_queue(priv->hw, ampdu_q); | ||
2600 | } | ||
2812 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | 2601 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); |
2813 | } | 2602 | } |
2814 | } else { | 2603 | } else { |
@@ -2827,20 +2616,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2827 | tx_resp->failure_frame); | 2616 | tx_resp->failure_frame); |
2828 | 2617 | ||
2829 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 2618 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
2619 | #ifdef CONFIG_IWL4965_HT | ||
2830 | if (index != -1) { | 2620 | if (index != -1) { |
2831 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | 2621 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); |
2832 | #ifdef CONFIG_IWL4965_HT | ||
2833 | if (tid != MAX_TID_COUNT) | 2622 | if (tid != MAX_TID_COUNT) |
2834 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 2623 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
2835 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 2624 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
2836 | (txq_id >= 0) && | 2625 | (txq_id >= 0) && priv->mac80211_registered) |
2837 | priv->mac80211_registered) | ||
2838 | ieee80211_wake_queue(priv->hw, txq_id); | 2626 | ieee80211_wake_queue(priv->hw, txq_id); |
2839 | if (tid != MAX_TID_COUNT) | 2627 | if (tid != MAX_TID_COUNT) |
2840 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | 2628 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); |
2841 | #endif | ||
2842 | } | 2629 | } |
2843 | #ifdef CONFIG_IWL4965_HT | ||
2844 | } | 2630 | } |
2845 | #endif /* CONFIG_IWL4965_HT */ | 2631 | #endif /* CONFIG_IWL4965_HT */ |
2846 | 2632 | ||
@@ -2850,9 +2636,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2850 | 2636 | ||
2851 | 2637 | ||
2852 | static void iwl4965_rx_reply_alive(struct iwl_priv *priv, | 2638 | static void iwl4965_rx_reply_alive(struct iwl_priv *priv, |
2853 | struct iwl4965_rx_mem_buffer *rxb) | 2639 | struct iwl_rx_mem_buffer *rxb) |
2854 | { | 2640 | { |
2855 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2641 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2856 | struct iwl4965_alive_resp *palive; | 2642 | struct iwl4965_alive_resp *palive; |
2857 | struct delayed_work *pwork; | 2643 | struct delayed_work *pwork; |
2858 | 2644 | ||
@@ -2886,18 +2672,18 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv, | |||
2886 | } | 2672 | } |
2887 | 2673 | ||
2888 | static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, | 2674 | static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, |
2889 | struct iwl4965_rx_mem_buffer *rxb) | 2675 | struct iwl_rx_mem_buffer *rxb) |
2890 | { | 2676 | { |
2891 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2677 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2892 | 2678 | ||
2893 | IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); | 2679 | IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); |
2894 | return; | 2680 | return; |
2895 | } | 2681 | } |
2896 | 2682 | ||
2897 | static void iwl4965_rx_reply_error(struct iwl_priv *priv, | 2683 | static void iwl4965_rx_reply_error(struct iwl_priv *priv, |
2898 | struct iwl4965_rx_mem_buffer *rxb) | 2684 | struct iwl_rx_mem_buffer *rxb) |
2899 | { | 2685 | { |
2900 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2686 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2901 | 2687 | ||
2902 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " | 2688 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " |
2903 | "seq 0x%04X ser 0x%08X\n", | 2689 | "seq 0x%04X ser 0x%08X\n", |
@@ -2910,9 +2696,9 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv, | |||
2910 | 2696 | ||
2911 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 2697 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
2912 | 2698 | ||
2913 | static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) | 2699 | static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
2914 | { | 2700 | { |
2915 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2701 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2916 | struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; | 2702 | struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; |
2917 | struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); | 2703 | struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); |
2918 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", | 2704 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", |
@@ -2922,15 +2708,15 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer * | |||
2922 | } | 2708 | } |
2923 | 2709 | ||
2924 | static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, | 2710 | static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, |
2925 | struct iwl4965_rx_mem_buffer *rxb) | 2711 | struct iwl_rx_mem_buffer *rxb) |
2926 | { | 2712 | { |
2927 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 2713 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
2928 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2714 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2929 | struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); | 2715 | struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); |
2930 | 2716 | ||
2931 | if (!report->state) { | 2717 | if (!report->state) { |
2932 | IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, | 2718 | IWL_DEBUG(IWL_DL_11H, |
2933 | "Spectrum Measure Notification: Start\n"); | 2719 | "Spectrum Measure Notification: Start\n"); |
2934 | return; | 2720 | return; |
2935 | } | 2721 | } |
2936 | 2722 | ||
@@ -2940,10 +2726,10 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
2940 | } | 2726 | } |
2941 | 2727 | ||
2942 | static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, | 2728 | static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, |
2943 | struct iwl4965_rx_mem_buffer *rxb) | 2729 | struct iwl_rx_mem_buffer *rxb) |
2944 | { | 2730 | { |
2945 | #ifdef CONFIG_IWLWIFI_DEBUG | 2731 | #ifdef CONFIG_IWLWIFI_DEBUG |
2946 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2732 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2947 | struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); | 2733 | struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); |
2948 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", | 2734 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", |
2949 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 2735 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
@@ -2951,13 +2737,13 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
2951 | } | 2737 | } |
2952 | 2738 | ||
2953 | static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 2739 | static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
2954 | struct iwl4965_rx_mem_buffer *rxb) | 2740 | struct iwl_rx_mem_buffer *rxb) |
2955 | { | 2741 | { |
2956 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2742 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2957 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " | 2743 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " |
2958 | "notification for %s:\n", | 2744 | "notification for %s:\n", |
2959 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); | 2745 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); |
2960 | iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); | 2746 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); |
2961 | } | 2747 | } |
2962 | 2748 | ||
2963 | static void iwl4965_bg_beacon_update(struct work_struct *work) | 2749 | static void iwl4965_bg_beacon_update(struct work_struct *work) |
@@ -2986,10 +2772,10 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) | |||
2986 | } | 2772 | } |
2987 | 2773 | ||
2988 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | 2774 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, |
2989 | struct iwl4965_rx_mem_buffer *rxb) | 2775 | struct iwl_rx_mem_buffer *rxb) |
2990 | { | 2776 | { |
2991 | #ifdef CONFIG_IWLWIFI_DEBUG | 2777 | #ifdef CONFIG_IWLWIFI_DEBUG |
2992 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2778 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2993 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); | 2779 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); |
2994 | u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 2780 | u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
2995 | 2781 | ||
@@ -3009,10 +2795,10 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | |||
3009 | 2795 | ||
3010 | /* Service response to REPLY_SCAN_CMD (0x80) */ | 2796 | /* Service response to REPLY_SCAN_CMD (0x80) */ |
3011 | static void iwl4965_rx_reply_scan(struct iwl_priv *priv, | 2797 | static void iwl4965_rx_reply_scan(struct iwl_priv *priv, |
3012 | struct iwl4965_rx_mem_buffer *rxb) | 2798 | struct iwl_rx_mem_buffer *rxb) |
3013 | { | 2799 | { |
3014 | #ifdef CONFIG_IWLWIFI_DEBUG | 2800 | #ifdef CONFIG_IWLWIFI_DEBUG |
3015 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2801 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3016 | struct iwl4965_scanreq_notification *notif = | 2802 | struct iwl4965_scanreq_notification *notif = |
3017 | (struct iwl4965_scanreq_notification *)pkt->u.raw; | 2803 | (struct iwl4965_scanreq_notification *)pkt->u.raw; |
3018 | 2804 | ||
@@ -3022,9 +2808,9 @@ static void iwl4965_rx_reply_scan(struct iwl_priv *priv, | |||
3022 | 2808 | ||
3023 | /* Service SCAN_START_NOTIFICATION (0x82) */ | 2809 | /* Service SCAN_START_NOTIFICATION (0x82) */ |
3024 | static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, | 2810 | static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, |
3025 | struct iwl4965_rx_mem_buffer *rxb) | 2811 | struct iwl_rx_mem_buffer *rxb) |
3026 | { | 2812 | { |
3027 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2813 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3028 | struct iwl4965_scanstart_notification *notif = | 2814 | struct iwl4965_scanstart_notification *notif = |
3029 | (struct iwl4965_scanstart_notification *)pkt->u.raw; | 2815 | (struct iwl4965_scanstart_notification *)pkt->u.raw; |
3030 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 2816 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
@@ -3039,9 +2825,9 @@ static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, | |||
3039 | 2825 | ||
3040 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 2826 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
3041 | static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, | 2827 | static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, |
3042 | struct iwl4965_rx_mem_buffer *rxb) | 2828 | struct iwl_rx_mem_buffer *rxb) |
3043 | { | 2829 | { |
3044 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2830 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3045 | struct iwl4965_scanresults_notification *notif = | 2831 | struct iwl4965_scanresults_notification *notif = |
3046 | (struct iwl4965_scanresults_notification *)pkt->u.raw; | 2832 | (struct iwl4965_scanresults_notification *)pkt->u.raw; |
3047 | 2833 | ||
@@ -3064,9 +2850,9 @@ static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, | |||
3064 | 2850 | ||
3065 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | 2851 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ |
3066 | static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | 2852 | static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, |
3067 | struct iwl4965_rx_mem_buffer *rxb) | 2853 | struct iwl_rx_mem_buffer *rxb) |
3068 | { | 2854 | { |
3069 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2855 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3070 | struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 2856 | struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; |
3071 | 2857 | ||
3072 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 2858 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
@@ -3122,9 +2908,9 @@ reschedule: | |||
3122 | /* Handle notification from uCode that card's power state is changing | 2908 | /* Handle notification from uCode that card's power state is changing |
3123 | * due to software, hardware, or critical temperature RFKILL */ | 2909 | * due to software, hardware, or critical temperature RFKILL */ |
3124 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | 2910 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, |
3125 | struct iwl4965_rx_mem_buffer *rxb) | 2911 | struct iwl_rx_mem_buffer *rxb) |
3126 | { | 2912 | { |
3127 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2913 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3128 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 2914 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
3129 | unsigned long status = priv->status; | 2915 | unsigned long status = priv->status; |
3130 | 2916 | ||
@@ -3242,9 +3028,9 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
3242 | * if the callback returns 1 | 3028 | * if the callback returns 1 |
3243 | */ | 3029 | */ |
3244 | static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, | 3030 | static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, |
3245 | struct iwl4965_rx_mem_buffer *rxb) | 3031 | struct iwl_rx_mem_buffer *rxb) |
3246 | { | 3032 | { |
3247 | struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 3033 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3248 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 3034 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
3249 | int txq_id = SEQ_TO_QUEUE(sequence); | 3035 | int txq_id = SEQ_TO_QUEUE(sequence); |
3250 | int index = SEQ_TO_INDEX(sequence); | 3036 | int index = SEQ_TO_INDEX(sequence); |
@@ -3279,438 +3065,28 @@ static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, | |||
3279 | } | 3065 | } |
3280 | } | 3066 | } |
3281 | 3067 | ||
3282 | /************************** RX-FUNCTIONS ****************************/ | ||
3283 | /* | ||
3284 | * Rx theory of operation | ||
3285 | * | ||
3286 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
3287 | * each of which point to Receive Buffers to be filled by 4965. These get | ||
3288 | * used not only for Rx frames, but for any command response or notification | ||
3289 | * from the 4965. The driver and 4965 manage the Rx buffers by means | ||
3290 | * of indexes into the circular buffer. | ||
3291 | * | ||
3292 | * Rx Queue Indexes | ||
3293 | * The host/firmware share two index registers for managing the Rx buffers. | ||
3294 | * | ||
3295 | * The READ index maps to the first position that the firmware may be writing | ||
3296 | * to -- the driver can read up to (but not including) this position and get | ||
3297 | * good data. | ||
3298 | * The READ index is managed by the firmware once the card is enabled. | ||
3299 | * | ||
3300 | * The WRITE index maps to the last position the driver has read from -- the | ||
3301 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
3302 | * | ||
3303 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
3304 | * WRITE = READ. | ||
3305 | * | ||
3306 | * During initialization, the host sets up the READ queue position to the first | ||
3307 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
3308 | * | ||
3309 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
3310 | * and fire the RX interrupt. The driver can then query the READ index and | ||
3311 | * process as many packets as possible, moving the WRITE index forward as it | ||
3312 | * resets the Rx queue buffers with new memory. | ||
3313 | * | ||
3314 | * The management in the driver is as follows: | ||
3315 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
3316 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
3317 | * to replenish the iwl->rxq->rx_free. | ||
3318 | * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
3319 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
3320 | * 'processed' and 'read' driver indexes as well) | ||
3321 | * + A received packet is processed and handed to the kernel network stack, | ||
3322 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
3323 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
3324 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
3325 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
3326 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
3327 | * | ||
3328 | * | ||
3329 | * Driver sequence: | ||
3330 | * | ||
3331 | * iwl4965_rx_queue_alloc() Allocates rx_free | ||
3332 | * iwl4965_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
3333 | * iwl4965_rx_queue_restock | ||
3334 | * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
3335 | * queue, updates firmware pointers, and updates | ||
3336 | * the WRITE index. If insufficient rx_free buffers | ||
3337 | * are available, schedules iwl4965_rx_replenish | ||
3338 | * | ||
3339 | * -- enable interrupts -- | ||
3340 | * ISR - iwl4965_rx() Detach iwl4965_rx_mem_buffers from pool up to the | ||
3341 | * READ INDEX, detaching the SKB from the pool. | ||
3342 | * Moves the packet buffer from queue to rx_used. | ||
3343 | * Calls iwl4965_rx_queue_restock to refill any empty | ||
3344 | * slots. | ||
3345 | * ... | ||
3346 | * | ||
3347 | */ | ||
3348 | |||
3349 | /** | ||
3350 | * iwl4965_rx_queue_space - Return number of free slots available in queue. | ||
3351 | */ | ||
3352 | static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q) | ||
3353 | { | ||
3354 | int s = q->read - q->write; | ||
3355 | if (s <= 0) | ||
3356 | s += RX_QUEUE_SIZE; | ||
3357 | /* keep some buffer to not confuse full and empty queue */ | ||
3358 | s -= 2; | ||
3359 | if (s < 0) | ||
3360 | s = 0; | ||
3361 | return s; | ||
3362 | } | ||
3363 | |||
3364 | /** | ||
3365 | * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
3366 | */ | ||
3367 | int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_rx_queue *q) | ||
3368 | { | ||
3369 | u32 reg = 0; | ||
3370 | int rc = 0; | ||
3371 | unsigned long flags; | ||
3372 | |||
3373 | spin_lock_irqsave(&q->lock, flags); | ||
3374 | |||
3375 | if (q->need_update == 0) | ||
3376 | goto exit_unlock; | ||
3377 | |||
3378 | /* If power-saving is in use, make sure device is awake */ | ||
3379 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
3380 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
3381 | |||
3382 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
3383 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
3384 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
3385 | goto exit_unlock; | ||
3386 | } | ||
3387 | |||
3388 | rc = iwl_grab_nic_access(priv); | ||
3389 | if (rc) | ||
3390 | goto exit_unlock; | ||
3391 | |||
3392 | /* Device expects a multiple of 8 */ | ||
3393 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
3394 | q->write & ~0x7); | ||
3395 | iwl_release_nic_access(priv); | ||
3396 | |||
3397 | /* Else device is assumed to be awake */ | ||
3398 | } else | ||
3399 | /* Device expects a multiple of 8 */ | ||
3400 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | ||
3401 | |||
3402 | |||
3403 | q->need_update = 0; | ||
3404 | |||
3405 | exit_unlock: | ||
3406 | spin_unlock_irqrestore(&q->lock, flags); | ||
3407 | return rc; | ||
3408 | } | ||
3409 | |||
3410 | /** | ||
3411 | * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
3412 | */ | ||
3413 | static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl_priv *priv, | ||
3414 | dma_addr_t dma_addr) | ||
3415 | { | ||
3416 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
3417 | } | ||
3418 | |||
3419 | |||
3420 | /** | ||
3421 | * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool | ||
3422 | * | ||
3423 | * If there are slots in the RX queue that need to be restocked, | ||
3424 | * and we have free pre-allocated buffers, fill the ranks as much | ||
3425 | * as we can, pulling from rx_free. | ||
3426 | * | ||
3427 | * This moves the 'write' index forward to catch up with 'processed', and | ||
3428 | * also updates the memory address in the firmware to reference the new | ||
3429 | * target buffer. | ||
3430 | */ | ||
3431 | static int iwl4965_rx_queue_restock(struct iwl_priv *priv) | ||
3432 | { | ||
3433 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
3434 | struct list_head *element; | ||
3435 | struct iwl4965_rx_mem_buffer *rxb; | ||
3436 | unsigned long flags; | ||
3437 | int write, rc; | ||
3438 | |||
3439 | spin_lock_irqsave(&rxq->lock, flags); | ||
3440 | write = rxq->write & ~0x7; | ||
3441 | while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | ||
3442 | /* Get next free Rx buffer, remove from free list */ | ||
3443 | element = rxq->rx_free.next; | ||
3444 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | ||
3445 | list_del(element); | ||
3446 | |||
3447 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
3448 | rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); | ||
3449 | rxq->queue[rxq->write] = rxb; | ||
3450 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | ||
3451 | rxq->free_count--; | ||
3452 | } | ||
3453 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3454 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
3455 | * refill it */ | ||
3456 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
3457 | queue_work(priv->workqueue, &priv->rx_replenish); | ||
3458 | |||
3459 | |||
3460 | /* If we've added more space for the firmware to place data, tell it. | ||
3461 | * Increment device's write pointer in multiples of 8. */ | ||
3462 | if ((write != (rxq->write & ~0x7)) | ||
3463 | || (abs(rxq->write - rxq->read) > 7)) { | ||
3464 | spin_lock_irqsave(&rxq->lock, flags); | ||
3465 | rxq->need_update = 1; | ||
3466 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3467 | rc = iwl4965_rx_queue_update_write_ptr(priv, rxq); | ||
3468 | if (rc) | ||
3469 | return rc; | ||
3470 | } | ||
3471 | |||
3472 | return 0; | ||
3473 | } | ||
3474 | |||
3475 | /** | ||
3476 | * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free | ||
3477 | * | ||
3478 | * When moving to rx_free an SKB is allocated for the slot. | ||
3479 | * | ||
3480 | * Also restock the Rx queue via iwl4965_rx_queue_restock. | ||
3481 | * This is called as a scheduled work item (except for during initialization) | ||
3482 | */ | ||
3483 | static void iwl4965_rx_allocate(struct iwl_priv *priv) | ||
3484 | { | ||
3485 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
3486 | struct list_head *element; | ||
3487 | struct iwl4965_rx_mem_buffer *rxb; | ||
3488 | unsigned long flags; | ||
3489 | spin_lock_irqsave(&rxq->lock, flags); | ||
3490 | while (!list_empty(&rxq->rx_used)) { | ||
3491 | element = rxq->rx_used.next; | ||
3492 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | ||
3493 | |||
3494 | /* Alloc a new receive buffer */ | ||
3495 | rxb->skb = | ||
3496 | alloc_skb(priv->hw_params.rx_buf_size, | ||
3497 | __GFP_NOWARN | GFP_ATOMIC); | ||
3498 | if (!rxb->skb) { | ||
3499 | if (net_ratelimit()) | ||
3500 | printk(KERN_CRIT DRV_NAME | ||
3501 | ": Can not allocate SKB buffers\n"); | ||
3502 | /* We don't reschedule replenish work here -- we will | ||
3503 | * call the restock method and if it still needs | ||
3504 | * more buffers it will schedule replenish */ | ||
3505 | break; | ||
3506 | } | ||
3507 | priv->alloc_rxb_skb++; | ||
3508 | list_del(element); | ||
3509 | |||
3510 | /* Get physical address of RB/SKB */ | ||
3511 | rxb->dma_addr = | ||
3512 | pci_map_single(priv->pci_dev, rxb->skb->data, | ||
3513 | priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); | ||
3514 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
3515 | rxq->free_count++; | ||
3516 | } | ||
3517 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3518 | } | ||
3519 | |||
3520 | /* | 3068 | /* |
3521 | * this should be called while priv->lock is locked | 3069 | * this should be called while priv->lock is locked |
3522 | */ | 3070 | */ |
3523 | static void __iwl4965_rx_replenish(void *data) | 3071 | static void __iwl_rx_replenish(struct iwl_priv *priv) |
3524 | { | ||
3525 | struct iwl_priv *priv = data; | ||
3526 | |||
3527 | iwl4965_rx_allocate(priv); | ||
3528 | iwl4965_rx_queue_restock(priv); | ||
3529 | } | ||
3530 | |||
3531 | |||
3532 | void iwl4965_rx_replenish(void *data) | ||
3533 | { | ||
3534 | struct iwl_priv *priv = data; | ||
3535 | unsigned long flags; | ||
3536 | |||
3537 | iwl4965_rx_allocate(priv); | ||
3538 | |||
3539 | spin_lock_irqsave(&priv->lock, flags); | ||
3540 | iwl4965_rx_queue_restock(priv); | ||
3541 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3542 | } | ||
3543 | |||
3544 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | ||
3545 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | ||
3546 | * This free routine walks the list of POOL entries and if SKB is set to | ||
3547 | * non NULL it is unmapped and freed | ||
3548 | */ | ||
3549 | static void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | ||
3550 | { | ||
3551 | int i; | ||
3552 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | ||
3553 | if (rxq->pool[i].skb != NULL) { | ||
3554 | pci_unmap_single(priv->pci_dev, | ||
3555 | rxq->pool[i].dma_addr, | ||
3556 | priv->hw_params.rx_buf_size, | ||
3557 | PCI_DMA_FROMDEVICE); | ||
3558 | dev_kfree_skb(rxq->pool[i].skb); | ||
3559 | } | ||
3560 | } | ||
3561 | |||
3562 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
3563 | rxq->dma_addr); | ||
3564 | rxq->bd = NULL; | ||
3565 | } | ||
3566 | |||
3567 | int iwl4965_rx_queue_alloc(struct iwl_priv *priv) | ||
3568 | { | 3072 | { |
3569 | struct iwl4965_rx_queue *rxq = &priv->rxq; | 3073 | iwl_rx_allocate(priv); |
3570 | struct pci_dev *dev = priv->pci_dev; | 3074 | iwl_rx_queue_restock(priv); |
3571 | int i; | ||
3572 | |||
3573 | spin_lock_init(&rxq->lock); | ||
3574 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3575 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3576 | |||
3577 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
3578 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | ||
3579 | if (!rxq->bd) | ||
3580 | return -ENOMEM; | ||
3581 | |||
3582 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3583 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | ||
3584 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3585 | |||
3586 | /* Set us so that we have processed and used all buffers, but have | ||
3587 | * not restocked the Rx queue with fresh buffers */ | ||
3588 | rxq->read = rxq->write = 0; | ||
3589 | rxq->free_count = 0; | ||
3590 | rxq->need_update = 0; | ||
3591 | return 0; | ||
3592 | } | 3075 | } |
3593 | 3076 | ||
3594 | void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | ||
3595 | { | ||
3596 | unsigned long flags; | ||
3597 | int i; | ||
3598 | spin_lock_irqsave(&rxq->lock, flags); | ||
3599 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3600 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3601 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3602 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
3603 | /* In the reset function, these buffers may have been allocated | ||
3604 | * to an SKB, so we need to unmap and free potential storage */ | ||
3605 | if (rxq->pool[i].skb != NULL) { | ||
3606 | pci_unmap_single(priv->pci_dev, | ||
3607 | rxq->pool[i].dma_addr, | ||
3608 | priv->hw_params.rx_buf_size, | ||
3609 | PCI_DMA_FROMDEVICE); | ||
3610 | priv->alloc_rxb_skb--; | ||
3611 | dev_kfree_skb(rxq->pool[i].skb); | ||
3612 | rxq->pool[i].skb = NULL; | ||
3613 | } | ||
3614 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3615 | } | ||
3616 | |||
3617 | /* Set us so that we have processed and used all buffers, but have | ||
3618 | * not restocked the Rx queue with fresh buffers */ | ||
3619 | rxq->read = rxq->write = 0; | ||
3620 | rxq->free_count = 0; | ||
3621 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3622 | } | ||
3623 | |||
3624 | /* Convert linear signal-to-noise ratio into dB */ | ||
3625 | static u8 ratio2dB[100] = { | ||
3626 | /* 0 1 2 3 4 5 6 7 8 9 */ | ||
3627 | 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ | ||
3628 | 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ | ||
3629 | 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ | ||
3630 | 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ | ||
3631 | 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ | ||
3632 | 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ | ||
3633 | 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ | ||
3634 | 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ | ||
3635 | 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ | ||
3636 | 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ | ||
3637 | }; | ||
3638 | |||
3639 | /* Calculates a relative dB value from a ratio of linear | ||
3640 | * (i.e. not dB) signal levels. | ||
3641 | * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ | ||
3642 | int iwl4965_calc_db_from_ratio(int sig_ratio) | ||
3643 | { | ||
3644 | /* 1000:1 or higher just report as 60 dB */ | ||
3645 | if (sig_ratio >= 1000) | ||
3646 | return 60; | ||
3647 | |||
3648 | /* 100:1 or higher, divide by 10 and use table, | ||
3649 | * add 20 dB to make up for divide by 10 */ | ||
3650 | if (sig_ratio >= 100) | ||
3651 | return (20 + (int)ratio2dB[sig_ratio/10]); | ||
3652 | |||
3653 | /* We shouldn't see this */ | ||
3654 | if (sig_ratio < 1) | ||
3655 | return 0; | ||
3656 | |||
3657 | /* Use table for ratios 1:1 - 99:1 */ | ||
3658 | return (int)ratio2dB[sig_ratio]; | ||
3659 | } | ||
3660 | |||
3661 | #define PERFECT_RSSI (-20) /* dBm */ | ||
3662 | #define WORST_RSSI (-95) /* dBm */ | ||
3663 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
3664 | |||
3665 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
3666 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
3667 | * about formulas used below. */ | ||
3668 | int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
3669 | { | ||
3670 | int sig_qual; | ||
3671 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
3672 | |||
3673 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
3674 | * as indicator; formula is (signal dbm - noise dbm). | ||
3675 | * SNR at or above 40 is a great signal (100%). | ||
3676 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
3677 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
3678 | if (noise_dbm) { | ||
3679 | if (rssi_dbm - noise_dbm >= 40) | ||
3680 | return 100; | ||
3681 | else if (rssi_dbm < noise_dbm) | ||
3682 | return 0; | ||
3683 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
3684 | |||
3685 | /* Else use just the signal level. | ||
3686 | * This formula is a least squares fit of data points collected and | ||
3687 | * compared with a reference system that had a percentage (%) display | ||
3688 | * for signal quality. */ | ||
3689 | } else | ||
3690 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
3691 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
3692 | (RSSI_RANGE * RSSI_RANGE); | ||
3693 | |||
3694 | if (sig_qual > 100) | ||
3695 | sig_qual = 100; | ||
3696 | else if (sig_qual < 1) | ||
3697 | sig_qual = 0; | ||
3698 | |||
3699 | return sig_qual; | ||
3700 | } | ||
3701 | 3077 | ||
3702 | /** | 3078 | /** |
3703 | * iwl4965_rx_handle - Main entry function for receiving responses from uCode | 3079 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
3704 | * | 3080 | * |
3705 | * Uses the priv->rx_handlers callback function array to invoke | 3081 | * Uses the priv->rx_handlers callback function array to invoke |
3706 | * the appropriate handlers, including command responses, | 3082 | * the appropriate handlers, including command responses, |
3707 | * frame-received notifications, and other notifications. | 3083 | * frame-received notifications, and other notifications. |
3708 | */ | 3084 | */ |
3709 | static void iwl4965_rx_handle(struct iwl_priv *priv) | 3085 | void iwl_rx_handle(struct iwl_priv *priv) |
3710 | { | 3086 | { |
3711 | struct iwl4965_rx_mem_buffer *rxb; | 3087 | struct iwl_rx_mem_buffer *rxb; |
3712 | struct iwl4965_rx_packet *pkt; | 3088 | struct iwl_rx_packet *pkt; |
3713 | struct iwl4965_rx_queue *rxq = &priv->rxq; | 3089 | struct iwl_rx_queue *rxq = &priv->rxq; |
3714 | u32 r, i; | 3090 | u32 r, i; |
3715 | int reclaim; | 3091 | int reclaim; |
3716 | unsigned long flags; | 3092 | unsigned long flags; |
@@ -3719,14 +3095,14 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3719 | 3095 | ||
3720 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 3096 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
3721 | * buffer that the driver may process (last buffer filled by ucode). */ | 3097 | * buffer that the driver may process (last buffer filled by ucode). */ |
3722 | r = iwl4965_hw_get_rx_read(priv); | 3098 | r = priv->cfg->ops->lib->shared_mem_rx_idx(priv); |
3723 | i = rxq->read; | 3099 | i = rxq->read; |
3724 | 3100 | ||
3725 | /* Rx interrupt, but nothing sent from uCode */ | 3101 | /* Rx interrupt, but nothing sent from uCode */ |
3726 | if (i == r) | 3102 | if (i == r) |
3727 | IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); | 3103 | IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i); |
3728 | 3104 | ||
3729 | if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 3105 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) |
3730 | fill_rx = 1; | 3106 | fill_rx = 1; |
3731 | 3107 | ||
3732 | while (i != r) { | 3108 | while (i != r) { |
@@ -3742,7 +3118,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3742 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 3118 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, |
3743 | priv->hw_params.rx_buf_size, | 3119 | priv->hw_params.rx_buf_size, |
3744 | PCI_DMA_FROMDEVICE); | 3120 | PCI_DMA_FROMDEVICE); |
3745 | pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 3121 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3746 | 3122 | ||
3747 | /* Reclaim a command buffer only if this packet is a response | 3123 | /* Reclaim a command buffer only if this packet is a response |
3748 | * to a (driver-originated) command. | 3124 | * to a (driver-originated) command. |
@@ -3761,13 +3137,12 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3761 | * handle those that need handling via function in | 3137 | * handle those that need handling via function in |
3762 | * rx_handlers table. See iwl4965_setup_rx_handlers() */ | 3138 | * rx_handlers table. See iwl4965_setup_rx_handlers() */ |
3763 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 3139 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
3764 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 3140 | IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r, |
3765 | "r = %d, i = %d, %s, 0x%02x\n", r, i, | 3141 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
3766 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
3767 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 3142 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
3768 | } else { | 3143 | } else { |
3769 | /* No handling needed */ | 3144 | /* No handling needed */ |
3770 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 3145 | IWL_DEBUG(IWL_DL_RX, |
3771 | "r %d i %d No handler needed for %s, 0x%02x\n", | 3146 | "r %d i %d No handler needed for %s, 0x%02x\n", |
3772 | r, i, get_cmd_string(pkt->hdr.cmd), | 3147 | r, i, get_cmd_string(pkt->hdr.cmd), |
3773 | pkt->hdr.cmd); | 3148 | pkt->hdr.cmd); |
@@ -3805,7 +3180,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3805 | count++; | 3180 | count++; |
3806 | if (count >= 8) { | 3181 | if (count >= 8) { |
3807 | priv->rxq.read = i; | 3182 | priv->rxq.read = i; |
3808 | __iwl4965_rx_replenish(priv); | 3183 | __iwl_rx_replenish(priv); |
3809 | count = 0; | 3184 | count = 0; |
3810 | } | 3185 | } |
3811 | } | 3186 | } |
@@ -3813,14 +3188,91 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3813 | 3188 | ||
3814 | /* Backtrack one entry */ | 3189 | /* Backtrack one entry */ |
3815 | priv->rxq.read = i; | 3190 | priv->rxq.read = i; |
3816 | iwl4965_rx_queue_restock(priv); | 3191 | iwl_rx_queue_restock(priv); |
3192 | } | ||
3193 | /* Convert linear signal-to-noise ratio into dB */ | ||
3194 | static u8 ratio2dB[100] = { | ||
3195 | /* 0 1 2 3 4 5 6 7 8 9 */ | ||
3196 | 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ | ||
3197 | 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ | ||
3198 | 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ | ||
3199 | 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ | ||
3200 | 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ | ||
3201 | 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ | ||
3202 | 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ | ||
3203 | 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ | ||
3204 | 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ | ||
3205 | 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ | ||
3206 | }; | ||
3207 | |||
3208 | /* Calculates a relative dB value from a ratio of linear | ||
3209 | * (i.e. not dB) signal levels. | ||
3210 | * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ | ||
3211 | int iwl4965_calc_db_from_ratio(int sig_ratio) | ||
3212 | { | ||
3213 | /* 1000:1 or higher just report as 60 dB */ | ||
3214 | if (sig_ratio >= 1000) | ||
3215 | return 60; | ||
3216 | |||
3217 | /* 100:1 or higher, divide by 10 and use table, | ||
3218 | * add 20 dB to make up for divide by 10 */ | ||
3219 | if (sig_ratio >= 100) | ||
3220 | return (20 + (int)ratio2dB[sig_ratio/10]); | ||
3221 | |||
3222 | /* We shouldn't see this */ | ||
3223 | if (sig_ratio < 1) | ||
3224 | return 0; | ||
3225 | |||
3226 | /* Use table for ratios 1:1 - 99:1 */ | ||
3227 | return (int)ratio2dB[sig_ratio]; | ||
3228 | } | ||
3229 | |||
3230 | #define PERFECT_RSSI (-20) /* dBm */ | ||
3231 | #define WORST_RSSI (-95) /* dBm */ | ||
3232 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
3233 | |||
3234 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
3235 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
3236 | * about formulas used below. */ | ||
3237 | int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
3238 | { | ||
3239 | int sig_qual; | ||
3240 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
3241 | |||
3242 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
3243 | * as indicator; formula is (signal dbm - noise dbm). | ||
3244 | * SNR at or above 40 is a great signal (100%). | ||
3245 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
3246 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
3247 | if (noise_dbm) { | ||
3248 | if (rssi_dbm - noise_dbm >= 40) | ||
3249 | return 100; | ||
3250 | else if (rssi_dbm < noise_dbm) | ||
3251 | return 0; | ||
3252 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
3253 | |||
3254 | /* Else use just the signal level. | ||
3255 | * This formula is a least squares fit of data points collected and | ||
3256 | * compared with a reference system that had a percentage (%) display | ||
3257 | * for signal quality. */ | ||
3258 | } else | ||
3259 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
3260 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
3261 | (RSSI_RANGE * RSSI_RANGE); | ||
3262 | |||
3263 | if (sig_qual > 100) | ||
3264 | sig_qual = 100; | ||
3265 | else if (sig_qual < 1) | ||
3266 | sig_qual = 0; | ||
3267 | |||
3268 | return sig_qual; | ||
3817 | } | 3269 | } |
3818 | 3270 | ||
3819 | /** | 3271 | /** |
3820 | * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware | 3272 | * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware |
3821 | */ | 3273 | */ |
3822 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | 3274 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, |
3823 | struct iwl4965_tx_queue *txq) | 3275 | struct iwl_tx_queue *txq) |
3824 | { | 3276 | { |
3825 | u32 reg = 0; | 3277 | u32 reg = 0; |
3826 | int rc = 0; | 3278 | int rc = 0; |
@@ -3863,12 +3315,13 @@ static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | |||
3863 | } | 3315 | } |
3864 | 3316 | ||
3865 | #ifdef CONFIG_IWLWIFI_DEBUG | 3317 | #ifdef CONFIG_IWLWIFI_DEBUG |
3866 | static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon) | 3318 | static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) |
3867 | { | 3319 | { |
3320 | struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; | ||
3868 | DECLARE_MAC_BUF(mac); | 3321 | DECLARE_MAC_BUF(mac); |
3869 | 3322 | ||
3870 | IWL_DEBUG_RADIO("RX CONFIG:\n"); | 3323 | IWL_DEBUG_RADIO("RX CONFIG:\n"); |
3871 | iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); | 3324 | iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); |
3872 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); | 3325 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); |
3873 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); | 3326 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); |
3874 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", | 3327 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", |
@@ -4094,10 +3547,10 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4094 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 3547 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
4095 | 3548 | ||
4096 | #ifdef CONFIG_IWLWIFI_DEBUG | 3549 | #ifdef CONFIG_IWLWIFI_DEBUG |
4097 | if (iwl_debug_level & IWL_DL_FW_ERRORS) { | 3550 | if (priv->debug_level & IWL_DL_FW_ERRORS) { |
4098 | iwl4965_dump_nic_error_log(priv); | 3551 | iwl4965_dump_nic_error_log(priv); |
4099 | iwl4965_dump_nic_event_log(priv); | 3552 | iwl4965_dump_nic_event_log(priv); |
4100 | iwl4965_print_rx_config_cmd(&priv->staging_rxon); | 3553 | iwl4965_print_rx_config_cmd(priv); |
4101 | } | 3554 | } |
4102 | #endif | 3555 | #endif |
4103 | 3556 | ||
@@ -4108,7 +3561,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4108 | clear_bit(STATUS_READY, &priv->status); | 3561 | clear_bit(STATUS_READY, &priv->status); |
4109 | 3562 | ||
4110 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 3563 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
4111 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS, | 3564 | IWL_DEBUG(IWL_DL_FW_ERRORS, |
4112 | "Restarting adapter due to uCode error.\n"); | 3565 | "Restarting adapter due to uCode error.\n"); |
4113 | 3566 | ||
4114 | if (iwl_is_associated(priv)) { | 3567 | if (iwl_is_associated(priv)) { |
@@ -4116,7 +3569,8 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4116 | sizeof(priv->recovery_rxon)); | 3569 | sizeof(priv->recovery_rxon)); |
4117 | priv->error_recovering = 1; | 3570 | priv->error_recovering = 1; |
4118 | } | 3571 | } |
4119 | queue_work(priv->workqueue, &priv->restart); | 3572 | if (priv->cfg->mod_params->restart_fw) |
3573 | queue_work(priv->workqueue, &priv->restart); | ||
4120 | } | 3574 | } |
4121 | } | 3575 | } |
4122 | 3576 | ||
@@ -4161,7 +3615,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4161 | iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); | 3615 | iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); |
4162 | 3616 | ||
4163 | #ifdef CONFIG_IWLWIFI_DEBUG | 3617 | #ifdef CONFIG_IWLWIFI_DEBUG |
4164 | if (iwl_debug_level & IWL_DL_ISR) { | 3618 | if (priv->debug_level & IWL_DL_ISR) { |
4165 | /* just for debug */ | 3619 | /* just for debug */ |
4166 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | 3620 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4167 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", | 3621 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", |
@@ -4195,7 +3649,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4195 | } | 3649 | } |
4196 | 3650 | ||
4197 | #ifdef CONFIG_IWLWIFI_DEBUG | 3651 | #ifdef CONFIG_IWLWIFI_DEBUG |
4198 | if (iwl_debug_level & (IWL_DL_ISR)) { | 3652 | if (priv->debug_level & (IWL_DL_ISR)) { |
4199 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 3653 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
4200 | if (inta & CSR_INT_BIT_SCD) | 3654 | if (inta & CSR_INT_BIT_SCD) |
4201 | IWL_DEBUG_ISR("Scheduler finished to transmit " | 3655 | IWL_DEBUG_ISR("Scheduler finished to transmit " |
@@ -4216,8 +3670,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4216 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 3670 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) |
4217 | hw_rf_kill = 1; | 3671 | hw_rf_kill = 1; |
4218 | 3672 | ||
4219 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR, | 3673 | IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", |
4220 | "RF_KILL bit toggled to %s.\n", | ||
4221 | hw_rf_kill ? "disable radio":"enable radio"); | 3674 | hw_rf_kill ? "disable radio":"enable radio"); |
4222 | 3675 | ||
4223 | /* Queue restart only if RF_KILL switch was set to "kill" | 3676 | /* Queue restart only if RF_KILL switch was set to "kill" |
@@ -4249,7 +3702,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4249 | /* uCode wakes up after power-down sleep */ | 3702 | /* uCode wakes up after power-down sleep */ |
4250 | if (inta & CSR_INT_BIT_WAKEUP) { | 3703 | if (inta & CSR_INT_BIT_WAKEUP) { |
4251 | IWL_DEBUG_ISR("Wakeup interrupt\n"); | 3704 | IWL_DEBUG_ISR("Wakeup interrupt\n"); |
4252 | iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq); | 3705 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
4253 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]); | 3706 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]); |
4254 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]); | 3707 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]); |
4255 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]); | 3708 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]); |
@@ -4264,7 +3717,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4264 | * Rx "responses" (frame-received notification), and other | 3717 | * Rx "responses" (frame-received notification), and other |
4265 | * notifications from uCode come through here*/ | 3718 | * notifications from uCode come through here*/ |
4266 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 3719 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
4267 | iwl4965_rx_handle(priv); | 3720 | iwl_rx_handle(priv); |
4268 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 3721 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
4269 | } | 3722 | } |
4270 | 3723 | ||
@@ -4288,7 +3741,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4288 | iwl4965_enable_interrupts(priv); | 3741 | iwl4965_enable_interrupts(priv); |
4289 | 3742 | ||
4290 | #ifdef CONFIG_IWLWIFI_DEBUG | 3743 | #ifdef CONFIG_IWLWIFI_DEBUG |
4291 | if (iwl_debug_level & (IWL_DL_ISR)) { | 3744 | if (priv->debug_level & (IWL_DL_ISR)) { |
4292 | inta = iwl_read32(priv, CSR_INT); | 3745 | inta = iwl_read32(priv, CSR_INT); |
4293 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | 3746 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4294 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); | 3747 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); |
@@ -4708,105 +4161,6 @@ static int iwl4965_read_ucode(struct iwl_priv *priv) | |||
4708 | return ret; | 4161 | return ret; |
4709 | } | 4162 | } |
4710 | 4163 | ||
4711 | |||
4712 | /** | ||
4713 | * iwl4965_set_ucode_ptrs - Set uCode address location | ||
4714 | * | ||
4715 | * Tell initialization uCode where to find runtime uCode. | ||
4716 | * | ||
4717 | * BSM registers initially contain pointers to initialization uCode. | ||
4718 | * We need to replace them to load runtime uCode inst and data, | ||
4719 | * and to save runtime data when powering down. | ||
4720 | */ | ||
4721 | static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) | ||
4722 | { | ||
4723 | dma_addr_t pinst; | ||
4724 | dma_addr_t pdata; | ||
4725 | int rc = 0; | ||
4726 | unsigned long flags; | ||
4727 | |||
4728 | /* bits 35:4 for 4965 */ | ||
4729 | pinst = priv->ucode_code.p_addr >> 4; | ||
4730 | pdata = priv->ucode_data_backup.p_addr >> 4; | ||
4731 | |||
4732 | spin_lock_irqsave(&priv->lock, flags); | ||
4733 | rc = iwl_grab_nic_access(priv); | ||
4734 | if (rc) { | ||
4735 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4736 | return rc; | ||
4737 | } | ||
4738 | |||
4739 | /* Tell bootstrap uCode where to find image to load */ | ||
4740 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
4741 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
4742 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, | ||
4743 | priv->ucode_data.len); | ||
4744 | |||
4745 | /* Inst bytecount must be last to set up, bit 31 signals uCode | ||
4746 | * that all new ptr/size info is in place */ | ||
4747 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | ||
4748 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | ||
4749 | |||
4750 | iwl_release_nic_access(priv); | ||
4751 | |||
4752 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4753 | |||
4754 | IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); | ||
4755 | |||
4756 | return rc; | ||
4757 | } | ||
4758 | |||
4759 | /** | ||
4760 | * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received | ||
4761 | * | ||
4762 | * Called after REPLY_ALIVE notification received from "initialize" uCode. | ||
4763 | * | ||
4764 | * The 4965 "initialize" ALIVE reply contains calibration data for: | ||
4765 | * Voltage, temperature, and MIMO tx gain correction, now stored in priv | ||
4766 | * (3945 does not contain this data). | ||
4767 | * | ||
4768 | * Tell "initialize" uCode to go ahead and load the runtime uCode. | ||
4769 | */ | ||
4770 | static void iwl4965_init_alive_start(struct iwl_priv *priv) | ||
4771 | { | ||
4772 | /* Check alive response for "valid" sign from uCode */ | ||
4773 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
4774 | /* We had an error bringing up the hardware, so take it | ||
4775 | * all the way back down so we can try again */ | ||
4776 | IWL_DEBUG_INFO("Initialize Alive failed.\n"); | ||
4777 | goto restart; | ||
4778 | } | ||
4779 | |||
4780 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | ||
4781 | * This is a paranoid check, because we would not have gotten the | ||
4782 | * "initialize" alive if code weren't properly loaded. */ | ||
4783 | if (iwl_verify_ucode(priv)) { | ||
4784 | /* Runtime instruction load was bad; | ||
4785 | * take it all the way back down so we can try again */ | ||
4786 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); | ||
4787 | goto restart; | ||
4788 | } | ||
4789 | |||
4790 | /* Calculate temperature */ | ||
4791 | priv->temperature = iwl4965_get_temperature(priv); | ||
4792 | |||
4793 | /* Send pointers to protocol/runtime uCode image ... init code will | ||
4794 | * load and launch runtime uCode, which will send us another "Alive" | ||
4795 | * notification. */ | ||
4796 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | ||
4797 | if (iwl4965_set_ucode_ptrs(priv)) { | ||
4798 | /* Runtime instruction load won't happen; | ||
4799 | * take it all the way back down so we can try again */ | ||
4800 | IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); | ||
4801 | goto restart; | ||
4802 | } | ||
4803 | return; | ||
4804 | |||
4805 | restart: | ||
4806 | queue_work(priv->workqueue, &priv->restart); | ||
4807 | } | ||
4808 | |||
4809 | |||
4810 | /** | 4164 | /** |
4811 | * iwl4965_alive_start - called after REPLY_ALIVE notification received | 4165 | * iwl4965_alive_start - called after REPLY_ALIVE notification received |
4812 | * from protocol/runtime uCode (initialization uCode's | 4166 | * from protocol/runtime uCode (initialization uCode's |
@@ -5056,7 +4410,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5056 | return ret; | 4410 | return ret; |
5057 | } | 4411 | } |
5058 | 4412 | ||
5059 | ret = priv->cfg->ops->lib->hw_nic_init(priv); | 4413 | ret = iwl_hw_nic_init(priv); |
5060 | if (ret) { | 4414 | if (ret) { |
5061 | IWL_ERROR("Unable to init nic\n"); | 4415 | IWL_ERROR("Unable to init nic\n"); |
5062 | return ret; | 4416 | return ret; |
@@ -5132,7 +4486,7 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) | |||
5132 | return; | 4486 | return; |
5133 | 4487 | ||
5134 | mutex_lock(&priv->mutex); | 4488 | mutex_lock(&priv->mutex); |
5135 | iwl4965_init_alive_start(priv); | 4489 | priv->cfg->ops->lib->init_alive_start(priv); |
5136 | mutex_unlock(&priv->mutex); | 4490 | mutex_unlock(&priv->mutex); |
5137 | } | 4491 | } |
5138 | 4492 | ||
@@ -5161,7 +4515,7 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
5161 | mutex_lock(&priv->mutex); | 4515 | mutex_lock(&priv->mutex); |
5162 | 4516 | ||
5163 | if (!iwl_is_rfkill(priv)) { | 4517 | if (!iwl_is_rfkill(priv)) { |
5164 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, | 4518 | IWL_DEBUG(IWL_DL_RF_KILL, |
5165 | "HW and/or SW RF Kill no longer active, restarting " | 4519 | "HW and/or SW RF Kill no longer active, restarting " |
5166 | "device\n"); | 4520 | "device\n"); |
5167 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4521 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
@@ -5184,6 +4538,24 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
5184 | mutex_unlock(&priv->mutex); | 4538 | mutex_unlock(&priv->mutex); |
5185 | } | 4539 | } |
5186 | 4540 | ||
4541 | static void iwl4965_bg_set_monitor(struct work_struct *work) | ||
4542 | { | ||
4543 | struct iwl_priv *priv = container_of(work, | ||
4544 | struct iwl_priv, set_monitor); | ||
4545 | |||
4546 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | ||
4547 | |||
4548 | mutex_lock(&priv->mutex); | ||
4549 | |||
4550 | if (!iwl_is_ready(priv)) | ||
4551 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
4552 | else | ||
4553 | if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) | ||
4554 | IWL_ERROR("iwl4965_set_mode() failed\n"); | ||
4555 | |||
4556 | mutex_unlock(&priv->mutex); | ||
4557 | } | ||
4558 | |||
5187 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 4559 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
5188 | 4560 | ||
5189 | static void iwl4965_bg_scan_check(struct work_struct *data) | 4561 | static void iwl4965_bg_scan_check(struct work_struct *data) |
@@ -5197,9 +4569,9 @@ static void iwl4965_bg_scan_check(struct work_struct *data) | |||
5197 | mutex_lock(&priv->mutex); | 4569 | mutex_lock(&priv->mutex); |
5198 | if (test_bit(STATUS_SCANNING, &priv->status) || | 4570 | if (test_bit(STATUS_SCANNING, &priv->status) || |
5199 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | 4571 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
5200 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, | 4572 | IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " |
5201 | "Scan completion watchdog resetting adapter (%dms)\n", | 4573 | "adapter (%dms)\n", |
5202 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | 4574 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); |
5203 | 4575 | ||
5204 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4576 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
5205 | iwl4965_send_scan_abort(priv); | 4577 | iwl4965_send_scan_abort(priv); |
@@ -5453,7 +4825,7 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) | |||
5453 | return; | 4825 | return; |
5454 | 4826 | ||
5455 | mutex_lock(&priv->mutex); | 4827 | mutex_lock(&priv->mutex); |
5456 | iwl4965_rx_replenish(priv); | 4828 | iwl_rx_replenish(priv); |
5457 | mutex_unlock(&priv->mutex); | 4829 | mutex_unlock(&priv->mutex); |
5458 | } | 4830 | } |
5459 | 4831 | ||
@@ -5501,7 +4873,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
5501 | 4873 | ||
5502 | #ifdef CONFIG_IWL4965_HT | 4874 | #ifdef CONFIG_IWL4965_HT |
5503 | if (priv->current_ht_config.is_ht) | 4875 | if (priv->current_ht_config.is_ht) |
5504 | iwl4965_set_rxon_ht(priv, &priv->current_ht_config); | 4876 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
5505 | #endif /* CONFIG_IWL4965_HT*/ | 4877 | #endif /* CONFIG_IWL4965_HT*/ |
5506 | iwl_set_rxon_chain(priv); | 4878 | iwl_set_rxon_chain(priv); |
5507 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 4879 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -5600,7 +4972,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) | |||
5600 | struct iwl_priv *priv = | 4972 | struct iwl_priv *priv = |
5601 | container_of(work, struct iwl_priv, scan_completed); | 4973 | container_of(work, struct iwl_priv, scan_completed); |
5602 | 4974 | ||
5603 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); | 4975 | IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n"); |
5604 | 4976 | ||
5605 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4977 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
5606 | return; | 4978 | return; |
@@ -6073,7 +5445,22 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw, | |||
6073 | * XXX: dummy | 5445 | * XXX: dummy |
6074 | * see also iwl4965_connection_init_rx_config | 5446 | * see also iwl4965_connection_init_rx_config |
6075 | */ | 5447 | */ |
6076 | *total_flags = 0; | 5448 | struct iwl_priv *priv = hw->priv; |
5449 | int new_flags = 0; | ||
5450 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | ||
5451 | if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | ||
5452 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | ||
5453 | IEEE80211_IF_TYPE_MNTR, | ||
5454 | changed_flags, *total_flags); | ||
5455 | /* queue work 'cuz mac80211 is holding a lock which | ||
5456 | * prevents us from issuing (synchronous) f/w cmds */ | ||
5457 | queue_work(priv->workqueue, &priv->set_monitor); | ||
5458 | new_flags &= FIF_PROMISC_IN_BSS | | ||
5459 | FIF_OTHER_BSS | | ||
5460 | FIF_ALLMULTI; | ||
5461 | } | ||
5462 | } | ||
5463 | *total_flags = new_flags; | ||
6077 | } | 5464 | } |
6078 | 5465 | ||
6079 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | 5466 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -6261,7 +5648,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
6261 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 5648 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
6262 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 5649 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
6263 | 5650 | ||
6264 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 5651 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
6265 | 5652 | ||
6266 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 5653 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
6267 | 5654 | ||
@@ -6395,7 +5782,7 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
6395 | { | 5782 | { |
6396 | struct iwl_priv *priv = hw->priv; | 5783 | struct iwl_priv *priv = hw->priv; |
6397 | int i, avail; | 5784 | int i, avail; |
6398 | struct iwl4965_tx_queue *txq; | 5785 | struct iwl_tx_queue *txq; |
6399 | struct iwl4965_queue *q; | 5786 | struct iwl4965_queue *q; |
6400 | unsigned long flags; | 5787 | unsigned long flags; |
6401 | 5788 | ||
@@ -6428,6 +5815,9 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
6428 | static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, | 5815 | static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, |
6429 | struct ieee80211_low_level_stats *stats) | 5816 | struct ieee80211_low_level_stats *stats) |
6430 | { | 5817 | { |
5818 | struct iwl_priv *priv = hw->priv; | ||
5819 | |||
5820 | priv = hw->priv; | ||
6431 | IWL_DEBUG_MAC80211("enter\n"); | 5821 | IWL_DEBUG_MAC80211("enter\n"); |
6432 | IWL_DEBUG_MAC80211("leave\n"); | 5822 | IWL_DEBUG_MAC80211("leave\n"); |
6433 | 5823 | ||
@@ -6436,6 +5826,9 @@ static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, | |||
6436 | 5826 | ||
6437 | static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) | 5827 | static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) |
6438 | { | 5828 | { |
5829 | struct iwl_priv *priv; | ||
5830 | |||
5831 | priv = hw->priv; | ||
6439 | IWL_DEBUG_MAC80211("enter\n"); | 5832 | IWL_DEBUG_MAC80211("enter\n"); |
6440 | IWL_DEBUG_MAC80211("leave\n"); | 5833 | IWL_DEBUG_MAC80211("leave\n"); |
6441 | 5834 | ||
@@ -6569,13 +5962,18 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
6569 | * See the level definitions in iwl for details. | 5962 | * See the level definitions in iwl for details. |
6570 | */ | 5963 | */ |
6571 | 5964 | ||
6572 | static ssize_t show_debug_level(struct device_driver *d, char *buf) | 5965 | static ssize_t show_debug_level(struct device *d, |
5966 | struct device_attribute *attr, char *buf) | ||
6573 | { | 5967 | { |
6574 | return sprintf(buf, "0x%08X\n", iwl_debug_level); | 5968 | struct iwl_priv *priv = d->driver_data; |
5969 | |||
5970 | return sprintf(buf, "0x%08X\n", priv->debug_level); | ||
6575 | } | 5971 | } |
6576 | static ssize_t store_debug_level(struct device_driver *d, | 5972 | static ssize_t store_debug_level(struct device *d, |
5973 | struct device_attribute *attr, | ||
6577 | const char *buf, size_t count) | 5974 | const char *buf, size_t count) |
6578 | { | 5975 | { |
5976 | struct iwl_priv *priv = d->driver_data; | ||
6579 | char *p = (char *)buf; | 5977 | char *p = (char *)buf; |
6580 | u32 val; | 5978 | u32 val; |
6581 | 5979 | ||
@@ -6584,17 +5982,37 @@ static ssize_t store_debug_level(struct device_driver *d, | |||
6584 | printk(KERN_INFO DRV_NAME | 5982 | printk(KERN_INFO DRV_NAME |
6585 | ": %s is not in hex or decimal form.\n", buf); | 5983 | ": %s is not in hex or decimal form.\n", buf); |
6586 | else | 5984 | else |
6587 | iwl_debug_level = val; | 5985 | priv->debug_level = val; |
6588 | 5986 | ||
6589 | return strnlen(buf, count); | 5987 | return strnlen(buf, count); |
6590 | } | 5988 | } |
6591 | 5989 | ||
6592 | static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | 5990 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, |
6593 | show_debug_level, store_debug_level); | 5991 | show_debug_level, store_debug_level); |
5992 | |||
6594 | 5993 | ||
6595 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 5994 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
6596 | 5995 | ||
6597 | 5996 | ||
5997 | static ssize_t show_version(struct device *d, | ||
5998 | struct device_attribute *attr, char *buf) | ||
5999 | { | ||
6000 | struct iwl_priv *priv = d->driver_data; | ||
6001 | struct iwl4965_alive_resp *palive = &priv->card_alive; | ||
6002 | |||
6003 | if (palive->is_valid) | ||
6004 | return sprintf(buf, "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n" | ||
6005 | "fw type: 0x%01X 0x%01X\n", | ||
6006 | palive->ucode_major, palive->ucode_minor, | ||
6007 | palive->sw_rev[0], palive->sw_rev[1], | ||
6008 | palive->ver_type, palive->ver_subtype); | ||
6009 | |||
6010 | else | ||
6011 | return sprintf(buf, "fw not loaded\n"); | ||
6012 | } | ||
6013 | |||
6014 | static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); | ||
6015 | |||
6598 | static ssize_t show_temperature(struct device *d, | 6016 | static ssize_t show_temperature(struct device *d, |
6599 | struct device_attribute *attr, char *buf) | 6017 | struct device_attribute *attr, char *buf) |
6600 | { | 6018 | { |
@@ -6998,6 +6416,7 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | |||
6998 | INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); | 6416 | INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); |
6999 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); | 6417 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); |
7000 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); | 6418 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); |
6419 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); | ||
7001 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); | 6420 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); |
7002 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); | 6421 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); |
7003 | INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); | 6422 | INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); |
@@ -7036,6 +6455,10 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
7036 | &dev_attr_status.attr, | 6455 | &dev_attr_status.attr, |
7037 | &dev_attr_temperature.attr, | 6456 | &dev_attr_temperature.attr, |
7038 | &dev_attr_tx_power.attr, | 6457 | &dev_attr_tx_power.attr, |
6458 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
6459 | &dev_attr_debug_level.attr, | ||
6460 | #endif | ||
6461 | &dev_attr_version.attr, | ||
7039 | 6462 | ||
7040 | NULL | 6463 | NULL |
7041 | }; | 6464 | }; |
@@ -7085,7 +6508,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7085 | /* Disabling hardware scan means that mac80211 will perform scans | 6508 | /* Disabling hardware scan means that mac80211 will perform scans |
7086 | * "the hard way", rather than using device's scan. */ | 6509 | * "the hard way", rather than using device's scan. */ |
7087 | if (cfg->mod_params->disable_hw_scan) { | 6510 | if (cfg->mod_params->disable_hw_scan) { |
7088 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | 6511 | if (cfg->mod_params->debug & IWL_DL_INFO) |
6512 | dev_printk(KERN_DEBUG, &(pdev->dev), | ||
6513 | "Disabling hw_scan\n"); | ||
7089 | iwl4965_hw_ops.hw_scan = NULL; | 6514 | iwl4965_hw_ops.hw_scan = NULL; |
7090 | } | 6515 | } |
7091 | 6516 | ||
@@ -7104,7 +6529,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7104 | priv->pci_dev = pdev; | 6529 | priv->pci_dev = pdev; |
7105 | 6530 | ||
7106 | #ifdef CONFIG_IWLWIFI_DEBUG | 6531 | #ifdef CONFIG_IWLWIFI_DEBUG |
7107 | iwl_debug_level = priv->cfg->mod_params->debug; | 6532 | priv->debug_level = priv->cfg->mod_params->debug; |
7108 | atomic_set(&priv->restrict_refcnt, 0); | 6533 | atomic_set(&priv->restrict_refcnt, 0); |
7109 | #endif | 6534 | #endif |
7110 | 6535 | ||
@@ -7310,8 +6735,8 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
7310 | iwl4965_dealloc_ucode_pci(priv); | 6735 | iwl4965_dealloc_ucode_pci(priv); |
7311 | 6736 | ||
7312 | if (priv->rxq.bd) | 6737 | if (priv->rxq.bd) |
7313 | iwl4965_rx_queue_free(priv, &priv->rxq); | 6738 | iwl_rx_queue_free(priv, &priv->rxq); |
7314 | iwl4965_hw_txq_ctx_free(priv); | 6739 | iwl_hw_txq_ctx_free(priv); |
7315 | 6740 | ||
7316 | iwlcore_clear_stations_table(priv); | 6741 | iwlcore_clear_stations_table(priv); |
7317 | iwl_eeprom_free(priv); | 6742 | iwl_eeprom_free(priv); |
@@ -7420,18 +6845,11 @@ static int __init iwl4965_init(void) | |||
7420 | IWL_ERROR("Unable to initialize PCI module\n"); | 6845 | IWL_ERROR("Unable to initialize PCI module\n"); |
7421 | goto error_register; | 6846 | goto error_register; |
7422 | } | 6847 | } |
7423 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
7424 | ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); | ||
7425 | if (ret) { | ||
7426 | IWL_ERROR("Unable to create driver sysfs file\n"); | ||
7427 | goto error_debug; | ||
7428 | } | ||
7429 | #endif | ||
7430 | 6848 | ||
7431 | return ret; | 6849 | return ret; |
7432 | 6850 | ||
6851 | |||
7433 | #ifdef CONFIG_IWLWIFI_DEBUG | 6852 | #ifdef CONFIG_IWLWIFI_DEBUG |
7434 | error_debug: | ||
7435 | pci_unregister_driver(&iwl_driver); | 6853 | pci_unregister_driver(&iwl_driver); |
7436 | #endif | 6854 | #endif |
7437 | error_register: | 6855 | error_register: |
@@ -7441,9 +6859,6 @@ error_register: | |||
7441 | 6859 | ||
7442 | static void __exit iwl4965_exit(void) | 6860 | static void __exit iwl4965_exit(void) |
7443 | { | 6861 | { |
7444 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
7445 | driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); | ||
7446 | #endif | ||
7447 | pci_unregister_driver(&iwl_driver); | 6862 | pci_unregister_driver(&iwl_driver); |
7448 | iwl4965_rate_control_unregister(); | 6863 | iwl4965_rate_control_unregister(); |
7449 | } | 6864 | } |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 6328b9593877..c2dd43ece069 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -697,38 +697,6 @@ static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | |||
697 | } | 697 | } |
698 | 698 | ||
699 | /** | 699 | /** |
700 | * @brief Get the current data rate | ||
701 | * | ||
702 | * @param priv A pointer to struct lbs_private structure | ||
703 | * | ||
704 | * @return The data rate on success, error on failure | ||
705 | */ | ||
706 | int lbs_get_data_rate(struct lbs_private *priv) | ||
707 | { | ||
708 | struct cmd_ds_802_11_data_rate cmd; | ||
709 | int ret = -1; | ||
710 | |||
711 | lbs_deb_enter(LBS_DEB_CMD); | ||
712 | |||
713 | memset(&cmd, 0, sizeof(cmd)); | ||
714 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
715 | cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE); | ||
716 | |||
717 | ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); | ||
718 | if (ret) | ||
719 | goto out; | ||
720 | |||
721 | lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd)); | ||
722 | |||
723 | ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]); | ||
724 | lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret); | ||
725 | |||
726 | out: | ||
727 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | /** | ||
732 | * @brief Set the data rate | 700 | * @brief Set the data rate |
733 | * | 701 | * |
734 | * @param priv A pointer to struct lbs_private structure | 702 | * @param priv A pointer to struct lbs_private structure |
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index 4295bc613669..f4019c22adfc 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h | |||
@@ -34,7 +34,6 @@ int lbs_update_hw_spec(struct lbs_private *priv); | |||
34 | int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, | 34 | int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, |
35 | struct cmd_ds_mesh_access *cmd); | 35 | struct cmd_ds_mesh_access *cmd); |
36 | 36 | ||
37 | int lbs_get_data_rate(struct lbs_private *priv); | ||
38 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate); | 37 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate); |
39 | 38 | ||
40 | int lbs_get_channel(struct lbs_private *priv); | 39 | int lbs_get_channel(struct lbs_private *priv); |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 0be89573716c..e333f14dce23 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -927,20 +927,10 @@ static int lbs_setup_firmware(struct lbs_private *priv) | |||
927 | */ | 927 | */ |
928 | memset(priv->current_addr, 0xff, ETH_ALEN); | 928 | memset(priv->current_addr, 0xff, ETH_ALEN); |
929 | ret = lbs_update_hw_spec(priv); | 929 | ret = lbs_update_hw_spec(priv); |
930 | if (ret) { | 930 | if (ret) |
931 | ret = -1; | ||
932 | goto done; | 931 | goto done; |
933 | } | ||
934 | 932 | ||
935 | lbs_set_mac_control(priv); | 933 | lbs_set_mac_control(priv); |
936 | |||
937 | ret = lbs_get_data_rate(priv); | ||
938 | if (ret < 0) { | ||
939 | ret = -1; | ||
940 | goto done; | ||
941 | } | ||
942 | |||
943 | ret = 0; | ||
944 | done: | 934 | done: |
945 | lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); | 935 | lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); |
946 | return ret; | 936 | return ret; |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 33d608a60d79..9cbef5bce0f6 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -355,7 +355,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
355 | struct ieee80211_rx_status rx_status = {0}; | 355 | struct ieee80211_rx_status rx_status = {0}; |
356 | u16 freq = le16_to_cpu(hdr->freq); | 356 | u16 freq = le16_to_cpu(hdr->freq); |
357 | 357 | ||
358 | rx_status.ssi = hdr->rssi; | 358 | rx_status.signal = hdr->rssi; |
359 | /* XX correct? */ | 359 | /* XX correct? */ |
360 | rx_status.rate_idx = hdr->rate & 0xf; | 360 | rx_status.rate_idx = hdr->rate & 0xf; |
361 | rx_status.freq = freq; | 361 | rx_status.freq = freq; |
@@ -1000,9 +1000,10 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
1000 | skb_queue_head_init(&priv->tx_queue); | 1000 | skb_queue_head_init(&priv->tx_queue); |
1001 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; | 1001 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; |
1002 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ | 1002 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ |
1003 | IEEE80211_HW_RX_INCLUDES_FCS; | 1003 | IEEE80211_HW_RX_INCLUDES_FCS | |
1004 | IEEE80211_HW_SIGNAL_UNSPEC; | ||
1004 | dev->channel_change_time = 1000; /* TODO: find actual value */ | 1005 | dev->channel_change_time = 1000; /* TODO: find actual value */ |
1005 | dev->max_rssi = 127; | 1006 | dev->max_signal = 127; |
1006 | 1007 | ||
1007 | priv->tx_stats[0].limit = 5; | 1008 | priv->tx_stats[0].limit = 5; |
1008 | dev->queues = 1; | 1009 | dev->queues = 1; |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 247fbbfb0f2b..afa565c63621 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1361,10 +1361,9 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1361 | /* | 1361 | /* |
1362 | * Initialize all hw fields. | 1362 | * Initialize all hw fields. |
1363 | */ | 1363 | */ |
1364 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 1364 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1365 | IEEE80211_HW_SIGNAL_DBM; | ||
1365 | rt2x00dev->hw->extra_tx_headroom = 0; | 1366 | rt2x00dev->hw->extra_tx_headroom = 0; |
1366 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
1367 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
1368 | rt2x00dev->hw->queues = 2; | 1367 | rt2x00dev->hw->queues = 2; |
1369 | 1368 | ||
1370 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 1369 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 0d53c75d55dd..c06f1b5e5887 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1680,10 +1680,10 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1680 | /* | 1680 | /* |
1681 | * Initialize all hw fields. | 1681 | * Initialize all hw fields. |
1682 | */ | 1682 | */ |
1683 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 1683 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1684 | IEEE80211_HW_SIGNAL_DBM; | ||
1685 | |||
1684 | rt2x00dev->hw->extra_tx_headroom = 0; | 1686 | rt2x00dev->hw->extra_tx_headroom = 0; |
1685 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
1686 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
1687 | rt2x00dev->hw->queues = 2; | 1687 | rt2x00dev->hw->queues = 2; |
1688 | 1688 | ||
1689 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 1689 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 80b34d47114a..88bafdf8f0fa 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1587,10 +1587,10 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1587 | rt2x00dev->hw->flags = | 1587 | rt2x00dev->hw->flags = |
1588 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 1588 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
1589 | IEEE80211_HW_RX_INCLUDES_FCS | | 1589 | IEEE80211_HW_RX_INCLUDES_FCS | |
1590 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 1590 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1591 | IEEE80211_HW_SIGNAL_DBM; | ||
1592 | |||
1591 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1593 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1592 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
1593 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
1594 | rt2x00dev->hw->queues = 2; | 1594 | rt2x00dev->hw->queues = 2; |
1595 | 1595 | ||
1596 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1596 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 61510c519351..3a49c256789f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -600,9 +600,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
600 | rt2x00dev->link.qual.rx_success++; | 600 | rt2x00dev->link.qual.rx_success++; |
601 | 601 | ||
602 | rx_status->rate_idx = idx; | 602 | rx_status->rate_idx = idx; |
603 | rx_status->signal = | 603 | rx_status->qual = |
604 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); | 604 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
605 | rx_status->ssi = rxdesc->rssi; | 605 | rx_status->signal = rxdesc->rssi; |
606 | rx_status->flag = rxdesc->flags; | 606 | rx_status->flag = rxdesc->flags; |
607 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 607 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
608 | 608 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b64f2f5d0d53..edddbf35bbab 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2245,10 +2245,9 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2245 | */ | 2245 | */ |
2246 | rt2x00dev->hw->flags = | 2246 | rt2x00dev->hw->flags = |
2247 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 2247 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
2248 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 2248 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2249 | IEEE80211_HW_SIGNAL_DBM; | ||
2249 | rt2x00dev->hw->extra_tx_headroom = 0; | 2250 | rt2x00dev->hw->extra_tx_headroom = 0; |
2250 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
2251 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
2252 | rt2x00dev->hw->queues = 4; | 2251 | rt2x00dev->hw->queues = 4; |
2253 | 2252 | ||
2254 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2253 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 351d95c4f50d..51c5575ed02f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1830,10 +1830,9 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1830 | */ | 1830 | */ |
1831 | rt2x00dev->hw->flags = | 1831 | rt2x00dev->hw->flags = |
1832 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 1832 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
1833 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 1833 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1834 | IEEE80211_HW_SIGNAL_DBM; | ||
1834 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1835 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1835 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
1836 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
1837 | rt2x00dev->hw->queues = 4; | 1836 | rt2x00dev->hw->queues = 4; |
1838 | 1837 | ||
1839 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1838 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index c181f23e930d..c220998cee65 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -132,8 +132,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
132 | 132 | ||
133 | rx_status.antenna = (flags2 >> 15) & 1; | 133 | rx_status.antenna = (flags2 >> 15) & 1; |
134 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
135 | rx_status.signal = flags2 & 0xFF; | 135 | rx_status.qual = flags2 & 0xFF; |
136 | rx_status.ssi = (flags2 >> 8) & 0x7F; | 136 | rx_status.signal = (flags2 >> 8) & 0x7F; |
137 | /* XXX: is this correct? */ | 137 | /* XXX: is this correct? */ |
138 | rx_status.rate_idx = (flags >> 20) & 0xF; | 138 | rx_status.rate_idx = (flags >> 20) & 0xF; |
139 | rx_status.freq = dev->conf.channel->center_freq; | 139 | rx_status.freq = dev->conf.channel->center_freq; |
@@ -894,9 +894,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
894 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; | 894 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
895 | 895 | ||
896 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 896 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
897 | IEEE80211_HW_RX_INCLUDES_FCS; | 897 | IEEE80211_HW_RX_INCLUDES_FCS | |
898 | IEEE80211_HW_SIGNAL_UNSPEC; | ||
898 | dev->queues = 1; | 899 | dev->queues = 1; |
899 | dev->max_rssi = 65; | 900 | dev->max_signal = 65; |
900 | 901 | ||
901 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); | 902 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); |
902 | reg &= RTL818X_TX_CONF_HWVER_MASK; | 903 | reg &= RTL818X_TX_CONF_HWVER_MASK; |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index d5787b37e1fb..e14c84248686 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -261,8 +261,8 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | rx_status.antenna = (hdr->signal >> 7) & 1; | 263 | rx_status.antenna = (hdr->signal >> 7) & 1; |
264 | rx_status.signal = 64 - min(hdr->noise, (u8)64); | 264 | rx_status.qual = 64 - min(hdr->noise, (u8)64); |
265 | rx_status.ssi = signal; | 265 | rx_status.signal = signal; |
266 | rx_status.rate_idx = rate; | 266 | rx_status.rate_idx = rate; |
267 | rx_status.freq = dev->conf.channel->center_freq; | 267 | rx_status.freq = dev->conf.channel->center_freq; |
268 | rx_status.band = dev->conf.channel->band; | 268 | rx_status.band = dev->conf.channel->band; |
@@ -740,11 +740,11 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
740 | 740 | ||
741 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 741 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
742 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 742 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
743 | IEEE80211_HW_RX_INCLUDES_FCS; | 743 | IEEE80211_HW_RX_INCLUDES_FCS | |
744 | IEEE80211_HW_SIGNAL_UNSPEC; | ||
744 | dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); | 745 | dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); |
745 | dev->queues = 1; | 746 | dev->queues = 1; |
746 | dev->max_rssi = 65; | 747 | dev->max_signal = 65; |
747 | dev->max_signal = 64; | ||
748 | 748 | ||
749 | eeprom.data = dev; | 749 | eeprom.data = dev; |
750 | eeprom.register_read = rtl8187_eeprom_register_read; | 750 | eeprom.register_read = rtl8187_eeprom_register_read; |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 69c45ca99051..0c736735e217 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -638,7 +638,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
638 | 638 | ||
639 | memset(&status, 0, sizeof(status)); | 639 | memset(&status, 0, sizeof(status)); |
640 | status.flags = IEEE80211_TX_STATUS_ACK; | 640 | status.flags = IEEE80211_TX_STATUS_ACK; |
641 | status.ack_signal = stats->ssi; | 641 | status.ack_signal = stats->signal; |
642 | __skb_unlink(skb, q); | 642 | __skb_unlink(skb, q); |
643 | tx_status(hw, skb, &status, 1); | 643 | tx_status(hw, skb, &status, 1); |
644 | goto out; | 644 | goto out; |
@@ -691,8 +691,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
691 | 691 | ||
692 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; | 692 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
693 | stats.band = IEEE80211_BAND_2GHZ; | 693 | stats.band = IEEE80211_BAND_2GHZ; |
694 | stats.ssi = status->signal_strength; | 694 | stats.signal = status->signal_strength; |
695 | stats.signal = zd_rx_qual_percent(buffer, | 695 | stats.qual = zd_rx_qual_percent(buffer, |
696 | length - sizeof(struct rx_status), | 696 | length - sizeof(struct rx_status), |
697 | status); | 697 | status); |
698 | 698 | ||
@@ -751,6 +751,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw, | |||
751 | case IEEE80211_IF_TYPE_MNTR: | 751 | case IEEE80211_IF_TYPE_MNTR: |
752 | case IEEE80211_IF_TYPE_MESH_POINT: | 752 | case IEEE80211_IF_TYPE_MESH_POINT: |
753 | case IEEE80211_IF_TYPE_STA: | 753 | case IEEE80211_IF_TYPE_STA: |
754 | case IEEE80211_IF_TYPE_IBSS: | ||
754 | mac->type = conf->type; | 755 | mac->type = conf->type; |
755 | break; | 756 | break; |
756 | default: | 757 | default: |
@@ -781,7 +782,8 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, | |||
781 | struct zd_mac *mac = zd_hw_mac(hw); | 782 | struct zd_mac *mac = zd_hw_mac(hw); |
782 | int associated; | 783 | int associated; |
783 | 784 | ||
784 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) { | 785 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || |
786 | mac->type == IEEE80211_IF_TYPE_IBSS) { | ||
785 | associated = true; | 787 | associated = true; |
786 | if (conf->beacon) { | 788 | if (conf->beacon) { |
787 | zd_mac_config_beacon(hw, conf->beacon); | 789 | zd_mac_config_beacon(hw, conf->beacon); |
@@ -941,6 +943,18 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
941 | } | 943 | } |
942 | } | 944 | } |
943 | 945 | ||
946 | static int zd_op_beacon_update(struct ieee80211_hw *hw, | ||
947 | struct sk_buff *skb, | ||
948 | struct ieee80211_tx_control *ctl) | ||
949 | { | ||
950 | struct zd_mac *mac = zd_hw_mac(hw); | ||
951 | zd_mac_config_beacon(hw, skb); | ||
952 | kfree_skb(skb); | ||
953 | zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | | ||
954 | hw->conf.beacon_int); | ||
955 | return 0; | ||
956 | } | ||
957 | |||
944 | static const struct ieee80211_ops zd_ops = { | 958 | static const struct ieee80211_ops zd_ops = { |
945 | .tx = zd_op_tx, | 959 | .tx = zd_op_tx, |
946 | .start = zd_op_start, | 960 | .start = zd_op_start, |
@@ -951,6 +965,7 @@ static const struct ieee80211_ops zd_ops = { | |||
951 | .config_interface = zd_op_config_interface, | 965 | .config_interface = zd_op_config_interface, |
952 | .configure_filter = zd_op_configure_filter, | 966 | .configure_filter = zd_op_configure_filter, |
953 | .bss_info_changed = zd_op_bss_info_changed, | 967 | .bss_info_changed = zd_op_bss_info_changed, |
968 | .beacon_update = zd_op_beacon_update, | ||
954 | }; | 969 | }; |
955 | 970 | ||
956 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | 971 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) |
@@ -982,10 +997,10 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
982 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; | 997 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; |
983 | 998 | ||
984 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 999 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
985 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | 1000 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
986 | hw->max_rssi = 100; | 1001 | IEEE80211_HW_SIGNAL_DB; |
987 | hw->max_signal = 100; | ||
988 | 1002 | ||
1003 | hw->max_signal = 100; | ||
989 | hw->queues = 1; | 1004 | hw->queues = 1; |
990 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); | 1005 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); |
991 | 1006 | ||
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 0b5e03eae6d2..a9102bc78b61 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -552,16 +552,17 @@ enum ieee80211_back_parties { | |||
552 | */ | 552 | */ |
553 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) | 553 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) |
554 | { | 554 | { |
555 | u8 *raw = (u8 *) hdr; | 555 | __le16 fc = hdr->frame_control; |
556 | u8 tofrom = (*(raw+1)) & 3; /* get the TODS and FROMDS bits */ | 556 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); |
557 | 557 | ||
558 | switch (tofrom) { | 558 | switch (fc) { |
559 | case 2: | 559 | case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): |
560 | return hdr->addr3; | 560 | return hdr->addr3; |
561 | case 3: | 561 | case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS): |
562 | return hdr->addr4; | 562 | return hdr->addr4; |
563 | default: | ||
564 | return hdr->addr2; | ||
563 | } | 565 | } |
564 | return hdr->addr2; | ||
565 | } | 566 | } |
566 | 567 | ||
567 | /** | 568 | /** |
@@ -577,12 +578,13 @@ static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) | |||
577 | */ | 578 | */ |
578 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) | 579 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) |
579 | { | 580 | { |
580 | u8 *raw = (u8 *) hdr; | 581 | __le16 fc = hdr->frame_control; |
581 | u8 to_ds = (*(raw+1)) & 1; /* get the TODS bit */ | 582 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS); |
582 | 583 | ||
583 | if (to_ds) | 584 | if (fc) |
584 | return hdr->addr3; | 585 | return hdr->addr3; |
585 | return hdr->addr1; | 586 | else |
587 | return hdr->addr1; | ||
586 | } | 588 | } |
587 | 589 | ||
588 | /** | 590 | /** |
@@ -595,8 +597,8 @@ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) | |||
595 | */ | 597 | */ |
596 | static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) | 598 | static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) |
597 | { | 599 | { |
598 | return (le16_to_cpu(hdr->frame_control) & | 600 | __le16 fc = hdr->frame_control; |
599 | IEEE80211_FCTL_MOREFRAGS) != 0; | 601 | return !!(fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)); |
600 | } | 602 | } |
601 | 603 | ||
602 | #endif /* IEEE80211_H */ | 604 | #endif /* IEEE80211_H */ |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 75a34609eed7..909956c97c44 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -336,13 +336,16 @@ enum mac80211_rx_flags { | |||
336 | * The low-level driver should provide this information (the subset | 336 | * The low-level driver should provide this information (the subset |
337 | * supported by hardware) to the 802.11 code with each received | 337 | * supported by hardware) to the 802.11 code with each received |
338 | * frame. | 338 | * frame. |
339 | * | ||
339 | * @mactime: value in microseconds of the 64-bit Time Synchronization Function | 340 | * @mactime: value in microseconds of the 64-bit Time Synchronization Function |
340 | * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. | 341 | * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. |
341 | * @band: the active band when this frame was received | 342 | * @band: the active band when this frame was received |
342 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz | 343 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz |
343 | * @ssi: signal strength when receiving this frame | 344 | * @signal: signal strength when receiving this frame, either in dBm, in dB or |
344 | * @signal: used as 'qual' in statistics reporting | 345 | * unspecified depending on the hardware capabilities flags |
345 | * @noise: PHY noise when receiving this frame | 346 | * @IEEE80211_HW_SIGNAL_* |
347 | * @noise: noise when receiving this frame, in dBm. | ||
348 | * @qual: overall signal quality indication, in percent (0-100). | ||
346 | * @antenna: antenna used | 349 | * @antenna: antenna used |
347 | * @rate_idx: index of data rate into band's supported rates | 350 | * @rate_idx: index of data rate into band's supported rates |
348 | * @flag: %RX_FLAG_* | 351 | * @flag: %RX_FLAG_* |
@@ -351,9 +354,9 @@ struct ieee80211_rx_status { | |||
351 | u64 mactime; | 354 | u64 mactime; |
352 | enum ieee80211_band band; | 355 | enum ieee80211_band band; |
353 | int freq; | 356 | int freq; |
354 | int ssi; | ||
355 | int signal; | 357 | int signal; |
356 | int noise; | 358 | int noise; |
359 | int qual; | ||
357 | int antenna; | 360 | int antenna; |
358 | int rate_idx; | 361 | int rate_idx; |
359 | int flag; | 362 | int flag; |
@@ -392,7 +395,8 @@ enum ieee80211_tx_status_flags { | |||
392 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. | 395 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. |
393 | * @ampdu_ack_map: block ack bit map for the aggregation. | 396 | * @ampdu_ack_map: block ack bit map for the aggregation. |
394 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. | 397 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. |
395 | * @ack_signal: signal strength of the ACK frame | 398 | * @ack_signal: signal strength of the ACK frame either in dBm, dB or unspec |
399 | * depending on hardware capabilites flags @IEEE80211_HW_SIGNAL_* | ||
396 | */ | 400 | */ |
397 | struct ieee80211_tx_status { | 401 | struct ieee80211_tx_status { |
398 | struct ieee80211_tx_control control; | 402 | struct ieee80211_tx_control control; |
@@ -703,6 +707,25 @@ enum ieee80211_tkip_key_type { | |||
703 | * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE: | 707 | * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE: |
704 | * Hardware is not capable of receiving frames with short preamble on | 708 | * Hardware is not capable of receiving frames with short preamble on |
705 | * the 2.4 GHz band. | 709 | * the 2.4 GHz band. |
710 | * | ||
711 | * @IEEE80211_HW_SIGNAL_UNSPEC: | ||
712 | * Hardware can provide signal values but we don't know its units. We | ||
713 | * expect values between 0 and @max_signal. | ||
714 | * If possible please provide dB or dBm instead. | ||
715 | * | ||
716 | * @IEEE80211_HW_SIGNAL_DB: | ||
717 | * Hardware gives signal values in dB, decibel difference from an | ||
718 | * arbitrary, fixed reference. We expect values between 0 and @max_signal. | ||
719 | * If possible please provide dBm instead. | ||
720 | * | ||
721 | * @IEEE80211_HW_SIGNAL_DBM: | ||
722 | * Hardware gives signal values in dBm, decibel difference from | ||
723 | * one milliwatt. This is the preferred method since it is standardized | ||
724 | * between different devices. @max_signal does not need to be set. | ||
725 | * | ||
726 | * @IEEE80211_HW_NOISE_DBM: | ||
727 | * Hardware can provide noise (radio interference) values in units dBm, | ||
728 | * decibel difference from one milliwatt. | ||
706 | */ | 729 | */ |
707 | enum ieee80211_hw_flags { | 730 | enum ieee80211_hw_flags { |
708 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, | 731 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, |
@@ -710,6 +733,10 @@ enum ieee80211_hw_flags { | |||
710 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, | 733 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, |
711 | IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, | 734 | IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, |
712 | IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, | 735 | IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, |
736 | IEEE80211_HW_SIGNAL_UNSPEC = 1<<5, | ||
737 | IEEE80211_HW_SIGNAL_DB = 1<<6, | ||
738 | IEEE80211_HW_SIGNAL_DBM = 1<<7, | ||
739 | IEEE80211_HW_NOISE_DBM = 1<<8, | ||
713 | }; | 740 | }; |
714 | 741 | ||
715 | /** | 742 | /** |
@@ -740,12 +767,8 @@ enum ieee80211_hw_flags { | |||
740 | * | 767 | * |
741 | * @channel_change_time: time (in microseconds) it takes to change channels. | 768 | * @channel_change_time: time (in microseconds) it takes to change channels. |
742 | * | 769 | * |
743 | * @max_rssi: Maximum value for ssi in RX information, use | 770 | * @max_signal: Maximum value for signal (rssi) in RX information, used |
744 | * negative numbers for dBm and 0 to indicate no support. | 771 | * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB |
745 | * | ||
746 | * @max_signal: like @max_rssi, but for the signal value. | ||
747 | * | ||
748 | * @max_noise: like @max_rssi, but for the noise value. | ||
749 | * | 772 | * |
750 | * @queues: number of available hardware transmit queues for | 773 | * @queues: number of available hardware transmit queues for |
751 | * data packets. WMM/QoS requires at least four, these | 774 | * data packets. WMM/QoS requires at least four, these |
@@ -775,9 +798,7 @@ struct ieee80211_hw { | |||
775 | int channel_change_time; | 798 | int channel_change_time; |
776 | int vif_data_size; | 799 | int vif_data_size; |
777 | u16 queues, ampdu_queues; | 800 | u16 queues, ampdu_queues; |
778 | s8 max_rssi; | ||
779 | s8 max_signal; | 801 | s8 max_signal; |
780 | s8 max_noise; | ||
781 | }; | 802 | }; |
782 | 803 | ||
783 | /** | 804 | /** |
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 200ee1e63728..69dbc342a464 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -391,7 +391,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
391 | 391 | ||
392 | wstats.updated = 0; | 392 | wstats.updated = 0; |
393 | if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { | 393 | if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { |
394 | wstats.level = rx_stats->rssi; | 394 | wstats.level = rx_stats->signal; |
395 | wstats.updated |= IW_QUAL_LEVEL_UPDATED; | 395 | wstats.updated |= IW_QUAL_LEVEL_UPDATED; |
396 | } else | 396 | } else |
397 | wstats.updated |= IW_QUAL_LEVEL_INVALID; | 397 | wstats.updated |= IW_QUAL_LEVEL_INVALID; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 699d97b8de5e..3cef80dcd0e5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -602,6 +602,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
602 | */ | 602 | */ |
603 | 603 | ||
604 | if (params->station_flags & STATION_FLAG_CHANGED) { | 604 | if (params->station_flags & STATION_FLAG_CHANGED) { |
605 | spin_lock_bh(&sta->lock); | ||
605 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 606 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
606 | if (params->station_flags & STATION_FLAG_AUTHORIZED) | 607 | if (params->station_flags & STATION_FLAG_AUTHORIZED) |
607 | sta->flags |= WLAN_STA_AUTHORIZED; | 608 | sta->flags |= WLAN_STA_AUTHORIZED; |
@@ -613,6 +614,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
613 | sta->flags &= ~WLAN_STA_WME; | 614 | sta->flags &= ~WLAN_STA_WME; |
614 | if (params->station_flags & STATION_FLAG_WME) | 615 | if (params->station_flags & STATION_FLAG_WME) |
615 | sta->flags |= WLAN_STA_WME; | 616 | sta->flags |= WLAN_STA_WME; |
617 | spin_unlock_bh(&sta->lock); | ||
616 | } | 618 | } |
617 | 619 | ||
618 | /* | 620 | /* |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 676a93202ff9..a2cc0284c9d0 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -63,8 +63,8 @@ STA_FILE(tx_fragments, tx_fragments, LU); | |||
63 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
65 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
66 | STA_FILE(last_rssi, last_rssi, D); | ||
67 | STA_FILE(last_signal, last_signal, D); | 66 | STA_FILE(last_signal, last_signal, D); |
67 | STA_FILE(last_qual, last_qual, D); | ||
68 | STA_FILE(last_noise, last_noise, D); | 68 | STA_FILE(last_noise, last_noise, D); |
69 | STA_FILE(channel_use, channel_use, D); | 69 | STA_FILE(channel_use, channel_use, D); |
70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); | 70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
@@ -74,14 +74,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
74 | { | 74 | { |
75 | char buf[100]; | 75 | char buf[100]; |
76 | struct sta_info *sta = file->private_data; | 76 | struct sta_info *sta = file->private_data; |
77 | u32 staflags = get_sta_flags(sta); | ||
77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", | 78 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 79 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", |
79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 80 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 81 | staflags & WLAN_STA_PS ? "PS\n" : "", |
81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 82 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 83 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 84 | staflags & WLAN_STA_WME ? "WME\n" : "", |
84 | sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); | 85 | staflags & WLAN_STA_WDS ? "WDS\n" : ""); |
85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 86 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
86 | } | 87 | } |
87 | STA_OPS(flags); | 88 | STA_OPS(flags); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d82ed20a344c..ed0d9b35ae6f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -82,7 +82,7 @@ struct ieee80211_sta_bss { | |||
82 | u16 capability; /* host byte order */ | 82 | u16 capability; /* host byte order */ |
83 | enum ieee80211_band band; | 83 | enum ieee80211_band band; |
84 | int freq; | 84 | int freq; |
85 | int rssi, signal, noise; | 85 | int signal, noise, qual; |
86 | u8 *wpa_ie; | 86 | u8 *wpa_ie; |
87 | size_t wpa_ie_len; | 87 | size_t wpa_ie_len; |
88 | u8 *rsn_ie; | 88 | u8 *rsn_ie; |
@@ -610,8 +610,8 @@ struct ieee80211_local { | |||
610 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 610 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
611 | struct timer_list sta_cleanup; | 611 | struct timer_list sta_cleanup; |
612 | 612 | ||
613 | unsigned long state[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; | 613 | unsigned long state[IEEE80211_MAX_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; |
614 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; | 614 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; |
615 | struct tasklet_struct tx_pending_tasklet; | 615 | struct tasklet_struct tx_pending_tasklet; |
616 | 616 | ||
617 | /* number of interfaces with corresponding IFF_ flags */ | 617 | /* number of interfaces with corresponding IFF_ flags */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4a8062f8b1cc..3c64e42eb12e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -166,9 +166,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
166 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | | 166 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | |
167 | IEEE80211_AUTH_ALG_SHARED_KEY; | 167 | IEEE80211_AUTH_ALG_SHARED_KEY; |
168 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | | 168 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | |
169 | IEEE80211_STA_WMM_ENABLED | | ||
170 | IEEE80211_STA_AUTO_BSSID_SEL | | 169 | IEEE80211_STA_AUTO_BSSID_SEL | |
171 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 170 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
171 | if (sdata->local->hw.queues >= 4) | ||
172 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; | ||
172 | 173 | ||
173 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | 174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); |
174 | sdata->bss = &msdata->u.ap; | 175 | sdata->bss = &msdata->u.ap; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 88b211af7c1f..d4893bd17754 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -321,7 +321,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
321 | * some hardware cannot handle TKIP with QoS, so | 321 | * some hardware cannot handle TKIP with QoS, so |
322 | * we indicate whether QoS could be in use. | 322 | * we indicate whether QoS could be in use. |
323 | */ | 323 | */ |
324 | if (sta->flags & WLAN_STA_WME) | 324 | if (test_sta_flags(sta, WLAN_STA_WME)) |
325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
326 | 326 | ||
327 | /* | 327 | /* |
@@ -342,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
342 | /* same here, the AP could be using QoS */ | 342 | /* same here, the AP could be using QoS */ |
343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); | 343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); |
344 | if (ap) { | 344 | if (ap) { |
345 | if (ap->flags & WLAN_STA_WME) | 345 | if (test_sta_flags(ap, WLAN_STA_WME)) |
346 | key->conf.flags |= | 346 | key->conf.flags |= |
347 | IEEE80211_KEY_FLAG_WMM_STA; | 347 | IEEE80211_KEY_FLAG_WMM_STA; |
348 | } | 348 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index eb347eca30b5..36016363d225 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -346,6 +346,7 @@ static int ieee80211_open(struct net_device *dev) | |||
346 | goto err_del_interface; | 346 | goto err_del_interface; |
347 | } | 347 | } |
348 | 348 | ||
349 | /* no locking required since STA is not live yet */ | ||
349 | sta->flags |= WLAN_STA_AUTHORIZED; | 350 | sta->flags |= WLAN_STA_AUTHORIZED; |
350 | 351 | ||
351 | res = sta_info_insert(sta); | 352 | res = sta_info_insert(sta); |
@@ -588,7 +589,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
588 | return -ENOENT; | 589 | return -ENOENT; |
589 | } | 590 | } |
590 | 591 | ||
591 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 592 | spin_lock_bh(&sta->lock); |
592 | 593 | ||
593 | /* we have tried too many times, receiver does not want A-MPDU */ | 594 | /* we have tried too many times, receiver does not want A-MPDU */ |
594 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
@@ -691,7 +692,7 @@ start_ba_err: | |||
691 | spin_unlock_bh(&local->mdev->queue_lock); | 692 | spin_unlock_bh(&local->mdev->queue_lock); |
692 | ret = -EBUSY; | 693 | ret = -EBUSY; |
693 | start_ba_exit: | 694 | start_ba_exit: |
694 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 695 | spin_unlock_bh(&sta->lock); |
695 | rcu_read_unlock(); | 696 | rcu_read_unlock(); |
696 | return ret; | 697 | return ret; |
697 | } | 698 | } |
@@ -719,7 +720,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
719 | 720 | ||
720 | /* check if the TID is in aggregation */ | 721 | /* check if the TID is in aggregation */ |
721 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
722 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 723 | spin_lock_bh(&sta->lock); |
723 | 724 | ||
724 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 725 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
725 | ret = -ENOENT; | 726 | ret = -ENOENT; |
@@ -749,7 +750,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
749 | } | 750 | } |
750 | 751 | ||
751 | stop_BA_exit: | 752 | stop_BA_exit: |
752 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 753 | spin_unlock_bh(&sta->lock); |
753 | rcu_read_unlock(); | 754 | rcu_read_unlock(); |
754 | return ret; | 755 | return ret; |
755 | } | 756 | } |
@@ -778,12 +779,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
778 | } | 779 | } |
779 | 780 | ||
780 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
781 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 782 | spin_lock_bh(&sta->lock); |
782 | 783 | ||
783 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
784 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
785 | *state); | 786 | *state); |
786 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 787 | spin_unlock_bh(&sta->lock); |
787 | rcu_read_unlock(); | 788 | rcu_read_unlock(); |
788 | return; | 789 | return; |
789 | } | 790 | } |
@@ -796,7 +797,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
796 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
797 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
798 | } | 799 | } |
799 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 800 | spin_unlock_bh(&sta->lock); |
800 | rcu_read_unlock(); | 801 | rcu_read_unlock(); |
801 | } | 802 | } |
802 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
@@ -830,10 +831,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
830 | } | 831 | } |
831 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
832 | 833 | ||
833 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 834 | spin_lock_bh(&sta->lock); |
834 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
835 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
836 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 837 | spin_unlock_bh(&sta->lock); |
837 | rcu_read_unlock(); | 838 | rcu_read_unlock(); |
838 | return; | 839 | return; |
839 | } | 840 | } |
@@ -860,7 +861,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
860 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 861 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
861 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 862 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
862 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 863 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
863 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 864 | spin_unlock_bh(&sta->lock); |
864 | 865 | ||
865 | rcu_read_unlock(); | 866 | rcu_read_unlock(); |
866 | } | 867 | } |
@@ -1315,7 +1316,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1315 | * packet. If the STA went to power save mode, this will happen | 1316 | * packet. If the STA went to power save mode, this will happen |
1316 | * happen when it wakes up for the next time. | 1317 | * happen when it wakes up for the next time. |
1317 | */ | 1318 | */ |
1318 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1319 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
1319 | 1320 | ||
1320 | /* | 1321 | /* |
1321 | * This code races in the following way: | 1322 | * This code races in the following way: |
@@ -1347,7 +1348,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1347 | * can be unknown, for example with different interrupt status | 1348 | * can be unknown, for example with different interrupt status |
1348 | * bits. | 1349 | * bits. |
1349 | */ | 1350 | */ |
1350 | if (sta->flags & WLAN_STA_PS && | 1351 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1351 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1352 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1353 | ieee80211_remove_tx_extra(local, sta->key, skb, |
1353 | &status->control); | 1354 | &status->control); |
@@ -1355,7 +1356,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1355 | return; | 1356 | return; |
1356 | } | 1357 | } |
1357 | 1358 | ||
1358 | if (!(sta->flags & WLAN_STA_PS) && | 1359 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1359 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { |
1360 | /* Software retry the packet once */ | 1361 | /* Software retry the packet once */ |
1361 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; |
@@ -1370,7 +1371,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1370 | "queue_len=%d PS=%d @%lu\n", | 1371 | "queue_len=%d PS=%d @%lu\n", |
1371 | wiphy_name(local->hw.wiphy), | 1372 | wiphy_name(local->hw.wiphy), |
1372 | skb_queue_len(&sta->tx_filtered), | 1373 | skb_queue_len(&sta->tx_filtered), |
1373 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1374 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1374 | dev_kfree_skb(skb); | 1375 | dev_kfree_skb(skb); |
1375 | } | 1376 | } |
1376 | 1377 | ||
@@ -1399,7 +1400,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1399 | struct sta_info *sta; | 1400 | struct sta_info *sta; |
1400 | sta = sta_info_get(local, hdr->addr1); | 1401 | sta = sta_info_get(local, hdr->addr1); |
1401 | if (sta) { | 1402 | if (sta) { |
1402 | if (sta->flags & WLAN_STA_PS) { | 1403 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
1403 | /* | 1404 | /* |
1404 | * The STA is in power save mode, so assume | 1405 | * The STA is in power save mode, so assume |
1405 | * that this TX packet failed because of that. | 1406 | * that this TX packet failed because of that. |
@@ -1701,13 +1702,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1701 | 1702 | ||
1702 | local->hw.conf.beacon_int = 1000; | 1703 | local->hw.conf.beacon_int = 1000; |
1703 | 1704 | ||
1704 | local->wstats_flags |= local->hw.max_rssi ? | 1705 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1705 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1706 | IEEE80211_HW_SIGNAL_DB | |
1706 | local->wstats_flags |= local->hw.max_signal ? | 1707 | IEEE80211_HW_SIGNAL_DBM) ? |
1707 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
1708 | local->wstats_flags |= local->hw.max_noise ? | 1709 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
1709 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
1710 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1711 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
1711 | local->wstats_flags |= IW_QUAL_DBM; | 1712 | local->wstats_flags |= IW_QUAL_DBM; |
1712 | 1713 | ||
1713 | result = sta_info_start(local); | 1714 | result = sta_info_start(local); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index af0cd1e3e213..7fa149e230e6 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -26,7 +26,7 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) | |||
26 | { | 26 | { |
27 | if (ae) | 27 | if (ae) |
28 | offset += 6; | 28 | offset += 6; |
29 | return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset))); | 29 | return get_unaligned_le32(preq_elem + offset); |
30 | } | 30 | } |
31 | 31 | ||
32 | /* HWMP IE processing macros */ | 32 | /* HWMP IE processing macros */ |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 37f0c2b94ae7..9efeb1f07025 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | |||
79 | * | 79 | * |
80 | * @sta: mes peer link to restart | 80 | * @sta: mes peer link to restart |
81 | * | 81 | * |
82 | * Locking: this function must be called holding sta->plink_lock | 82 | * Locking: this function must be called holding sta->lock |
83 | */ | 83 | */ |
84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) | 84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) |
85 | { | 85 | { |
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | if (!sta) | 105 | if (!sta) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | sta->flags |= WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED; |
109 | sta->supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->supp_rates[local->hw.conf.channel->band] = rates; |
110 | 110 | ||
111 | return sta; | 111 | return sta; |
@@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
118 | * | 118 | * |
119 | * All mesh paths with this peer as next hop will be flushed | 119 | * All mesh paths with this peer as next hop will be flushed |
120 | * | 120 | * |
121 | * Locking: the caller must hold sta->plink_lock | 121 | * Locking: the caller must hold sta->lock |
122 | */ | 122 | */ |
123 | static void __mesh_plink_deactivate(struct sta_info *sta) | 123 | static void __mesh_plink_deactivate(struct sta_info *sta) |
124 | { | 124 | { |
@@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta) | |||
139 | */ | 139 | */ |
140 | void mesh_plink_deactivate(struct sta_info *sta) | 140 | void mesh_plink_deactivate(struct sta_info *sta) |
141 | { | 141 | { |
142 | spin_lock_bh(&sta->plink_lock); | 142 | spin_lock_bh(&sta->lock); |
143 | __mesh_plink_deactivate(sta); | 143 | __mesh_plink_deactivate(sta); |
144 | spin_unlock_bh(&sta->plink_lock); | 144 | spin_unlock_bh(&sta->lock); |
145 | } | 145 | } |
146 | 146 | ||
147 | static int mesh_plink_frame_tx(struct net_device *dev, | 147 | static int mesh_plink_frame_tx(struct net_device *dev, |
@@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data) | |||
270 | */ | 270 | */ |
271 | sta = (struct sta_info *) data; | 271 | sta = (struct sta_info *) data; |
272 | 272 | ||
273 | spin_lock_bh(&sta->plink_lock); | 273 | spin_lock_bh(&sta->lock); |
274 | if (sta->ignore_plink_timer) { | 274 | if (sta->ignore_plink_timer) { |
275 | sta->ignore_plink_timer = false; | 275 | sta->ignore_plink_timer = false; |
276 | spin_unlock_bh(&sta->plink_lock); | 276 | spin_unlock_bh(&sta->lock); |
277 | return; | 277 | return; |
278 | } | 278 | } |
279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", | 279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", |
@@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data) | |||
298 | rand % sta->plink_timeout; | 298 | rand % sta->plink_timeout; |
299 | ++sta->plink_retries; | 299 | ++sta->plink_retries; |
300 | mod_plink_timer(sta, sta->plink_timeout); | 300 | mod_plink_timer(sta, sta->plink_timeout); |
301 | spin_unlock_bh(&sta->plink_lock); | 301 | spin_unlock_bh(&sta->lock); |
302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
303 | 0, 0); | 303 | 0, 0); |
304 | break; | 304 | break; |
@@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data) | |||
311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); | 311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); |
312 | sta->plink_state = PLINK_HOLDING; | 312 | sta->plink_state = PLINK_HOLDING; |
313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
314 | spin_unlock_bh(&sta->plink_lock); | 314 | spin_unlock_bh(&sta->lock); |
315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, | 315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, |
316 | reason); | 316 | reason); |
317 | break; | 317 | break; |
@@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data) | |||
319 | /* holding timer */ | 319 | /* holding timer */ |
320 | del_timer(&sta->plink_timer); | 320 | del_timer(&sta->plink_timer); |
321 | mesh_plink_fsm_restart(sta); | 321 | mesh_plink_fsm_restart(sta); |
322 | spin_unlock_bh(&sta->plink_lock); | 322 | spin_unlock_bh(&sta->lock); |
323 | break; | 323 | break; |
324 | default: | 324 | default: |
325 | spin_unlock_bh(&sta->plink_lock); | 325 | spin_unlock_bh(&sta->lock); |
326 | break; | 326 | break; |
327 | } | 327 | } |
328 | } | 328 | } |
@@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta) | |||
344 | DECLARE_MAC_BUF(mac); | 344 | DECLARE_MAC_BUF(mac); |
345 | #endif | 345 | #endif |
346 | 346 | ||
347 | spin_lock_bh(&sta->plink_lock); | 347 | spin_lock_bh(&sta->lock); |
348 | get_random_bytes(&llid, 2); | 348 | get_random_bytes(&llid, 2); |
349 | sta->llid = llid; | 349 | sta->llid = llid; |
350 | if (sta->plink_state != PLINK_LISTEN) { | 350 | if (sta->plink_state != PLINK_LISTEN) { |
351 | spin_unlock_bh(&sta->plink_lock); | 351 | spin_unlock_bh(&sta->lock); |
352 | return -EBUSY; | 352 | return -EBUSY; |
353 | } | 353 | } |
354 | sta->plink_state = PLINK_OPN_SNT; | 354 | sta->plink_state = PLINK_OPN_SNT; |
355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
356 | spin_unlock_bh(&sta->plink_lock); | 356 | spin_unlock_bh(&sta->lock); |
357 | mpl_dbg("Mesh plink: starting establishment with %s\n", | 357 | mpl_dbg("Mesh plink: starting establishment with %s\n", |
358 | print_mac(mac, sta->addr)); | 358 | print_mac(mac, sta->addr)); |
359 | 359 | ||
@@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta) | |||
367 | DECLARE_MAC_BUF(mac); | 367 | DECLARE_MAC_BUF(mac); |
368 | #endif | 368 | #endif |
369 | 369 | ||
370 | spin_lock_bh(&sta->plink_lock); | 370 | spin_lock_bh(&sta->lock); |
371 | __mesh_plink_deactivate(sta); | 371 | __mesh_plink_deactivate(sta); |
372 | sta->plink_state = PLINK_BLOCKED; | 372 | sta->plink_state = PLINK_BLOCKED; |
373 | spin_unlock_bh(&sta->plink_lock); | 373 | spin_unlock_bh(&sta->lock); |
374 | } | 374 | } |
375 | 375 | ||
376 | int mesh_plink_close(struct sta_info *sta) | 376 | int mesh_plink_close(struct sta_info *sta) |
@@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta) | |||
383 | 383 | ||
384 | mpl_dbg("Mesh plink: closing link with %s\n", | 384 | mpl_dbg("Mesh plink: closing link with %s\n", |
385 | print_mac(mac, sta->addr)); | 385 | print_mac(mac, sta->addr)); |
386 | spin_lock_bh(&sta->plink_lock); | 386 | spin_lock_bh(&sta->lock); |
387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); | 387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); |
388 | reason = sta->reason; | 388 | reason = sta->reason; |
389 | 389 | ||
390 | if (sta->plink_state == PLINK_LISTEN || | 390 | if (sta->plink_state == PLINK_LISTEN || |
391 | sta->plink_state == PLINK_BLOCKED) { | 391 | sta->plink_state == PLINK_BLOCKED) { |
392 | mesh_plink_fsm_restart(sta); | 392 | mesh_plink_fsm_restart(sta); |
393 | spin_unlock_bh(&sta->plink_lock); | 393 | spin_unlock_bh(&sta->lock); |
394 | return 0; | 394 | return 0; |
395 | } else if (sta->plink_state == PLINK_ESTAB) { | 395 | } else if (sta->plink_state == PLINK_ESTAB) { |
396 | __mesh_plink_deactivate(sta); | 396 | __mesh_plink_deactivate(sta); |
@@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta) | |||
402 | sta->plink_state = PLINK_HOLDING; | 402 | sta->plink_state = PLINK_HOLDING; |
403 | llid = sta->llid; | 403 | llid = sta->llid; |
404 | plid = sta->plid; | 404 | plid = sta->plid; |
405 | spin_unlock_bh(&sta->plink_lock); | 405 | spin_unlock_bh(&sta->lock); |
406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, | 406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, |
407 | plid, reason); | 407 | plid, reason); |
408 | return 0; | 408 | return 0; |
@@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
490 | /* avoid warning */ | 490 | /* avoid warning */ |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | spin_lock_bh(&sta->plink_lock); | 493 | spin_lock_bh(&sta->lock); |
494 | } else if (!sta) { | 494 | } else if (!sta) { |
495 | /* ftype == PLINK_OPEN */ | 495 | /* ftype == PLINK_OPEN */ |
496 | u64 rates; | 496 | u64 rates; |
@@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
512 | return; | 512 | return; |
513 | } | 513 | } |
514 | event = OPN_ACPT; | 514 | event = OPN_ACPT; |
515 | spin_lock_bh(&sta->plink_lock); | 515 | spin_lock_bh(&sta->lock); |
516 | } else { | 516 | } else { |
517 | spin_lock_bh(&sta->plink_lock); | 517 | spin_lock_bh(&sta->lock); |
518 | switch (ftype) { | 518 | switch (ftype) { |
519 | case PLINK_OPEN: | 519 | case PLINK_OPEN: |
520 | if (!mesh_plink_free_count(sdata) || | 520 | if (!mesh_plink_free_count(sdata) || |
@@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
551 | break; | 551 | break; |
552 | default: | 552 | default: |
553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); | 553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); |
554 | spin_unlock_bh(&sta->plink_lock); | 554 | spin_unlock_bh(&sta->lock); |
555 | rcu_read_unlock(); | 555 | rcu_read_unlock(); |
556 | return; | 556 | return; |
557 | } | 557 | } |
@@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
568 | switch (event) { | 568 | switch (event) { |
569 | case CLS_ACPT: | 569 | case CLS_ACPT: |
570 | mesh_plink_fsm_restart(sta); | 570 | mesh_plink_fsm_restart(sta); |
571 | spin_unlock_bh(&sta->plink_lock); | 571 | spin_unlock_bh(&sta->lock); |
572 | break; | 572 | break; |
573 | case OPN_ACPT: | 573 | case OPN_ACPT: |
574 | sta->plink_state = PLINK_OPN_RCVD; | 574 | sta->plink_state = PLINK_OPN_RCVD; |
@@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
576 | get_random_bytes(&llid, 2); | 576 | get_random_bytes(&llid, 2); |
577 | sta->llid = llid; | 577 | sta->llid = llid; |
578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
579 | spin_unlock_bh(&sta->plink_lock); | 579 | spin_unlock_bh(&sta->lock); |
580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
581 | 0, 0); | 581 | 0, 0); |
582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, | 582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, |
583 | llid, plid, 0); | 583 | llid, plid, 0); |
584 | break; | 584 | break; |
585 | default: | 585 | default: |
586 | spin_unlock_bh(&sta->plink_lock); | 586 | spin_unlock_bh(&sta->lock); |
587 | break; | 587 | break; |
588 | } | 588 | } |
589 | break; | 589 | break; |
@@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
603 | sta->ignore_plink_timer = true; | 603 | sta->ignore_plink_timer = true; |
604 | 604 | ||
605 | llid = sta->llid; | 605 | llid = sta->llid; |
606 | spin_unlock_bh(&sta->plink_lock); | 606 | spin_unlock_bh(&sta->lock); |
607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
608 | plid, reason); | 608 | plid, reason); |
609 | break; | 609 | break; |
@@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
612 | sta->plink_state = PLINK_OPN_RCVD; | 612 | sta->plink_state = PLINK_OPN_RCVD; |
613 | sta->plid = plid; | 613 | sta->plid = plid; |
614 | llid = sta->llid; | 614 | llid = sta->llid; |
615 | spin_unlock_bh(&sta->plink_lock); | 615 | spin_unlock_bh(&sta->lock); |
616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
617 | plid, 0); | 617 | plid, 0); |
618 | break; | 618 | break; |
@@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
622 | dot11MeshConfirmTimeout(sdata))) | 622 | dot11MeshConfirmTimeout(sdata))) |
623 | sta->ignore_plink_timer = true; | 623 | sta->ignore_plink_timer = true; |
624 | 624 | ||
625 | spin_unlock_bh(&sta->plink_lock); | 625 | spin_unlock_bh(&sta->lock); |
626 | break; | 626 | break; |
627 | default: | 627 | default: |
628 | spin_unlock_bh(&sta->plink_lock); | 628 | spin_unlock_bh(&sta->lock); |
629 | break; | 629 | break; |
630 | } | 630 | } |
631 | break; | 631 | break; |
@@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
645 | sta->ignore_plink_timer = true; | 645 | sta->ignore_plink_timer = true; |
646 | 646 | ||
647 | llid = sta->llid; | 647 | llid = sta->llid; |
648 | spin_unlock_bh(&sta->plink_lock); | 648 | spin_unlock_bh(&sta->lock); |
649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
650 | plid, reason); | 650 | plid, reason); |
651 | break; | 651 | break; |
652 | case OPN_ACPT: | 652 | case OPN_ACPT: |
653 | llid = sta->llid; | 653 | llid = sta->llid; |
654 | spin_unlock_bh(&sta->plink_lock); | 654 | spin_unlock_bh(&sta->lock); |
655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
656 | plid, 0); | 656 | plid, 0); |
657 | break; | 657 | break; |
@@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
659 | del_timer(&sta->plink_timer); | 659 | del_timer(&sta->plink_timer); |
660 | sta->plink_state = PLINK_ESTAB; | 660 | sta->plink_state = PLINK_ESTAB; |
661 | mesh_plink_inc_estab_count(sdata); | 661 | mesh_plink_inc_estab_count(sdata); |
662 | spin_unlock_bh(&sta->plink_lock); | 662 | spin_unlock_bh(&sta->lock); |
663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
664 | print_mac(mac, sta->addr)); | 664 | print_mac(mac, sta->addr)); |
665 | break; | 665 | break; |
666 | default: | 666 | default: |
667 | spin_unlock_bh(&sta->plink_lock); | 667 | spin_unlock_bh(&sta->lock); |
668 | break; | 668 | break; |
669 | } | 669 | } |
670 | break; | 670 | break; |
@@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
684 | sta->ignore_plink_timer = true; | 684 | sta->ignore_plink_timer = true; |
685 | 685 | ||
686 | llid = sta->llid; | 686 | llid = sta->llid; |
687 | spin_unlock_bh(&sta->plink_lock); | 687 | spin_unlock_bh(&sta->lock); |
688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
689 | plid, reason); | 689 | plid, reason); |
690 | break; | 690 | break; |
@@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
692 | del_timer(&sta->plink_timer); | 692 | del_timer(&sta->plink_timer); |
693 | sta->plink_state = PLINK_ESTAB; | 693 | sta->plink_state = PLINK_ESTAB; |
694 | mesh_plink_inc_estab_count(sdata); | 694 | mesh_plink_inc_estab_count(sdata); |
695 | spin_unlock_bh(&sta->plink_lock); | 695 | spin_unlock_bh(&sta->lock); |
696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
697 | print_mac(mac, sta->addr)); | 697 | print_mac(mac, sta->addr)); |
698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
699 | plid, 0); | 699 | plid, 0); |
700 | break; | 700 | break; |
701 | default: | 701 | default: |
702 | spin_unlock_bh(&sta->plink_lock); | 702 | spin_unlock_bh(&sta->lock); |
703 | break; | 703 | break; |
704 | } | 704 | } |
705 | break; | 705 | break; |
@@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
713 | sta->plink_state = PLINK_HOLDING; | 713 | sta->plink_state = PLINK_HOLDING; |
714 | llid = sta->llid; | 714 | llid = sta->llid; |
715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
716 | spin_unlock_bh(&sta->plink_lock); | 716 | spin_unlock_bh(&sta->lock); |
717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
718 | plid, reason); | 718 | plid, reason); |
719 | break; | 719 | break; |
720 | case OPN_ACPT: | 720 | case OPN_ACPT: |
721 | llid = sta->llid; | 721 | llid = sta->llid; |
722 | spin_unlock_bh(&sta->plink_lock); | 722 | spin_unlock_bh(&sta->lock); |
723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
724 | plid, 0); | 724 | plid, 0); |
725 | break; | 725 | break; |
726 | default: | 726 | default: |
727 | spin_unlock_bh(&sta->plink_lock); | 727 | spin_unlock_bh(&sta->lock); |
728 | break; | 728 | break; |
729 | } | 729 | } |
730 | break; | 730 | break; |
@@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
734 | if (del_timer(&sta->plink_timer)) | 734 | if (del_timer(&sta->plink_timer)) |
735 | sta->ignore_plink_timer = 1; | 735 | sta->ignore_plink_timer = 1; |
736 | mesh_plink_fsm_restart(sta); | 736 | mesh_plink_fsm_restart(sta); |
737 | spin_unlock_bh(&sta->plink_lock); | 737 | spin_unlock_bh(&sta->lock); |
738 | break; | 738 | break; |
739 | case OPN_ACPT: | 739 | case OPN_ACPT: |
740 | case CNF_ACPT: | 740 | case CNF_ACPT: |
@@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
742 | case CNF_RJCT: | 742 | case CNF_RJCT: |
743 | llid = sta->llid; | 743 | llid = sta->llid; |
744 | reason = sta->reason; | 744 | reason = sta->reason; |
745 | spin_unlock_bh(&sta->plink_lock); | 745 | spin_unlock_bh(&sta->lock); |
746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
747 | plid, reason); | 747 | plid, reason); |
748 | break; | 748 | break; |
749 | default: | 749 | default: |
750 | spin_unlock_bh(&sta->plink_lock); | 750 | spin_unlock_bh(&sta->lock); |
751 | } | 751 | } |
752 | break; | 752 | break; |
753 | default: | 753 | default: |
754 | /* should not get here, PLINK_BLOCKED is dealt with at the | 754 | /* should not get here, PLINK_BLOCKED is dealt with at the |
755 | * beggining of the function | 755 | * beggining of the function |
756 | */ | 756 | */ |
757 | spin_unlock_bh(&sta->plink_lock); | 757 | spin_unlock_bh(&sta->lock); |
758 | break; | 758 | break; |
759 | } | 759 | } |
760 | 760 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5d7719f44bea..7877d3b3f4cb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -272,6 +272,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
272 | int count; | 272 | int count; |
273 | u8 *pos; | 273 | u8 *pos; |
274 | 274 | ||
275 | if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
276 | return; | ||
277 | |||
278 | if (!wmm_param) | ||
279 | return; | ||
280 | |||
275 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 281 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
276 | return; | 282 | return; |
277 | count = wmm_param[6] & 0x0f; | 283 | count = wmm_param[6] & 0x0f; |
@@ -799,8 +805,10 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
799 | *pos++ = 1; /* WME ver */ | 805 | *pos++ = 1; /* WME ver */ |
800 | *pos++ = 0; | 806 | *pos++ = 0; |
801 | } | 807 | } |
808 | |||
802 | /* wmm support is a must to HT */ | 809 | /* wmm support is a must to HT */ |
803 | if (wmm && sband->ht_info.ht_supported) { | 810 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
811 | sband->ht_info.ht_supported) { | ||
804 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 812 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); |
805 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 813 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
806 | *pos++ = WLAN_EID_HT_CAPABILITY; | 814 | *pos++ = WLAN_EID_HT_CAPABILITY; |
@@ -1269,7 +1277,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1269 | 1277 | ||
1270 | 1278 | ||
1271 | /* examine state machine */ | 1279 | /* examine state machine */ |
1272 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1280 | spin_lock_bh(&sta->lock); |
1273 | 1281 | ||
1274 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 1282 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { |
1275 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1283 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -1336,7 +1344,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1336 | tid_agg_rx->stored_mpdu_num = 0; | 1344 | tid_agg_rx->stored_mpdu_num = 0; |
1337 | status = WLAN_STATUS_SUCCESS; | 1345 | status = WLAN_STATUS_SUCCESS; |
1338 | end: | 1346 | end: |
1339 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1347 | spin_unlock_bh(&sta->lock); |
1340 | 1348 | ||
1341 | end_no_lock: | 1349 | end_no_lock: |
1342 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, | 1350 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, |
@@ -1368,10 +1376,10 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1368 | 1376 | ||
1369 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1377 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1370 | 1378 | ||
1371 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1379 | spin_lock_bh(&sta->lock); |
1372 | 1380 | ||
1373 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1381 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1374 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1382 | spin_unlock_bh(&sta->lock); |
1375 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | 1383 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" |
1376 | "%d\n", *state); | 1384 | "%d\n", *state); |
1377 | goto addba_resp_exit; | 1385 | goto addba_resp_exit; |
@@ -1379,7 +1387,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1379 | 1387 | ||
1380 | if (mgmt->u.action.u.addba_resp.dialog_token != | 1388 | if (mgmt->u.action.u.addba_resp.dialog_token != |
1381 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 1389 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
1382 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1390 | spin_unlock_bh(&sta->lock); |
1383 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1391 | #ifdef CONFIG_MAC80211_HT_DEBUG |
1384 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 1392 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
1385 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1393 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -1403,7 +1411,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1403 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1411 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
1404 | } | 1412 | } |
1405 | 1413 | ||
1406 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1414 | spin_unlock_bh(&sta->lock); |
1407 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | 1415 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); |
1408 | } else { | 1416 | } else { |
1409 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | 1417 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); |
@@ -1411,7 +1419,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1411 | sta->ampdu_mlme.addba_req_num[tid]++; | 1419 | sta->ampdu_mlme.addba_req_num[tid]++; |
1412 | /* this will allow the state check in stop_BA_session */ | 1420 | /* this will allow the state check in stop_BA_session */ |
1413 | *state = HT_AGG_STATE_OPERATIONAL; | 1421 | *state = HT_AGG_STATE_OPERATIONAL; |
1414 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1422 | spin_unlock_bh(&sta->lock); |
1415 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, | 1423 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, |
1416 | WLAN_BACK_INITIATOR); | 1424 | WLAN_BACK_INITIATOR); |
1417 | } | 1425 | } |
@@ -1481,17 +1489,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1481 | } | 1489 | } |
1482 | 1490 | ||
1483 | /* check if TID is in operational state */ | 1491 | /* check if TID is in operational state */ |
1484 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1492 | spin_lock_bh(&sta->lock); |
1485 | if (sta->ampdu_mlme.tid_state_rx[tid] | 1493 | if (sta->ampdu_mlme.tid_state_rx[tid] |
1486 | != HT_AGG_STATE_OPERATIONAL) { | 1494 | != HT_AGG_STATE_OPERATIONAL) { |
1487 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1495 | spin_unlock_bh(&sta->lock); |
1488 | rcu_read_unlock(); | 1496 | rcu_read_unlock(); |
1489 | return; | 1497 | return; |
1490 | } | 1498 | } |
1491 | sta->ampdu_mlme.tid_state_rx[tid] = | 1499 | sta->ampdu_mlme.tid_state_rx[tid] = |
1492 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 1500 | HT_AGG_STATE_REQ_STOP_BA_MSK | |
1493 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 1501 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
1494 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1502 | spin_unlock_bh(&sta->lock); |
1495 | 1503 | ||
1496 | /* stop HW Rx aggregation. ampdu_action existence | 1504 | /* stop HW Rx aggregation. ampdu_action existence |
1497 | * already verified in session init so we add the BUG_ON */ | 1505 | * already verified in session init so we add the BUG_ON */ |
@@ -1568,10 +1576,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev, | |||
1568 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, | 1576 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, |
1569 | WLAN_BACK_INITIATOR, 0); | 1577 | WLAN_BACK_INITIATOR, 0); |
1570 | else { /* WLAN_BACK_RECIPIENT */ | 1578 | else { /* WLAN_BACK_RECIPIENT */ |
1571 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1579 | spin_lock_bh(&sta->lock); |
1572 | sta->ampdu_mlme.tid_state_tx[tid] = | 1580 | sta->ampdu_mlme.tid_state_tx[tid] = |
1573 | HT_AGG_STATE_OPERATIONAL; | 1581 | HT_AGG_STATE_OPERATIONAL; |
1574 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1582 | spin_unlock_bh(&sta->lock); |
1575 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, | 1583 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, |
1576 | WLAN_BACK_RECIPIENT); | 1584 | WLAN_BACK_RECIPIENT); |
1577 | } | 1585 | } |
@@ -1608,9 +1616,9 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1608 | 1616 | ||
1609 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1617 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1610 | /* check if the TID waits for addBA response */ | 1618 | /* check if the TID waits for addBA response */ |
1611 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1619 | spin_lock_bh(&sta->lock); |
1612 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1620 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1613 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1621 | spin_unlock_bh(&sta->lock); |
1614 | *state = HT_AGG_STATE_IDLE; | 1622 | *state = HT_AGG_STATE_IDLE; |
1615 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 1623 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
1616 | "expecting addBA response there", tid); | 1624 | "expecting addBA response there", tid); |
@@ -1621,7 +1629,7 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1621 | 1629 | ||
1622 | /* go through the state check in stop_BA_session */ | 1630 | /* go through the state check in stop_BA_session */ |
1623 | *state = HT_AGG_STATE_OPERATIONAL; | 1631 | *state = HT_AGG_STATE_OPERATIONAL; |
1624 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1632 | spin_unlock_bh(&sta->lock); |
1625 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, | 1633 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, |
1626 | WLAN_BACK_INITIATOR); | 1634 | WLAN_BACK_INITIATOR); |
1627 | 1635 | ||
@@ -1987,8 +1995,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1987 | local->hw.conf.channel->center_freq, | 1995 | local->hw.conf.channel->center_freq, |
1988 | ifsta->ssid, ifsta->ssid_len); | 1996 | ifsta->ssid, ifsta->ssid_len); |
1989 | if (bss) { | 1997 | if (bss) { |
1990 | sta->last_rssi = bss->rssi; | ||
1991 | sta->last_signal = bss->signal; | 1998 | sta->last_signal = bss->signal; |
1999 | sta->last_qual = bss->qual; | ||
1992 | sta->last_noise = bss->noise; | 2000 | sta->last_noise = bss->noise; |
1993 | ieee80211_rx_bss_put(dev, bss); | 2001 | ieee80211_rx_bss_put(dev, bss); |
1994 | } | 2002 | } |
@@ -2012,8 +2020,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2012 | * to between the sta_info_alloc() and sta_info_insert() above. | 2020 | * to between the sta_info_alloc() and sta_info_insert() above. |
2013 | */ | 2021 | */ |
2014 | 2022 | ||
2015 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | | 2023 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
2016 | WLAN_STA_AUTHORIZED; | 2024 | WLAN_STA_AUTHORIZED); |
2017 | 2025 | ||
2018 | rates = 0; | 2026 | rates = 0; |
2019 | basic_rates = 0; | 2027 | basic_rates = 0; |
@@ -2057,7 +2065,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2057 | else | 2065 | else |
2058 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 2066 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
2059 | 2067 | ||
2060 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | 2068 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
2069 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
2061 | struct ieee80211_ht_bss_info bss_info; | 2070 | struct ieee80211_ht_bss_info bss_info; |
2062 | ieee80211_ht_cap_ie_to_ht_info( | 2071 | ieee80211_ht_cap_ie_to_ht_info( |
2063 | (struct ieee80211_ht_cap *) | 2072 | (struct ieee80211_ht_cap *) |
@@ -2070,8 +2079,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2070 | 2079 | ||
2071 | rate_control_rate_init(sta, local); | 2080 | rate_control_rate_init(sta, local); |
2072 | 2081 | ||
2073 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2082 | if (elems.wmm_param) { |
2074 | sta->flags |= WLAN_STA_WME; | 2083 | set_sta_flags(sta, WLAN_STA_WME); |
2075 | rcu_read_unlock(); | 2084 | rcu_read_unlock(); |
2076 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2085 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2077 | elems.wmm_param_len); | 2086 | elems.wmm_param_len); |
@@ -2656,9 +2665,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2656 | 2665 | ||
2657 | bss->timestamp = beacon_timestamp; | 2666 | bss->timestamp = beacon_timestamp; |
2658 | bss->last_update = jiffies; | 2667 | bss->last_update = jiffies; |
2659 | bss->rssi = rx_status->ssi; | ||
2660 | bss->signal = rx_status->signal; | 2668 | bss->signal = rx_status->signal; |
2661 | bss->noise = rx_status->noise; | 2669 | bss->noise = rx_status->noise; |
2670 | bss->qual = rx_status->qual; | ||
2662 | if (!beacon && !bss->probe_resp) | 2671 | if (!beacon && !bss->probe_resp) |
2663 | bss->probe_resp = true; | 2672 | bss->probe_resp = true; |
2664 | 2673 | ||
@@ -2853,10 +2862,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2853 | 2862 | ||
2854 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | 2863 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); |
2855 | 2864 | ||
2856 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2865 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2857 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2866 | elems.wmm_param_len); |
2858 | elems.wmm_param_len); | ||
2859 | } | ||
2860 | 2867 | ||
2861 | /* Do not send changes to driver if we are scanning. This removes | 2868 | /* Do not send changes to driver if we are scanning. This removes |
2862 | * requirement that driver's bss_info_changed function needs to be | 2869 | * requirement that driver's bss_info_changed function needs to be |
@@ -3456,9 +3463,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3456 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) | 3463 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) |
3457 | continue; | 3464 | continue; |
3458 | 3465 | ||
3459 | if (!selected || top_rssi < bss->rssi) { | 3466 | if (!selected || top_rssi < bss->signal) { |
3460 | selected = bss; | 3467 | selected = bss; |
3461 | top_rssi = bss->rssi; | 3468 | top_rssi = bss->signal; |
3462 | } | 3469 | } |
3463 | } | 3470 | } |
3464 | if (selected) | 3471 | if (selected) |
@@ -4089,8 +4096,8 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4089 | 4096 | ||
4090 | memset(&iwe, 0, sizeof(iwe)); | 4097 | memset(&iwe, 0, sizeof(iwe)); |
4091 | iwe.cmd = IWEVQUAL; | 4098 | iwe.cmd = IWEVQUAL; |
4092 | iwe.u.qual.qual = bss->signal; | 4099 | iwe.u.qual.qual = bss->qual; |
4093 | iwe.u.qual.level = bss->rssi; | 4100 | iwe.u.qual.level = bss->signal; |
4094 | iwe.u.qual.noise = bss->noise; | 4101 | iwe.u.qual.noise = bss->noise; |
4095 | iwe.u.qual.updated = local->wstats_flags; | 4102 | iwe.u.qual.updated = local->wstats_flags; |
4096 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4103 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
@@ -4266,7 +4273,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4266 | if (!sta) | 4273 | if (!sta) |
4267 | return NULL; | 4274 | return NULL; |
4268 | 4275 | ||
4269 | sta->flags |= WLAN_STA_AUTHORIZED; | 4276 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
4270 | 4277 | ||
4271 | sta->supp_rates[local->hw.conf.channel->band] = | 4278 | sta->supp_rates[local->hw.conf.channel->band] = |
4272 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | 4279 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9b5a3cbec265..fa68305fd59e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -77,6 +77,134 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | static int | ||
81 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, | ||
82 | struct ieee80211_rx_status *status) | ||
83 | { | ||
84 | int len; | ||
85 | |||
86 | /* always present fields */ | ||
87 | len = sizeof(struct ieee80211_radiotap_header) + 9; | ||
88 | |||
89 | if (status->flag & RX_FLAG_TSFT) | ||
90 | len += 8; | ||
91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB || | ||
92 | local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
93 | len += 1; | ||
94 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
95 | len += 1; | ||
96 | |||
97 | if (len & 1) /* padding for RX_FLAGS if necessary */ | ||
98 | len++; | ||
99 | |||
100 | /* make sure radiotap starts at a naturally aligned address */ | ||
101 | if (len % 8) | ||
102 | len = roundup(len, 8); | ||
103 | |||
104 | return len; | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * ieee80211_add_rx_radiotap_header - add radiotap header | ||
109 | * | ||
110 | * add a radiotap header containing all the fields which the hardware provided. | ||
111 | */ | ||
112 | static void | ||
113 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | ||
114 | struct sk_buff *skb, | ||
115 | struct ieee80211_rx_status *status, | ||
116 | struct ieee80211_rate *rate, | ||
117 | int rtap_len) | ||
118 | { | ||
119 | struct ieee80211_radiotap_header *rthdr; | ||
120 | unsigned char *pos; | ||
121 | |||
122 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | ||
123 | memset(rthdr, 0, rtap_len); | ||
124 | |||
125 | /* radiotap header, set always present flags */ | ||
126 | rthdr->it_present = | ||
127 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
128 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
129 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
130 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | ||
131 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
132 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
133 | |||
134 | pos = (unsigned char *)(rthdr+1); | ||
135 | |||
136 | /* the order of the following fields is important */ | ||
137 | |||
138 | /* IEEE80211_RADIOTAP_TSFT */ | ||
139 | if (status->flag & RX_FLAG_TSFT) { | ||
140 | *(__le64 *)pos = cpu_to_le64(status->mactime); | ||
141 | rthdr->it_present |= | ||
142 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
143 | pos += 8; | ||
144 | } | ||
145 | |||
146 | /* IEEE80211_RADIOTAP_FLAGS */ | ||
147 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
148 | *pos |= IEEE80211_RADIOTAP_F_FCS; | ||
149 | pos++; | ||
150 | |||
151 | /* IEEE80211_RADIOTAP_RATE */ | ||
152 | *pos = rate->bitrate / 5; | ||
153 | pos++; | ||
154 | |||
155 | /* IEEE80211_RADIOTAP_CHANNEL */ | ||
156 | *(__le16 *)pos = cpu_to_le16(status->freq); | ||
157 | pos += 2; | ||
158 | if (status->band == IEEE80211_BAND_5GHZ) | ||
159 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
160 | IEEE80211_CHAN_5GHZ); | ||
161 | else | ||
162 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
163 | IEEE80211_CHAN_2GHZ); | ||
164 | pos += 2; | ||
165 | |||
166 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | ||
167 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
168 | *pos = status->signal; | ||
169 | rthdr->it_present |= | ||
170 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | ||
171 | pos++; | ||
172 | } | ||
173 | |||
174 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ | ||
175 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | ||
176 | *pos = status->noise; | ||
177 | rthdr->it_present |= | ||
178 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); | ||
179 | pos++; | ||
180 | } | ||
181 | |||
182 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ | ||
183 | |||
184 | /* IEEE80211_RADIOTAP_ANTENNA */ | ||
185 | *pos = status->antenna; | ||
186 | pos++; | ||
187 | |||
188 | /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */ | ||
189 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB) { | ||
190 | *pos = status->signal; | ||
191 | rthdr->it_present |= | ||
192 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL); | ||
193 | pos++; | ||
194 | } | ||
195 | |||
196 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ | ||
197 | |||
198 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | ||
199 | /* ensure 2 byte alignment for the 2 byte field as required */ | ||
200 | if ((pos - (unsigned char *)rthdr) & 1) | ||
201 | pos++; | ||
202 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
203 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
204 | *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
205 | pos += 2; | ||
206 | } | ||
207 | |||
80 | /* | 208 | /* |
81 | * This function copies a received frame to all monitor interfaces and | 209 | * This function copies a received frame to all monitor interfaces and |
82 | * returns a cleaned-up SKB that no longer includes the FCS nor the | 210 | * returns a cleaned-up SKB that no longer includes the FCS nor the |
@@ -89,17 +217,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
89 | { | 217 | { |
90 | struct ieee80211_sub_if_data *sdata; | 218 | struct ieee80211_sub_if_data *sdata; |
91 | int needed_headroom = 0; | 219 | int needed_headroom = 0; |
92 | struct ieee80211_radiotap_header *rthdr; | ||
93 | __le64 *rttsft = NULL; | ||
94 | struct ieee80211_rtap_fixed_data { | ||
95 | u8 flags; | ||
96 | u8 rate; | ||
97 | __le16 chan_freq; | ||
98 | __le16 chan_flags; | ||
99 | u8 antsignal; | ||
100 | u8 padding_for_rxflags; | ||
101 | __le16 rx_flags; | ||
102 | } __attribute__ ((packed)) *rtfixed; | ||
103 | struct sk_buff *skb, *skb2; | 220 | struct sk_buff *skb, *skb2; |
104 | struct net_device *prev_dev = NULL; | 221 | struct net_device *prev_dev = NULL; |
105 | int present_fcs_len = 0; | 222 | int present_fcs_len = 0; |
@@ -116,8 +233,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
116 | if (status->flag & RX_FLAG_RADIOTAP) | 233 | if (status->flag & RX_FLAG_RADIOTAP) |
117 | rtap_len = ieee80211_get_radiotap_len(origskb->data); | 234 | rtap_len = ieee80211_get_radiotap_len(origskb->data); |
118 | else | 235 | else |
119 | /* room for radiotap header, always present fields and TSFT */ | 236 | /* room for the radiotap header based on driver features */ |
120 | needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8; | 237 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
121 | 238 | ||
122 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 239 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
123 | present_fcs_len = FCS_LEN; | 240 | present_fcs_len = FCS_LEN; |
@@ -163,55 +280,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
163 | } | 280 | } |
164 | 281 | ||
165 | /* if necessary, prepend radiotap information */ | 282 | /* if necessary, prepend radiotap information */ |
166 | if (!(status->flag & RX_FLAG_RADIOTAP)) { | 283 | if (!(status->flag & RX_FLAG_RADIOTAP)) |
167 | rtfixed = (void *) skb_push(skb, sizeof(*rtfixed)); | 284 | ieee80211_add_rx_radiotap_header(local, skb, status, rate, |
168 | rtap_len = sizeof(*rthdr) + sizeof(*rtfixed); | 285 | needed_headroom); |
169 | if (status->flag & RX_FLAG_TSFT) { | ||
170 | rttsft = (void *) skb_push(skb, sizeof(*rttsft)); | ||
171 | rtap_len += 8; | ||
172 | } | ||
173 | rthdr = (void *) skb_push(skb, sizeof(*rthdr)); | ||
174 | memset(rthdr, 0, sizeof(*rthdr)); | ||
175 | memset(rtfixed, 0, sizeof(*rtfixed)); | ||
176 | rthdr->it_present = | ||
177 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
178 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
179 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
180 | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | | ||
181 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
182 | rtfixed->flags = 0; | ||
183 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
184 | rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS; | ||
185 | |||
186 | if (rttsft) { | ||
187 | *rttsft = cpu_to_le64(status->mactime); | ||
188 | rthdr->it_present |= | ||
189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
190 | } | ||
191 | |||
192 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
193 | rtfixed->rx_flags = 0; | ||
194 | if (status->flag & | ||
195 | (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
196 | rtfixed->rx_flags |= | ||
197 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
198 | |||
199 | rtfixed->rate = rate->bitrate / 5; | ||
200 | |||
201 | rtfixed->chan_freq = cpu_to_le16(status->freq); | ||
202 | |||
203 | if (status->band == IEEE80211_BAND_5GHZ) | ||
204 | rtfixed->chan_flags = | ||
205 | cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
206 | IEEE80211_CHAN_5GHZ); | ||
207 | else | ||
208 | rtfixed->chan_flags = | ||
209 | cpu_to_le16(IEEE80211_CHAN_DYN | | ||
210 | IEEE80211_CHAN_2GHZ); | ||
211 | |||
212 | rtfixed->antsignal = status->ssi; | ||
213 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
214 | } | ||
215 | 286 | ||
216 | skb_reset_mac_header(skb); | 287 | skb_reset_mac_header(skb); |
217 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 288 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -479,7 +550,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
479 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 550 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && |
480 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && | 551 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && |
481 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 552 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
482 | (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { | 553 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
483 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && | 554 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && |
484 | !(rx->fc & IEEE80211_FCTL_TODS) && | 555 | !(rx->fc & IEEE80211_FCTL_TODS) && |
485 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) | 556 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) |
@@ -630,8 +701,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
630 | 701 | ||
631 | if (sdata->bss) | 702 | if (sdata->bss) |
632 | atomic_inc(&sdata->bss->num_sta_ps); | 703 | atomic_inc(&sdata->bss->num_sta_ps); |
633 | sta->flags |= WLAN_STA_PS; | 704 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
634 | sta->flags &= ~WLAN_STA_PSPOLL; | ||
635 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 705 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
636 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 706 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
637 | dev->name, print_mac(mac, sta->addr), sta->aid); | 707 | dev->name, print_mac(mac, sta->addr), sta->aid); |
@@ -652,7 +722,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
652 | if (sdata->bss) | 722 | if (sdata->bss) |
653 | atomic_dec(&sdata->bss->num_sta_ps); | 723 | atomic_dec(&sdata->bss->num_sta_ps); |
654 | 724 | ||
655 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); | 725 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
656 | 726 | ||
657 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 727 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
658 | sta_info_clear_tim_bit(sta); | 728 | sta_info_clear_tim_bit(sta); |
@@ -720,16 +790,17 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
720 | 790 | ||
721 | sta->rx_fragments++; | 791 | sta->rx_fragments++; |
722 | sta->rx_bytes += rx->skb->len; | 792 | sta->rx_bytes += rx->skb->len; |
723 | sta->last_rssi = rx->status->ssi; | ||
724 | sta->last_signal = rx->status->signal; | 793 | sta->last_signal = rx->status->signal; |
794 | sta->last_qual = rx->status->qual; | ||
725 | sta->last_noise = rx->status->noise; | 795 | sta->last_noise = rx->status->noise; |
726 | 796 | ||
727 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { | 797 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { |
728 | /* Change STA power saving mode only in the end of a frame | 798 | /* Change STA power saving mode only in the end of a frame |
729 | * exchange sequence */ | 799 | * exchange sequence */ |
730 | if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) | 800 | if (test_sta_flags(sta, WLAN_STA_PS) && |
801 | !(rx->fc & IEEE80211_FCTL_PM)) | ||
731 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); | 802 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); |
732 | else if (!(sta->flags & WLAN_STA_PS) && | 803 | else if (!test_sta_flags(sta, WLAN_STA_PS) && |
733 | (rx->fc & IEEE80211_FCTL_PM)) | 804 | (rx->fc & IEEE80211_FCTL_PM)) |
734 | ap_sta_ps_start(dev, sta); | 805 | ap_sta_ps_start(dev, sta); |
735 | } | 806 | } |
@@ -983,7 +1054,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
983 | * Tell TX path to send one frame even though the STA may | 1054 | * Tell TX path to send one frame even though the STA may |
984 | * still remain is PS mode after this frame exchange. | 1055 | * still remain is PS mode after this frame exchange. |
985 | */ | 1056 | */ |
986 | rx->sta->flags |= WLAN_STA_PSPOLL; | 1057 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
987 | 1058 | ||
988 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1059 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
989 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1060 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", |
@@ -1046,7 +1117,8 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | |||
1046 | static int | 1117 | static int |
1047 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1118 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1048 | { | 1119 | { |
1049 | if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { | 1120 | if (unlikely(!rx->sta || |
1121 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) { | ||
1050 | #ifdef CONFIG_MAC80211_DEBUG | 1122 | #ifdef CONFIG_MAC80211_DEBUG |
1051 | if (net_ratelimit()) | 1123 | if (net_ratelimit()) |
1052 | printk(KERN_DEBUG "%s: dropped frame " | 1124 | printk(KERN_DEBUG "%s: dropped frame " |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 631943e8af8b..baf5e4746884 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -202,14 +202,12 @@ void sta_info_destroy(struct sta_info *sta) | |||
202 | dev_kfree_skb_any(skb); | 202 | dev_kfree_skb_any(skb); |
203 | 203 | ||
204 | for (i = 0; i < STA_TID_NUM; i++) { | 204 | for (i = 0; i < STA_TID_NUM; i++) { |
205 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 205 | spin_lock_bh(&sta->lock); |
206 | if (sta->ampdu_mlme.tid_rx[i]) | 206 | if (sta->ampdu_mlme.tid_rx[i]) |
207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); | 207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); |
208 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | ||
209 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
210 | if (sta->ampdu_mlme.tid_tx[i]) | 208 | if (sta->ampdu_mlme.tid_tx[i]) |
211 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); | 209 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); |
212 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 210 | spin_unlock_bh(&sta->lock); |
213 | } | 211 | } |
214 | 212 | ||
215 | __sta_info_free(local, sta); | 213 | __sta_info_free(local, sta); |
@@ -236,6 +234,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
236 | if (!sta) | 234 | if (!sta) |
237 | return NULL; | 235 | return NULL; |
238 | 236 | ||
237 | spin_lock_init(&sta->lock); | ||
238 | |||
239 | memcpy(sta->addr, addr, ETH_ALEN); | 239 | memcpy(sta->addr, addr, ETH_ALEN); |
240 | sta->local = local; | 240 | sta->local = local; |
241 | sta->sdata = sdata; | 241 | sta->sdata = sdata; |
@@ -249,8 +249,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
249 | return NULL; | 249 | return NULL; |
250 | } | 250 | } |
251 | 251 | ||
252 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | ||
253 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
254 | for (i = 0; i < STA_TID_NUM; i++) { | 252 | for (i = 0; i < STA_TID_NUM; i++) { |
255 | /* timer_to_tid must be initialized with identity mapping to | 253 | /* timer_to_tid must be initialized with identity mapping to |
256 | * enable session_timer's data differentiation. refer to | 254 | * enable session_timer's data differentiation. refer to |
@@ -276,7 +274,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
276 | 274 | ||
277 | #ifdef CONFIG_MAC80211_MESH | 275 | #ifdef CONFIG_MAC80211_MESH |
278 | sta->plink_state = PLINK_LISTEN; | 276 | sta->plink_state = PLINK_LISTEN; |
279 | spin_lock_init(&sta->plink_lock); | ||
280 | init_timer(&sta->plink_timer); | 277 | init_timer(&sta->plink_timer); |
281 | #endif | 278 | #endif |
282 | 279 | ||
@@ -437,8 +434,7 @@ void __sta_info_unlink(struct sta_info **sta) | |||
437 | 434 | ||
438 | list_del(&(*sta)->list); | 435 | list_del(&(*sta)->list); |
439 | 436 | ||
440 | if ((*sta)->flags & WLAN_STA_PS) { | 437 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
441 | (*sta)->flags &= ~WLAN_STA_PS; | ||
442 | if (sdata->bss) | 438 | if (sdata->bss) |
443 | atomic_dec(&sdata->bss->num_sta_ps); | 439 | atomic_dec(&sdata->bss->num_sta_ps); |
444 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 440 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index f8c95bc9659c..e89cc1655547 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -129,23 +129,19 @@ enum plink_state { | |||
129 | * | 129 | * |
130 | * @tid_state_rx: TID's state in Rx session state machine. | 130 | * @tid_state_rx: TID's state in Rx session state machine. |
131 | * @tid_rx: aggregation info for Rx per TID | 131 | * @tid_rx: aggregation info for Rx per TID |
132 | * @ampdu_rx: for locking sections in aggregation Rx flow | ||
133 | * @tid_state_tx: TID's state in Tx session state machine. | 132 | * @tid_state_tx: TID's state in Tx session state machine. |
134 | * @tid_tx: aggregation info for Tx per TID | 133 | * @tid_tx: aggregation info for Tx per TID |
135 | * @addba_req_num: number of times addBA request has been sent. | 134 | * @addba_req_num: number of times addBA request has been sent. |
136 | * @ampdu_tx: for locking sectionsi in aggregation Tx flow | ||
137 | * @dialog_token_allocator: dialog token enumerator for each new session; | 135 | * @dialog_token_allocator: dialog token enumerator for each new session; |
138 | */ | 136 | */ |
139 | struct sta_ampdu_mlme { | 137 | struct sta_ampdu_mlme { |
140 | /* rx */ | 138 | /* rx */ |
141 | u8 tid_state_rx[STA_TID_NUM]; | 139 | u8 tid_state_rx[STA_TID_NUM]; |
142 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 140 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
143 | spinlock_t ampdu_rx; | ||
144 | /* tx */ | 141 | /* tx */ |
145 | u8 tid_state_tx[STA_TID_NUM]; | 142 | u8 tid_state_tx[STA_TID_NUM]; |
146 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | 143 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; |
147 | u8 addba_req_num[STA_TID_NUM]; | 144 | u8 addba_req_num[STA_TID_NUM]; |
148 | spinlock_t ampdu_tx; | ||
149 | u8 dialog_token_allocator; | 145 | u8 dialog_token_allocator; |
150 | }; | 146 | }; |
151 | 147 | ||
@@ -177,6 +173,8 @@ struct sta_ampdu_mlme { | |||
177 | * @rx_bytes: Number of bytes received from this STA | 173 | * @rx_bytes: Number of bytes received from this STA |
178 | * @supp_rates: Bitmap of supported rates (per band) | 174 | * @supp_rates: Bitmap of supported rates (per band) |
179 | * @ht_info: HT capabilities of this STA | 175 | * @ht_info: HT capabilities of this STA |
176 | * @lock: used for locking all fields that require locking, see comments | ||
177 | * in the header file. | ||
180 | */ | 178 | */ |
181 | struct sta_info { | 179 | struct sta_info { |
182 | /* General information, mostly static */ | 180 | /* General information, mostly static */ |
@@ -187,6 +185,7 @@ struct sta_info { | |||
187 | struct ieee80211_key *key; | 185 | struct ieee80211_key *key; |
188 | struct rate_control_ref *rate_ctrl; | 186 | struct rate_control_ref *rate_ctrl; |
189 | void *rate_ctrl_priv; | 187 | void *rate_ctrl_priv; |
188 | spinlock_t lock; | ||
190 | struct ieee80211_ht_info ht_info; | 189 | struct ieee80211_ht_info ht_info; |
191 | u64 supp_rates[IEEE80211_NUM_BANDS]; | 190 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
192 | u8 addr[ETH_ALEN]; | 191 | u8 addr[ETH_ALEN]; |
@@ -199,7 +198,7 @@ struct sta_info { | |||
199 | */ | 198 | */ |
200 | u8 pin_status; | 199 | u8 pin_status; |
201 | 200 | ||
202 | /* frequently updated information, needs locking? */ | 201 | /* frequently updated information, locked with lock spinlock */ |
203 | u32 flags; | 202 | u32 flags; |
204 | 203 | ||
205 | /* | 204 | /* |
@@ -217,8 +216,8 @@ struct sta_info { | |||
217 | * from this STA */ | 216 | * from this STA */ |
218 | unsigned long rx_fragments; /* number of received MPDUs */ | 217 | unsigned long rx_fragments; /* number of received MPDUs */ |
219 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ | 218 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ |
220 | int last_rssi; /* RSSI of last received frame from this STA */ | ||
221 | int last_signal; /* signal of last received frame from this STA */ | 219 | int last_signal; /* signal of last received frame from this STA */ |
220 | int last_qual; /* qual of last received frame from this STA */ | ||
222 | int last_noise; /* noise of last received frame from this STA */ | 221 | int last_noise; /* noise of last received frame from this STA */ |
223 | /* last received seq/frag number from this STA (per RX queue) */ | 222 | /* last received seq/frag number from this STA (per RX queue) */ |
224 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 223 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; |
@@ -251,7 +250,7 @@ struct sta_info { | |||
251 | int channel_use_raw; | 250 | int channel_use_raw; |
252 | 251 | ||
253 | /* | 252 | /* |
254 | * Aggregation information, comes with own locking. | 253 | * Aggregation information, locked with lock. |
255 | */ | 254 | */ |
256 | struct sta_ampdu_mlme ampdu_mlme; | 255 | struct sta_ampdu_mlme ampdu_mlme; |
257 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ | 256 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ |
@@ -270,9 +269,6 @@ struct sta_info { | |||
270 | enum plink_state plink_state; | 269 | enum plink_state plink_state; |
271 | u32 plink_timeout; | 270 | u32 plink_timeout; |
272 | struct timer_list plink_timer; | 271 | struct timer_list plink_timer; |
273 | spinlock_t plink_lock; /* For peer_state reads / updates and other | ||
274 | updates in the structure. Ensures robust | ||
275 | transitions for the peerlink FSM */ | ||
276 | #endif | 272 | #endif |
277 | 273 | ||
278 | #ifdef CONFIG_MAC80211_DEBUGFS | 274 | #ifdef CONFIG_MAC80211_DEBUGFS |
@@ -299,6 +295,64 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta) | |||
299 | return PLINK_LISTEN; | 295 | return PLINK_LISTEN; |
300 | } | 296 | } |
301 | 297 | ||
298 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | ||
299 | { | ||
300 | spin_lock_bh(&sta->lock); | ||
301 | sta->flags |= flags; | ||
302 | spin_unlock_bh(&sta->lock); | ||
303 | } | ||
304 | |||
305 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | ||
306 | { | ||
307 | spin_lock_bh(&sta->lock); | ||
308 | sta->flags &= ~flags; | ||
309 | spin_unlock_bh(&sta->lock); | ||
310 | } | ||
311 | |||
312 | static inline void set_and_clear_sta_flags(struct sta_info *sta, | ||
313 | const u32 set, const u32 clear) | ||
314 | { | ||
315 | spin_lock_bh(&sta->lock); | ||
316 | sta->flags |= set; | ||
317 | sta->flags &= ~clear; | ||
318 | spin_unlock_bh(&sta->lock); | ||
319 | } | ||
320 | |||
321 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | ||
322 | { | ||
323 | u32 ret; | ||
324 | |||
325 | spin_lock_bh(&sta->lock); | ||
326 | ret = sta->flags & flags; | ||
327 | spin_unlock_bh(&sta->lock); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | ||
333 | const u32 flags) | ||
334 | { | ||
335 | u32 ret; | ||
336 | |||
337 | spin_lock_bh(&sta->lock); | ||
338 | ret = sta->flags & flags; | ||
339 | sta->flags &= ~flags; | ||
340 | spin_unlock_bh(&sta->lock); | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
346 | { | ||
347 | u32 ret; | ||
348 | |||
349 | spin_lock_bh(&sta->lock); | ||
350 | ret = sta->flags; | ||
351 | spin_unlock_bh(&sta->lock); | ||
352 | |||
353 | return ret; | ||
354 | } | ||
355 | |||
302 | 356 | ||
303 | /* Maximum number of concurrently registered stations */ | 357 | /* Maximum number of concurrently registered stations */ |
304 | #define MAX_STA_COUNT 2007 | 358 | #define MAX_STA_COUNT 2007 |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 09093da24af6..a7c3febc5a45 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -8,23 +8,22 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/bitops.h> | ||
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <asm/unaligned.h> | ||
13 | 15 | ||
14 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
15 | #include "key.h" | 17 | #include "key.h" |
16 | #include "tkip.h" | 18 | #include "tkip.h" |
17 | #include "wep.h" | 19 | #include "wep.h" |
18 | 20 | ||
19 | |||
20 | /* TKIP key mixing functions */ | ||
21 | |||
22 | |||
23 | #define PHASE1_LOOP_COUNT 8 | 21 | #define PHASE1_LOOP_COUNT 8 |
24 | 22 | ||
25 | 23 | /* | |
26 | /* 2-byte by 2-byte subset of the full AES S-box table; second part of this | 24 | * 2-byte by 2-byte subset of the full AES S-box table; second part of this |
27 | * table is identical to first part but byte-swapped */ | 25 | * table is identical to first part but byte-swapped |
26 | */ | ||
28 | static const u16 tkip_sbox[256] = | 27 | static const u16 tkip_sbox[256] = |
29 | { | 28 | { |
30 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | 29 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, |
@@ -61,53 +60,13 @@ static const u16 tkip_sbox[256] = | |||
61 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | 60 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, |
62 | }; | 61 | }; |
63 | 62 | ||
64 | 63 | static u16 tkipS(u16 val) | |
65 | static inline u16 Mk16(u8 x, u8 y) | ||
66 | { | ||
67 | return ((u16) x << 8) | (u16) y; | ||
68 | } | ||
69 | |||
70 | |||
71 | static inline u8 Hi8(u16 v) | ||
72 | { | ||
73 | return v >> 8; | ||
74 | } | ||
75 | |||
76 | |||
77 | static inline u8 Lo8(u16 v) | ||
78 | { | ||
79 | return v & 0xff; | ||
80 | } | ||
81 | |||
82 | |||
83 | static inline u16 Hi16(u32 v) | ||
84 | { | ||
85 | return v >> 16; | ||
86 | } | ||
87 | |||
88 | |||
89 | static inline u16 Lo16(u32 v) | ||
90 | { | ||
91 | return v & 0xffff; | ||
92 | } | ||
93 | |||
94 | |||
95 | static inline u16 RotR1(u16 v) | ||
96 | { | 64 | { |
97 | return (v >> 1) | ((v & 0x0001) << 15); | 65 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
98 | } | ||
99 | |||
100 | |||
101 | static inline u16 tkip_S(u16 val) | ||
102 | { | ||
103 | u16 a = tkip_sbox[Hi8(val)]; | ||
104 | |||
105 | return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); | ||
106 | } | 66 | } |
107 | 67 | ||
108 | 68 | /* | |
109 | 69 | * P1K := Phase1(TA, TK, TSC) | |
110 | /* P1K := Phase1(TA, TK, TSC) | ||
111 | * TA = transmitter address (48 bits) | 70 | * TA = transmitter address (48 bits) |
112 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) | 71 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) |
113 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 72 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
@@ -118,23 +77,22 @@ static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | |||
118 | { | 77 | { |
119 | int i, j; | 78 | int i, j; |
120 | 79 | ||
121 | p1k[0] = Lo16(tsc_IV32); | 80 | p1k[0] = tsc_IV32 & 0xFFFF; |
122 | p1k[1] = Hi16(tsc_IV32); | 81 | p1k[1] = tsc_IV32 >> 16; |
123 | p1k[2] = Mk16(ta[1], ta[0]); | 82 | p1k[2] = get_unaligned_le16(ta + 0); |
124 | p1k[3] = Mk16(ta[3], ta[2]); | 83 | p1k[3] = get_unaligned_le16(ta + 2); |
125 | p1k[4] = Mk16(ta[5], ta[4]); | 84 | p1k[4] = get_unaligned_le16(ta + 4); |
126 | 85 | ||
127 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | 86 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { |
128 | j = 2 * (i & 1); | 87 | j = 2 * (i & 1); |
129 | p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); | 88 | p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j)); |
130 | p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); | 89 | p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j)); |
131 | p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); | 90 | p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j)); |
132 | p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); | 91 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
133 | p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; | 92 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
134 | } | 93 | } |
135 | } | 94 | } |
136 | 95 | ||
137 | |||
138 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 96 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, |
139 | u8 *rc4key) | 97 | u8 *rc4key) |
140 | { | 98 | { |
@@ -148,31 +106,29 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
148 | ppk[4] = p1k[4]; | 106 | ppk[4] = p1k[4]; |
149 | ppk[5] = p1k[4] + tsc_IV16; | 107 | ppk[5] = p1k[4] + tsc_IV16; |
150 | 108 | ||
151 | ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); | 109 | ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0)); |
152 | ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); | 110 | ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2)); |
153 | ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); | 111 | ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4)); |
154 | ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); | 112 | ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6)); |
155 | ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); | 113 | ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8)); |
156 | ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); | 114 | ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10)); |
157 | ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); | 115 | ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1); |
158 | ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); | 116 | ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1); |
159 | ppk[2] += RotR1(ppk[1]); | 117 | ppk[2] += ror16(ppk[1], 1); |
160 | ppk[3] += RotR1(ppk[2]); | 118 | ppk[3] += ror16(ppk[2], 1); |
161 | ppk[4] += RotR1(ppk[3]); | 119 | ppk[4] += ror16(ppk[3], 1); |
162 | ppk[5] += RotR1(ppk[4]); | 120 | ppk[5] += ror16(ppk[4], 1); |
163 | 121 | ||
164 | rc4key[0] = Hi8(tsc_IV16); | 122 | rc4key[0] = tsc_IV16 >> 8; |
165 | rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; | 123 | rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f; |
166 | rc4key[2] = Lo8(tsc_IV16); | 124 | rc4key[2] = tsc_IV16 & 0xFF; |
167 | rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); | 125 | rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
168 | 126 | ||
169 | for (i = 0; i < 6; i++) { | 127 | rc4key += 4; |
170 | rc4key[4 + 2 * i] = Lo8(ppk[i]); | 128 | for (i = 0; i < 6; i++) |
171 | rc4key[5 + 2 * i] = Hi8(ppk[i]); | 129 | put_unaligned_le16(ppk[i], rc4key + 2 * i); |
172 | } | ||
173 | } | 130 | } |
174 | 131 | ||
175 | |||
176 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 132 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
177 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 133 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
178 | * the packet payload). */ | 134 | * the packet payload). */ |
@@ -183,14 +139,10 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | |||
183 | *pos++ = iv1; | 139 | *pos++ = iv1; |
184 | *pos++ = iv2; | 140 | *pos++ = iv2; |
185 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 141 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
186 | *pos++ = key->u.tkip.iv32 & 0xff; | 142 | put_unaligned_le32(key->u.tkip.iv32, pos); |
187 | *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; | 143 | return pos + 4; |
188 | *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; | ||
189 | *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; | ||
190 | return pos; | ||
191 | } | 144 | } |
192 | 145 | ||
193 | |||
194 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | 146 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, |
195 | u16 *phase1key) | 147 | u16 *phase1key) |
196 | { | 148 | { |
@@ -228,10 +180,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
228 | u16 iv16; | 180 | u16 iv16; |
229 | u32 iv32; | 181 | u32 iv32; |
230 | 182 | ||
231 | iv16 = data[hdr_len] << 8; | 183 | iv16 = data[hdr_len + 2] | (data[hdr_len] << 8); |
232 | iv16 += data[hdr_len + 2]; | 184 | iv32 = get_unaligned_le32(data + hdr_len + 4); |
233 | iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | | ||
234 | (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); | ||
235 | 185 | ||
236 | #ifdef CONFIG_TKIP_DEBUG | 186 | #ifdef CONFIG_TKIP_DEBUG |
237 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 187 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", |
@@ -281,7 +231,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
281 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 231 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
282 | } | 232 | } |
283 | 233 | ||
284 | |||
285 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 234 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
286 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., | 235 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., |
287 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the | 236 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the |
@@ -302,7 +251,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
302 | 251 | ||
303 | iv16 = (pos[0] << 8) | pos[2]; | 252 | iv16 = (pos[0] << 8) | pos[2]; |
304 | keyid = pos[3]; | 253 | keyid = pos[3]; |
305 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | 254 | iv32 = get_unaligned_le32(pos + 4); |
306 | pos += 8; | 255 | pos += 8; |
307 | #ifdef CONFIG_TKIP_DEBUG | 256 | #ifdef CONFIG_TKIP_DEBUG |
308 | { | 257 | { |
@@ -409,5 +358,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
409 | 358 | ||
410 | return res; | 359 | return res; |
411 | } | 360 | } |
412 | |||
413 | |||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1d7dd54aacef..aecec2a72b08 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -256,7 +256,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
257 | return TX_CONTINUE; | 257 | return TX_CONTINUE; |
258 | 258 | ||
259 | sta_flags = tx->sta ? tx->sta->flags : 0; | 259 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; |
260 | 260 | ||
261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && |
@@ -391,6 +391,7 @@ static ieee80211_tx_result | |||
391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | 391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) |
392 | { | 392 | { |
393 | struct sta_info *sta = tx->sta; | 393 | struct sta_info *sta = tx->sta; |
394 | u32 staflags; | ||
394 | DECLARE_MAC_BUF(mac); | 395 | DECLARE_MAC_BUF(mac); |
395 | 396 | ||
396 | if (unlikely(!sta || | 397 | if (unlikely(!sta || |
@@ -398,8 +399,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
398 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) | 399 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) |
399 | return TX_CONTINUE; | 400 | return TX_CONTINUE; |
400 | 401 | ||
401 | if (unlikely((sta->flags & WLAN_STA_PS) && | 402 | staflags = get_sta_flags(sta); |
402 | !(sta->flags & WLAN_STA_PSPOLL))) { | 403 | |
404 | if (unlikely((staflags & WLAN_STA_PS) && | ||
405 | !(staflags & WLAN_STA_PSPOLL))) { | ||
403 | struct ieee80211_tx_packet_data *pkt_data; | 406 | struct ieee80211_tx_packet_data *pkt_data; |
404 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 407 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
405 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 408 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " |
@@ -430,13 +433,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
430 | return TX_QUEUED; | 433 | return TX_QUEUED; |
431 | } | 434 | } |
432 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 435 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
433 | else if (unlikely(sta->flags & WLAN_STA_PS)) { | 436 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { |
434 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " | 437 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " |
435 | "set -> send frame\n", tx->dev->name, | 438 | "set -> send frame\n", tx->dev->name, |
436 | print_mac(mac, sta->addr)); | 439 | print_mac(mac, sta->addr)); |
437 | } | 440 | } |
438 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 441 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
439 | sta->flags &= ~WLAN_STA_PSPOLL; | 442 | clear_sta_flags(sta, WLAN_STA_PSPOLL); |
440 | 443 | ||
441 | return TX_CONTINUE; | 444 | return TX_CONTINUE; |
442 | } | 445 | } |
@@ -697,7 +700,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
697 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 700 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
698 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 701 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
699 | tx->sdata->bss_conf.use_short_preamble && | 702 | tx->sdata->bss_conf.use_short_preamble && |
700 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | 703 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { |
701 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 704 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
702 | } | 705 | } |
703 | 706 | ||
@@ -1025,10 +1028,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1025 | 1028 | ||
1026 | if (!tx->sta) | 1029 | if (!tx->sta) |
1027 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1030 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
1028 | else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { | 1031 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
1029 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1032 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
1030 | tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT; | ||
1031 | } | ||
1032 | 1033 | ||
1033 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1034 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
1034 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { | 1035 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { |
@@ -1336,6 +1337,8 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1336 | pkt_data->ifindex = dev->ifindex; | 1337 | pkt_data->ifindex = dev->ifindex; |
1337 | 1338 | ||
1338 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 1339 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; |
1340 | /* Interfaces should always request a status report */ | ||
1341 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1339 | 1342 | ||
1340 | /* | 1343 | /* |
1341 | * fix up the pointers accounting for the radiotap | 1344 | * fix up the pointers accounting for the radiotap |
@@ -1486,12 +1489,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1486 | rcu_read_lock(); | 1489 | rcu_read_lock(); |
1487 | sta = sta_info_get(local, hdr.addr1); | 1490 | sta = sta_info_get(local, hdr.addr1); |
1488 | if (sta) | 1491 | if (sta) |
1489 | sta_flags = sta->flags; | 1492 | sta_flags = get_sta_flags(sta); |
1490 | rcu_read_unlock(); | 1493 | rcu_read_unlock(); |
1491 | } | 1494 | } |
1492 | 1495 | ||
1493 | /* receiver is QoS enabled, use a QoS type frame */ | 1496 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1494 | if (sta_flags & WLAN_STA_WME) { | 1497 | if (sta_flags & WLAN_STA_WME && local->hw.queues >= 4) { |
1495 | fc |= IEEE80211_STYPE_QOS_DATA; | 1498 | fc |= IEEE80211_STYPE_QOS_DATA; |
1496 | hdrlen += 2; | 1499 | hdrlen += 2; |
1497 | } | 1500 | } |
@@ -1617,6 +1620,9 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1617 | if (ethertype == ETH_P_PAE) | 1620 | if (ethertype == ETH_P_PAE) |
1618 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | 1621 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; |
1619 | 1622 | ||
1623 | /* Interfaces should always request a status report */ | ||
1624 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1625 | |||
1620 | skb->dev = local->mdev; | 1626 | skb->dev = local->mdev; |
1621 | dev->stats.tx_packets++; | 1627 | dev->stats.tx_packets++; |
1622 | dev->stats.tx_bytes += skb->len; | 1628 | dev->stats.tx_bytes += skb->len; |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 76e1de1dc735..6a342a9a40cd 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -169,14 +169,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
169 | range->num_encoding_sizes = 2; | 169 | range->num_encoding_sizes = 2; |
170 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; | 170 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; |
171 | 171 | ||
172 | range->max_qual.qual = local->hw.max_signal; | 172 | if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC || |
173 | range->max_qual.level = local->hw.max_rssi; | 173 | local->hw.flags & IEEE80211_HW_SIGNAL_DB) |
174 | range->max_qual.noise = local->hw.max_noise; | 174 | range->max_qual.level = local->hw.max_signal; |
175 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
176 | range->max_qual.level = -110; | ||
177 | else | ||
178 | range->max_qual.level = 0; | ||
179 | |||
180 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
181 | range->max_qual.noise = -110; | ||
182 | else | ||
183 | range->max_qual.noise = 0; | ||
184 | |||
185 | range->max_qual.qual = 100; | ||
175 | range->max_qual.updated = local->wstats_flags; | 186 | range->max_qual.updated = local->wstats_flags; |
176 | 187 | ||
177 | range->avg_qual.qual = local->hw.max_signal/2; | 188 | range->avg_qual.qual = 50; |
178 | range->avg_qual.level = 0; | 189 | /* not always true but better than nothing */ |
179 | range->avg_qual.noise = 0; | 190 | range->avg_qual.level = range->max_qual.level / 2; |
191 | range->avg_qual.noise = range->max_qual.noise / 2; | ||
180 | range->avg_qual.updated = local->wstats_flags; | 192 | range->avg_qual.updated = local->wstats_flags; |
181 | 193 | ||
182 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 194 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
@@ -996,8 +1008,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev | |||
996 | wstats->qual.noise = 0; | 1008 | wstats->qual.noise = 0; |
997 | wstats->qual.updated = IW_QUAL_ALL_INVALID; | 1009 | wstats->qual.updated = IW_QUAL_ALL_INVALID; |
998 | } else { | 1010 | } else { |
999 | wstats->qual.level = sta->last_rssi; | 1011 | wstats->qual.level = sta->last_signal; |
1000 | wstats->qual.qual = sta->last_signal; | 1012 | wstats->qual.qual = sta->last_qual; |
1001 | wstats->qual.noise = sta->last_noise; | 1013 | wstats->qual.noise = sta->last_noise; |
1002 | wstats->qual.updated = local->wstats_flags; | 1014 | wstats->qual.updated = local->wstats_flags; |
1003 | } | 1015 | } |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 80afacdae46c..f1da0b93bc56 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -143,8 +143,11 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv) | |||
143 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | 143 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, |
144 | char *newname) | 144 | char *newname) |
145 | { | 145 | { |
146 | struct cfg80211_registered_device *drv; | ||
146 | int idx, taken = -1, result, digits; | 147 | int idx, taken = -1, result, digits; |
147 | 148 | ||
149 | mutex_lock(&cfg80211_drv_mutex); | ||
150 | |||
148 | /* prohibit calling the thing phy%d when %d is not its number */ | 151 | /* prohibit calling the thing phy%d when %d is not its number */ |
149 | sscanf(newname, PHY_NAME "%d%n", &idx, &taken); | 152 | sscanf(newname, PHY_NAME "%d%n", &idx, &taken); |
150 | if (taken == strlen(newname) && idx != rdev->idx) { | 153 | if (taken == strlen(newname) && idx != rdev->idx) { |
@@ -156,14 +159,30 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
156 | * deny the name if it is phy<idx> where <idx> is printed | 159 | * deny the name if it is phy<idx> where <idx> is printed |
157 | * without leading zeroes. taken == strlen(newname) here | 160 | * without leading zeroes. taken == strlen(newname) here |
158 | */ | 161 | */ |
162 | result = -EINVAL; | ||
159 | if (taken == strlen(PHY_NAME) + digits) | 163 | if (taken == strlen(PHY_NAME) + digits) |
160 | return -EINVAL; | 164 | goto out_unlock; |
165 | } | ||
166 | |||
167 | |||
168 | /* Ignore nop renames */ | ||
169 | result = 0; | ||
170 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) | ||
171 | goto out_unlock; | ||
172 | |||
173 | /* Ensure another device does not already have this name. */ | ||
174 | list_for_each_entry(drv, &cfg80211_drv_list, list) { | ||
175 | result = -EINVAL; | ||
176 | if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0) | ||
177 | goto out_unlock; | ||
161 | } | 178 | } |
162 | 179 | ||
163 | /* this will check for collisions */ | 180 | /* this will only check for collisions in sysfs |
181 | * which is not even always compiled in. | ||
182 | */ | ||
164 | result = device_rename(&rdev->wiphy.dev, newname); | 183 | result = device_rename(&rdev->wiphy.dev, newname); |
165 | if (result) | 184 | if (result) |
166 | return result; | 185 | goto out_unlock; |
167 | 186 | ||
168 | if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, | 187 | if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, |
169 | rdev->wiphy.debugfsdir, | 188 | rdev->wiphy.debugfsdir, |
@@ -172,9 +191,13 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
172 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", | 191 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", |
173 | newname); | 192 | newname); |
174 | 193 | ||
175 | nl80211_notify_dev_rename(rdev); | 194 | result = 0; |
195 | out_unlock: | ||
196 | mutex_unlock(&cfg80211_drv_mutex); | ||
197 | if (result == 0) | ||
198 | nl80211_notify_dev_rename(rdev); | ||
176 | 199 | ||
177 | return 0; | 200 | return result; |
178 | } | 201 | } |
179 | 202 | ||
180 | /* exported functions */ | 203 | /* exported functions */ |
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 28fbd0b0b568..f591871a7b4f 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
@@ -59,23 +59,21 @@ int ieee80211_radiotap_iterator_init( | |||
59 | return -EINVAL; | 59 | return -EINVAL; |
60 | 60 | ||
61 | /* sanity check for allowed length and radiotap length field */ | 61 | /* sanity check for allowed length and radiotap length field */ |
62 | if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len))) | 62 | if (max_length < get_unaligned_le16(&radiotap_header->it_len)) |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | 64 | ||
65 | iterator->rtheader = radiotap_header; | 65 | iterator->rtheader = radiotap_header; |
66 | iterator->max_length = le16_to_cpu(get_unaligned( | 66 | iterator->max_length = get_unaligned_le16(&radiotap_header->it_len); |
67 | &radiotap_header->it_len)); | ||
68 | iterator->arg_index = 0; | 67 | iterator->arg_index = 0; |
69 | iterator->bitmap_shifter = le32_to_cpu(get_unaligned( | 68 | iterator->bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); |
70 | &radiotap_header->it_present)); | ||
71 | iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); | 69 | iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); |
72 | iterator->this_arg = NULL; | 70 | iterator->this_arg = NULL; |
73 | 71 | ||
74 | /* find payload start allowing for extended bitmap(s) */ | 72 | /* find payload start allowing for extended bitmap(s) */ |
75 | 73 | ||
76 | if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { | 74 | if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { |
77 | while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) & | 75 | while (get_unaligned_le32(iterator->arg) & |
78 | (1<<IEEE80211_RADIOTAP_EXT)) { | 76 | (1 << IEEE80211_RADIOTAP_EXT)) { |
79 | iterator->arg += sizeof(u32); | 77 | iterator->arg += sizeof(u32); |
80 | 78 | ||
81 | /* | 79 | /* |
@@ -241,8 +239,8 @@ int ieee80211_radiotap_iterator_next( | |||
241 | if (iterator->bitmap_shifter & 1) { | 239 | if (iterator->bitmap_shifter & 1) { |
242 | /* b31 was set, there is more */ | 240 | /* b31 was set, there is more */ |
243 | /* move to next u32 bitmap */ | 241 | /* move to next u32 bitmap */ |
244 | iterator->bitmap_shifter = le32_to_cpu( | 242 | iterator->bitmap_shifter = |
245 | get_unaligned(iterator->next_bitmap)); | 243 | get_unaligned_le32(iterator->next_bitmap); |
246 | iterator->next_bitmap++; | 244 | iterator->next_bitmap++; |
247 | } else | 245 | } else |
248 | /* no more bitmaps: end */ | 246 | /* no more bitmaps: end */ |