aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r--drivers/net/wireless/ath5k/base.c174
1 files changed, 112 insertions, 62 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index a533ed60bb4d..bd2c580d1f19 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -232,13 +232,14 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
232 int mc_count, struct dev_mc_list *mclist); 232 int mc_count, struct dev_mc_list *mclist);
233static int ath5k_set_key(struct ieee80211_hw *hw, 233static int ath5k_set_key(struct ieee80211_hw *hw,
234 enum set_key_cmd cmd, 234 enum set_key_cmd cmd,
235 const u8 *local_addr, const u8 *addr, 235 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
236 struct ieee80211_key_conf *key); 236 struct ieee80211_key_conf *key);
237static int ath5k_get_stats(struct ieee80211_hw *hw, 237static int ath5k_get_stats(struct ieee80211_hw *hw,
238 struct ieee80211_low_level_stats *stats); 238 struct ieee80211_low_level_stats *stats);
239static int ath5k_get_tx_stats(struct ieee80211_hw *hw, 239static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
240 struct ieee80211_tx_queue_stats *stats); 240 struct ieee80211_tx_queue_stats *stats);
241static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 241static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
242static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
242static void ath5k_reset_tsf(struct ieee80211_hw *hw); 243static void ath5k_reset_tsf(struct ieee80211_hw *hw);
243static int ath5k_beacon_update(struct ath5k_softc *sc, 244static int ath5k_beacon_update(struct ath5k_softc *sc,
244 struct sk_buff *skb); 245 struct sk_buff *skb);
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops = {
261 .conf_tx = NULL, 262 .conf_tx = NULL,
262 .get_tx_stats = ath5k_get_tx_stats, 263 .get_tx_stats = ath5k_get_tx_stats,
263 .get_tsf = ath5k_get_tsf, 264 .get_tsf = ath5k_get_tsf,
265 .set_tsf = ath5k_set_tsf,
264 .reset_tsf = ath5k_reset_tsf, 266 .reset_tsf = ath5k_reset_tsf,
265 .bss_info_changed = ath5k_bss_info_changed, 267 .bss_info_changed = ath5k_bss_info_changed,
266}; 268};
@@ -347,9 +349,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
347} 349}
348 350
349/* Interrupt handling */ 351/* Interrupt handling */
350static int ath5k_init(struct ath5k_softc *sc, bool is_resume); 352static int ath5k_init(struct ath5k_softc *sc);
351static int ath5k_stop_locked(struct ath5k_softc *sc); 353static int ath5k_stop_locked(struct ath5k_softc *sc);
352static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend); 354static int ath5k_stop_hw(struct ath5k_softc *sc);
353static irqreturn_t ath5k_intr(int irq, void *dev_id); 355static irqreturn_t ath5k_intr(int irq, void *dev_id);
354static void ath5k_tasklet_reset(unsigned long data); 356static void ath5k_tasklet_reset(unsigned long data);
355 357
@@ -653,8 +655,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
653 655
654 ath5k_led_off(sc); 656 ath5k_led_off(sc);
655 657
656 ath5k_stop_hw(sc, true);
657
658 free_irq(pdev->irq, sc); 658 free_irq(pdev->irq, sc);
659 pci_save_state(pdev); 659 pci_save_state(pdev);
660 pci_disable_device(pdev); 660 pci_disable_device(pdev);
@@ -689,14 +689,9 @@ ath5k_pci_resume(struct pci_dev *pdev)
689 goto err_no_irq; 689 goto err_no_irq;
690 } 690 }
691 691
692 err = ath5k_init(sc, true);
693 if (err)
694 goto err_irq;
695 ath5k_led_enable(sc); 692 ath5k_led_enable(sc);
696
697 return 0; 693 return 0;
698err_irq: 694
699 free_irq(pdev->irq, sc);
700err_no_irq: 695err_no_irq:
701 pci_disable_device(pdev); 696 pci_disable_device(pdev);
702 return err; 697 return err;
@@ -1098,6 +1093,42 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
1098* Buffers setup * 1093* Buffers setup *
1099\***************/ 1094\***************/
1100 1095
1096static
1097struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
1098{
1099 struct sk_buff *skb;
1100 unsigned int off;
1101
1102 /*
1103 * Allocate buffer with headroom_needed space for the
1104 * fake physical layer header at the start.
1105 */
1106 skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
1107
1108 if (!skb) {
1109 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1110 sc->rxbufsize + sc->cachelsz - 1);
1111 return NULL;
1112 }
1113 /*
1114 * Cache-line-align. This is important (for the
1115 * 5210 at least) as not doing so causes bogus data
1116 * in rx'd frames.
1117 */
1118 off = ((unsigned long)skb->data) % sc->cachelsz;
1119 if (off != 0)
1120 skb_reserve(skb, sc->cachelsz - off);
1121
1122 *skb_addr = pci_map_single(sc->pdev,
1123 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
1124 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
1125 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1126 dev_kfree_skb(skb);
1127 return NULL;
1128 }
1129 return skb;
1130}
1131
1101static int 1132static int
1102ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) 1133ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1103{ 1134{
@@ -1105,37 +1136,11 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1105 struct sk_buff *skb = bf->skb; 1136 struct sk_buff *skb = bf->skb;
1106 struct ath5k_desc *ds; 1137 struct ath5k_desc *ds;
1107 1138
1108 if (likely(skb == NULL)) { 1139 if (!skb) {
1109 unsigned int off; 1140 skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
1110 1141 if (!skb)
1111 /*
1112 * Allocate buffer with headroom_needed space for the
1113 * fake physical layer header at the start.
1114 */
1115 skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
1116 if (unlikely(skb == NULL)) {
1117 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1118 sc->rxbufsize + sc->cachelsz - 1);
1119 return -ENOMEM; 1142 return -ENOMEM;
1120 }
1121 /*
1122 * Cache-line-align. This is important (for the
1123 * 5210 at least) as not doing so causes bogus data
1124 * in rx'd frames.
1125 */
1126 off = ((unsigned long)skb->data) % sc->cachelsz;
1127 if (off != 0)
1128 skb_reserve(skb, sc->cachelsz - off);
1129
1130 bf->skb = skb; 1143 bf->skb = skb;
1131 bf->skbaddr = pci_map_single(sc->pdev,
1132 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
1133 if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) {
1134 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1135 dev_kfree_skb(skb);
1136 bf->skb = NULL;
1137 return -ENOMEM;
1138 }
1139 } 1144 }
1140 1145
1141 /* 1146 /*
@@ -1178,6 +1183,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1178 struct ieee80211_rate *rate; 1183 struct ieee80211_rate *rate;
1179 unsigned int mrr_rate[3], mrr_tries[3]; 1184 unsigned int mrr_rate[3], mrr_tries[3];
1180 int i, ret; 1185 int i, ret;
1186 u16 hw_rate;
1187 u16 cts_rate = 0;
1188 u16 duration = 0;
1189 u8 rc_flags;
1181 1190
1182 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; 1191 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
1183 1192
@@ -1185,11 +1194,30 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1185 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 1194 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
1186 PCI_DMA_TODEVICE); 1195 PCI_DMA_TODEVICE);
1187 1196
1197 rate = ieee80211_get_tx_rate(sc->hw, info);
1198
1188 if (info->flags & IEEE80211_TX_CTL_NO_ACK) 1199 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1189 flags |= AR5K_TXDESC_NOACK; 1200 flags |= AR5K_TXDESC_NOACK;
1190 1201
1202 rc_flags = info->control.rates[0].flags;
1203 hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
1204 rate->hw_value_short : rate->hw_value;
1205
1191 pktlen = skb->len; 1206 pktlen = skb->len;
1192 1207
1208 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
1209 flags |= AR5K_TXDESC_RTSENA;
1210 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
1211 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
1212 sc->vif, pktlen, info));
1213 }
1214 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
1215 flags |= AR5K_TXDESC_CTSENA;
1216 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
1217 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
1218 sc->vif, pktlen, info));
1219 }
1220
1193 if (info->control.hw_key) { 1221 if (info->control.hw_key) {
1194 keyidx = info->control.hw_key->hw_key_idx; 1222 keyidx = info->control.hw_key->hw_key_idx;
1195 pktlen += info->control.hw_key->icv_len; 1223 pktlen += info->control.hw_key->icv_len;
@@ -1197,8 +1225,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1197 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1225 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1198 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1226 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1199 (sc->power_level * 2), 1227 (sc->power_level * 2),
1200 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 1228 hw_rate,
1201 info->control.rates[0].count, keyidx, 0, flags, 0, 0); 1229 info->control.rates[0].count, keyidx, 0, flags,
1230 cts_rate, duration);
1202 if (ret) 1231 if (ret)
1203 goto err_unmap; 1232 goto err_unmap;
1204 1233
@@ -1664,7 +1693,8 @@ ath5k_tasklet_rx(unsigned long data)
1664{ 1693{
1665 struct ieee80211_rx_status rxs = {}; 1694 struct ieee80211_rx_status rxs = {};
1666 struct ath5k_rx_status rs = {}; 1695 struct ath5k_rx_status rs = {};
1667 struct sk_buff *skb; 1696 struct sk_buff *skb, *next_skb;
1697 dma_addr_t next_skb_addr;
1668 struct ath5k_softc *sc = (void *)data; 1698 struct ath5k_softc *sc = (void *)data;
1669 struct ath5k_buf *bf, *bf_last; 1699 struct ath5k_buf *bf, *bf_last;
1670 struct ath5k_desc *ds; 1700 struct ath5k_desc *ds;
@@ -1749,10 +1779,17 @@ ath5k_tasklet_rx(unsigned long data)
1749 goto next; 1779 goto next;
1750 } 1780 }
1751accept: 1781accept:
1782 next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
1783
1784 /*
1785 * If we can't replace bf->skb with a new skb under memory
1786 * pressure, just skip this packet
1787 */
1788 if (!next_skb)
1789 goto next;
1790
1752 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 1791 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
1753 PCI_DMA_FROMDEVICE); 1792 PCI_DMA_FROMDEVICE);
1754 bf->skb = NULL;
1755
1756 skb_put(skb, rs.rs_datalen); 1793 skb_put(skb, rs.rs_datalen);
1757 1794
1758 /* The MAC header is padded to have 32-bit boundary if the 1795 /* The MAC header is padded to have 32-bit boundary if the
@@ -1825,6 +1862,9 @@ accept:
1825 ath5k_check_ibss_tsf(sc, skb, &rxs); 1862 ath5k_check_ibss_tsf(sc, skb, &rxs);
1826 1863
1827 __ieee80211_rx(sc->hw, skb, &rxs); 1864 __ieee80211_rx(sc->hw, skb, &rxs);
1865
1866 bf->skb = next_skb;
1867 bf->skbaddr = next_skb_addr;
1828next: 1868next:
1829 list_move_tail(&bf->list, &sc->rxbuf); 1869 list_move_tail(&bf->list, &sc->rxbuf);
1830 } while (ath5k_rxbuf_setup(sc, bf) == 0); 1870 } while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -2207,18 +2247,13 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2207\********************/ 2247\********************/
2208 2248
2209static int 2249static int
2210ath5k_init(struct ath5k_softc *sc, bool is_resume) 2250ath5k_init(struct ath5k_softc *sc)
2211{ 2251{
2212 struct ath5k_hw *ah = sc->ah; 2252 struct ath5k_hw *ah = sc->ah;
2213 int ret, i; 2253 int ret, i;
2214 2254
2215 mutex_lock(&sc->lock); 2255 mutex_lock(&sc->lock);
2216 2256
2217 if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
2218 goto out_ok;
2219
2220 __clear_bit(ATH_STAT_STARTED, sc->status);
2221
2222 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); 2257 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
2223 2258
2224 /* 2259 /*
@@ -2250,15 +2285,12 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
2250 for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) 2285 for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
2251 ath5k_hw_reset_key(ah, i); 2286 ath5k_hw_reset_key(ah, i);
2252 2287
2253 __set_bit(ATH_STAT_STARTED, sc->status);
2254
2255 /* Set ack to be sent at low bit-rates */ 2288 /* Set ack to be sent at low bit-rates */
2256 ath5k_hw_set_ack_bitrate_high(ah, false); 2289 ath5k_hw_set_ack_bitrate_high(ah, false);
2257 2290
2258 mod_timer(&sc->calib_tim, round_jiffies(jiffies + 2291 mod_timer(&sc->calib_tim, round_jiffies(jiffies +
2259 msecs_to_jiffies(ath5k_calinterval * 1000))); 2292 msecs_to_jiffies(ath5k_calinterval * 1000)));
2260 2293
2261out_ok:
2262 ret = 0; 2294 ret = 0;
2263done: 2295done:
2264 mmiowb(); 2296 mmiowb();
@@ -2313,7 +2345,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
2313 * stop is preempted). 2345 * stop is preempted).
2314 */ 2346 */
2315static int 2347static int
2316ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend) 2348ath5k_stop_hw(struct ath5k_softc *sc)
2317{ 2349{
2318 int ret; 2350 int ret;
2319 2351
@@ -2344,8 +2376,6 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
2344 } 2376 }
2345 } 2377 }
2346 ath5k_txbuf_free(sc, sc->bbuf); 2378 ath5k_txbuf_free(sc, sc->bbuf);
2347 if (!is_suspend)
2348 __clear_bit(ATH_STAT_STARTED, sc->status);
2349 2379
2350 mmiowb(); 2380 mmiowb();
2351 mutex_unlock(&sc->lock); 2381 mutex_unlock(&sc->lock);
@@ -2598,6 +2628,17 @@ ath5k_init_leds(struct ath5k_softc *sc)
2598 sc->led_pin = 1; 2628 sc->led_pin = 1;
2599 sc->led_on = 1; /* active high */ 2629 sc->led_on = 1; /* active high */
2600 } 2630 }
2631 /*
2632 * Pin 3 on Foxconn chips used in Acer Aspire One (0x105b:e008) and
2633 * in emachines notebooks with AMBIT subsystem.
2634 */
2635 if (pdev->subsystem_vendor == PCI_VENDOR_ID_FOXCONN ||
2636 pdev->subsystem_vendor == PCI_VENDOR_ID_AMBIT) {
2637 __set_bit(ATH_STAT_LEDSOFT, sc->status);
2638 sc->led_pin = 3;
2639 sc->led_on = 0; /* active low */
2640 }
2641
2601 if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) 2642 if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
2602 goto out; 2643 goto out;
2603 2644
@@ -2745,12 +2786,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)
2745 2786
2746static int ath5k_start(struct ieee80211_hw *hw) 2787static int ath5k_start(struct ieee80211_hw *hw)
2747{ 2788{
2748 return ath5k_init(hw->priv, false); 2789 return ath5k_init(hw->priv);
2749} 2790}
2750 2791
2751static void ath5k_stop(struct ieee80211_hw *hw) 2792static void ath5k_stop(struct ieee80211_hw *hw)
2752{ 2793{
2753 ath5k_stop_hw(hw->priv, false); 2794 ath5k_stop_hw(hw->priv);
2754} 2795}
2755 2796
2756static int ath5k_add_interface(struct ieee80211_hw *hw, 2797static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2999,8 +3040,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
2999 3040
3000static int 3041static int
3001ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3042ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3002 const u8 *local_addr, const u8 *addr, 3043 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
3003 struct ieee80211_key_conf *key) 3044 struct ieee80211_key_conf *key)
3004{ 3045{
3005 struct ath5k_softc *sc = hw->priv; 3046 struct ath5k_softc *sc = hw->priv;
3006 int ret = 0; 3047 int ret = 0;
@@ -3023,7 +3064,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3023 3064
3024 switch (cmd) { 3065 switch (cmd) {
3025 case SET_KEY: 3066 case SET_KEY:
3026 ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr); 3067 ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
3068 sta ? sta->addr : NULL);
3027 if (ret) { 3069 if (ret) {
3028 ATH5K_ERR(sc, "can't set the key\n"); 3070 ATH5K_ERR(sc, "can't set the key\n");
3029 goto unlock; 3071 goto unlock;
@@ -3083,6 +3125,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw)
3083} 3125}
3084 3126
3085static void 3127static void
3128ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
3129{
3130 struct ath5k_softc *sc = hw->priv;
3131
3132 ath5k_hw_set_tsf64(sc->ah, tsf);
3133}
3134
3135static void
3086ath5k_reset_tsf(struct ieee80211_hw *hw) 3136ath5k_reset_tsf(struct ieee80211_hw *hw)
3087{ 3137{
3088 struct ath5k_softc *sc = hw->priv; 3138 struct ath5k_softc *sc = hw->priv;