if (!ret)
return -EIO;
- sc->sc_keytype = hk.kv_type;
return 0;
}
{
struct ath_softc *sc = hw->priv;
int hdrlen, padsize;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ /*
+ * As a temporary workaround, assign seq# here; this will likely need
+ * to be cleaned up to work better with Beacon transmission and virtual
+ * BSSes.
+ */
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ sc->seq_no += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ }
/* Add the padding after the header if this is not already done */
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
}
sc->sc_ah->ah_channels[pos].chanmode =
- (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
+ (curchan->band == IEEE80211_BAND_2GHZ) ?
+ CHANNEL_G : CHANNEL_A;
+
+ if (sc->sc_curaid && hw->conf.ht_conf.ht_supported)
+ sc->sc_ah->ah_channels[pos].chanmode =
+ ath_get_extchanmode(sc, curchan);
+
sc->sc_config.txpowlimit = 2 * conf->power_level;
/* set h/w channel */
key->hw_key_idx = key->keyidx;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ if (key->alg == ALG_TKIP)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
}
break;
case DISABLE_KEY:
ath_key_delete(sc, key);
clear_bit(key->keyidx, sc->sc_keymap);
- sc->sc_keytype = ATH9K_CIPHER_CLR;
break;
default:
ret = -EINVAL;
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
tx_status->flags &= ~ATH_TX_BAR;
}
- if (tx_status->flags)
- tx_info->status.excessive_retries = 1;
+
+ if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ /* Frame was not ACKed, but an ACK was expected */
+ tx_info->status.excessive_retries = 1;
+ }
+ } else {
+ /* Frame was ACKed */
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ }
tx_info->status.retry_count = tx_status->retries;
return sc->sc_ht_info.tx_chan_width;
}
-void ath_setup_rate(struct ath_softc *sc,
- enum wireless_mode wMode,
- enum RATE_TYPE type,
- const struct ath9k_rate_table *rt)
-{
- int i, maxrates, a = 0, b = 0;
- struct ieee80211_supported_band *band_2ghz;
- struct ieee80211_supported_band *band_5ghz;
- struct ieee80211_rate *rates_2ghz;
- struct ieee80211_rate *rates_5ghz;
-
- if ((wMode >= WIRELESS_MODE_MAX) || (type != NORMAL_RATE))
- return;
-
- band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
- band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
- rates_2ghz = sc->rates[IEEE80211_BAND_2GHZ];
- rates_5ghz = sc->rates[IEEE80211_BAND_5GHZ];
-
- if (rt->rateCount > ATH_RATE_MAX)
- maxrates = ATH_RATE_MAX;
- else
- maxrates = rt->rateCount;
-
- if ((band_2ghz->n_bitrates != 0) && (band_5ghz->n_bitrates != 0)) {
- DPRINTF(sc, ATH_DBG_CONFIG,
- "%s: Rates already setup\n", __func__);
- return;
- }
-
- for (i = 0; i < maxrates; i++) {
- switch (wMode) {
- case WIRELESS_MODE_11b:
- case WIRELESS_MODE_11g:
- rates_2ghz[a].bitrate = rt->info[i].rateKbps / 100;
- rates_2ghz[a].hw_value = rt->info[i].rateCode;
- a++;
- band_2ghz->n_bitrates = a;
- break;
- case WIRELESS_MODE_11a:
- rates_5ghz[b].bitrate = rt->info[i].rateKbps / 100;
- rates_5ghz[b].hw_value = rt->info[i].rateCode;
- b++;
- band_5ghz->n_bitrates = b;
- break;
- default:
- break;
- }
- }
-
- if (band_2ghz->n_bitrates) {
- for (i = 0; i < band_2ghz->n_bitrates; i++) {
- DPRINTF(sc, ATH_DBG_CONFIG,
- "%s: 2GHz Rate: %2dMbps, ratecode: %2d\n",
- __func__,
- rates_2ghz[i].bitrate / 10,
- rates_2ghz[i].hw_value);
- }
- } else if (band_5ghz->n_bitrates) {
- for (i = 0; i < band_5ghz->n_bitrates; i++) {
- DPRINTF(sc, ATH_DBG_CONFIG,
- "%s: 5Ghz Rate: %2dMbps, ratecode: %2d\n",
- __func__,
- rates_5ghz[i].bitrate / 10,
- rates_5ghz[i].hw_value);
- }
- }
-}
-
static int ath_detach(struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&sc->sbands[IEEE80211_BAND_2GHZ];
- if (sc->sc_ah->ah_caps.wireless_modes & ATH9K_MODE_SEL_11A) {
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
sc->sbands[IEEE80211_BAND_5GHZ].channels =
sc->channels[IEEE80211_BAND_5GHZ];
sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
{
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
+ enum ath9k_int status;
- if (pdev->irq)
+ if (pdev->irq) {
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ /* clear the ISR */
+ ath9k_hw_getisr(sc->sc_ah, &status);
+ sc->sc_invalid = 1;
free_irq(pdev->irq, sc);
+ }
ath_detach(sc);
+
pci_iounmap(pdev, sc->mem);
pci_release_region(pdev, 0);
pci_disable_device(pdev);