forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ipw2x00/ipw2200.c
This commit is contained in:
commit
e9a68707d7
@ -564,3 +564,12 @@ Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: iwlwifi disable_hw_scan module parameters
|
||||
When: 2.6.40
|
||||
Why: Hareware scan is the prefer method for iwlwifi devices for
|
||||
scanning operation. Remove software scan support for all the
|
||||
iwlwifi devices.
|
||||
|
||||
Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
|
||||
----------------------------
|
||||
|
@ -6431,7 +6431,7 @@ WL1271 WIRELESS DRIVER
|
||||
M: Luciano Coelho <luciano.coelho@nokia.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://wireless.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/wl12xx/wl1271*
|
||||
F: include/linux/wl12xx.h
|
||||
|
@ -213,7 +213,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
|
||||
{
|
||||
.name = "wl1271",
|
||||
.mmc = 3,
|
||||
.wires = 4,
|
||||
.caps = MMC_CAP_4_BIT_DATA,
|
||||
.gpio_wp = -EINVAL,
|
||||
.gpio_cd = -EINVAL,
|
||||
.nonremovable = true,
|
||||
|
@ -54,8 +54,6 @@ MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
|
||||
MODULE_FIRMWARE("ar9170.fw");
|
||||
MODULE_FIRMWARE("ar9170-1.fw");
|
||||
MODULE_FIRMWARE("ar9170-2.fw");
|
||||
|
||||
enum ar9170_requirements {
|
||||
AR9170_REQ_FW1_ONLY = 1,
|
||||
|
@ -35,7 +35,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
struct ath_ani {
|
||||
bool caldone;
|
||||
int16_t noise_floor;
|
||||
unsigned int longcal_timer;
|
||||
unsigned int shortcal_timer;
|
||||
unsigned int resetcal_timer;
|
||||
@ -103,14 +102,12 @@ enum ath_cipher {
|
||||
* @read: Register read
|
||||
* @write: Register write
|
||||
* @enable_write_buffer: Enable multiple register writes
|
||||
* @disable_write_buffer: Disable multiple register writes
|
||||
* @write_flush: Flush buffered register writes
|
||||
* @write_flush: flush buffered register writes and disable buffering
|
||||
*/
|
||||
struct ath_ops {
|
||||
unsigned int (*read)(void *, u32 reg_offset);
|
||||
void (*write)(void *, u32 val, u32 reg_offset);
|
||||
void (*enable_write_buffer)(void *);
|
||||
void (*disable_write_buffer)(void *);
|
||||
void (*write_flush) (void *);
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
@ -509,8 +510,71 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
|
||||
}
|
||||
}
|
||||
|
||||
struct ath_vif_iter_data {
|
||||
const u8 *hw_macaddr;
|
||||
u8 mask[ETH_ALEN];
|
||||
u8 active_mac[ETH_ALEN]; /* first active MAC */
|
||||
bool need_set_hw_addr;
|
||||
bool found_active;
|
||||
bool any_assoc;
|
||||
};
|
||||
|
||||
static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_vif_iter_data *iter_data = data;
|
||||
int i;
|
||||
|
||||
if (iter_data->hw_macaddr)
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
iter_data->mask[i] &=
|
||||
~(iter_data->hw_macaddr[i] ^ mac[i]);
|
||||
|
||||
if (!iter_data->found_active) {
|
||||
iter_data->found_active = true;
|
||||
memcpy(iter_data->active_mac, mac, ETH_ALEN);
|
||||
}
|
||||
|
||||
if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
|
||||
if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
|
||||
iter_data->need_set_hw_addr = false;
|
||||
|
||||
if (!iter_data->any_assoc) {
|
||||
struct ath5k_vif *avf = (void *)vif->drv_priv;
|
||||
if (avf->assoc)
|
||||
iter_data->any_assoc = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(sc->ah);
|
||||
struct ath_vif_iter_data iter_data;
|
||||
|
||||
/*
|
||||
* Use the hardware MAC address as reference, the hardware uses it
|
||||
* together with the BSSID mask when matching addresses.
|
||||
*/
|
||||
iter_data.hw_macaddr = common->macaddr;
|
||||
memset(&iter_data.mask, 0xff, ETH_ALEN);
|
||||
iter_data.found_active = false;
|
||||
iter_data.need_set_hw_addr = true;
|
||||
|
||||
if (vif)
|
||||
ath_vif_iter(&iter_data, vif->addr, vif);
|
||||
|
||||
/* Get list of all active MAC addresses */
|
||||
ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
|
||||
&iter_data);
|
||||
memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
|
||||
|
||||
if (iter_data.need_set_hw_addr && iter_data.found_active)
|
||||
ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
|
||||
|
||||
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
|
||||
}
|
||||
|
||||
static void
|
||||
ath5k_mode_setup(struct ath5k_softc *sc)
|
||||
ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
u32 rfilt;
|
||||
@ -520,7 +584,7 @@ ath5k_mode_setup(struct ath5k_softc *sc)
|
||||
ath5k_hw_set_rx_filter(ah, rfilt);
|
||||
|
||||
if (ath5k_hw_hasbssidmask(ah))
|
||||
ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
|
||||
ath5k_update_bssid_mask(sc, vif);
|
||||
|
||||
/* configure operational mode */
|
||||
ath5k_hw_set_opmode(ah, sc->opmode);
|
||||
@ -698,13 +762,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
|
||||
flags |= AR5K_TXDESC_RTSENA;
|
||||
cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
|
||||
duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
|
||||
sc->vif, pktlen, info));
|
||||
info->control.vif, pktlen, info));
|
||||
}
|
||||
if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
flags |= AR5K_TXDESC_CTSENA;
|
||||
cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
|
||||
duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
|
||||
sc->vif, pktlen, info));
|
||||
info->control.vif, pktlen, info));
|
||||
}
|
||||
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
|
||||
ieee80211_get_hdrlen_from_skb(skb), padsize,
|
||||
@ -806,10 +870,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
|
||||
list_add_tail(&bf->list, &sc->txbuf);
|
||||
}
|
||||
|
||||
/* beacon buffer */
|
||||
bf->desc = ds;
|
||||
bf->daddr = da;
|
||||
sc->bbuf = bf;
|
||||
/* beacon buffers */
|
||||
INIT_LIST_HEAD(&sc->bcbuf);
|
||||
for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
|
||||
bf->desc = ds;
|
||||
bf->daddr = da;
|
||||
list_add_tail(&bf->list, &sc->bcbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
@ -824,11 +891,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
|
||||
{
|
||||
struct ath5k_buf *bf;
|
||||
|
||||
ath5k_txbuf_free_skb(sc, sc->bbuf);
|
||||
list_for_each_entry(bf, &sc->txbuf, list)
|
||||
ath5k_txbuf_free_skb(sc, bf);
|
||||
list_for_each_entry(bf, &sc->rxbuf, list)
|
||||
ath5k_rxbuf_free_skb(sc, bf);
|
||||
list_for_each_entry(bf, &sc->bcbuf, list)
|
||||
ath5k_txbuf_free_skb(sc, bf);
|
||||
|
||||
/* Free memory associated with all descriptors */
|
||||
pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
|
||||
@ -837,7 +905,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
|
||||
|
||||
kfree(sc->bufptr);
|
||||
sc->bufptr = NULL;
|
||||
sc->bbuf = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1083,7 +1150,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
|
||||
spin_unlock_bh(&sc->rxbuflock);
|
||||
|
||||
ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
|
||||
ath5k_mode_setup(sc); /* set filters, etc. */
|
||||
ath5k_mode_setup(sc, NULL); /* set filters, etc. */
|
||||
ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
|
||||
|
||||
return 0;
|
||||
@ -1366,6 +1433,7 @@ static bool
|
||||
ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
|
||||
{
|
||||
sc->stats.rx_all_count++;
|
||||
sc->stats.rx_bytes_count += rs->rs_datalen;
|
||||
|
||||
if (unlikely(rs->rs_status)) {
|
||||
if (rs->rs_status & AR5K_RXERR_CRC)
|
||||
@ -1544,6 +1612,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
|
||||
int i;
|
||||
|
||||
sc->stats.tx_all_count++;
|
||||
sc->stats.tx_bytes_count += skb->len;
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
@ -1642,7 +1711,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
|
||||
}
|
||||
}
|
||||
spin_unlock(&txq->lock);
|
||||
if (txq->txq_len < ATH5K_TXQ_LEN_LOW)
|
||||
if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4)
|
||||
ieee80211_wake_queue(sc->hw, txq->qnum);
|
||||
}
|
||||
|
||||
@ -1750,6 +1819,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
int ret;
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
struct ath5k_vif *avf = (void *)vif->drv_priv;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (WARN_ON(!vif)) {
|
||||
@ -1766,11 +1836,11 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
|
||||
ath5k_debug_dump_skb(sc, skb, "BC ", 1);
|
||||
|
||||
ath5k_txbuf_free_skb(sc, sc->bbuf);
|
||||
sc->bbuf->skb = skb;
|
||||
ret = ath5k_beacon_setup(sc, sc->bbuf);
|
||||
ath5k_txbuf_free_skb(sc, avf->bbuf);
|
||||
avf->bbuf->skb = skb;
|
||||
ret = ath5k_beacon_setup(sc, avf->bbuf);
|
||||
if (ret)
|
||||
sc->bbuf->skb = NULL;
|
||||
avf->bbuf->skb = NULL;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@ -1786,16 +1856,14 @@ out:
|
||||
static void
|
||||
ath5k_beacon_send(struct ath5k_softc *sc)
|
||||
{
|
||||
struct ath5k_buf *bf = sc->bbuf;
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ath5k_vif *avf;
|
||||
struct ath5k_buf *bf;
|
||||
struct sk_buff *skb;
|
||||
|
||||
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
|
||||
|
||||
if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) {
|
||||
ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Check if the previous beacon has gone out. If
|
||||
* not, don't don't try to post another: skip this
|
||||
@ -1824,6 +1892,28 @@ ath5k_beacon_send(struct ath5k_softc *sc)
|
||||
sc->bmisscount = 0;
|
||||
}
|
||||
|
||||
if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
|
||||
u64 tsf = ath5k_hw_get_tsf64(ah);
|
||||
u32 tsftu = TSF_TO_TU(tsf);
|
||||
int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
|
||||
vif = sc->bslot[(slot + 1) % ATH_BCBUF];
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
|
||||
"tsf %llx tsftu %x intval %u slot %u vif %p\n",
|
||||
(unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
|
||||
} else /* only one interface */
|
||||
vif = sc->bslot[0];
|
||||
|
||||
if (!vif)
|
||||
return;
|
||||
|
||||
avf = (void *)vif->drv_priv;
|
||||
bf = avf->bbuf;
|
||||
if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
|
||||
sc->opmode == NL80211_IFTYPE_MONITOR)) {
|
||||
ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop any current dma and put the new frame on the queue.
|
||||
* This should never fail since we check above that no frames
|
||||
@ -1836,17 +1926,17 @@ ath5k_beacon_send(struct ath5k_softc *sc)
|
||||
|
||||
/* refresh the beacon for AP mode */
|
||||
if (sc->opmode == NL80211_IFTYPE_AP)
|
||||
ath5k_beacon_update(sc->hw, sc->vif);
|
||||
ath5k_beacon_update(sc->hw, vif);
|
||||
|
||||
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
|
||||
ath5k_hw_start_tx_dma(ah, sc->bhalq);
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
|
||||
sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
|
||||
|
||||
skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
|
||||
skb = ieee80211_get_buffered_bc(sc->hw, vif);
|
||||
while (skb) {
|
||||
ath5k_tx_queue(sc->hw, skb, sc->cabq);
|
||||
skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
|
||||
skb = ieee80211_get_buffered_bc(sc->hw, vif);
|
||||
}
|
||||
|
||||
sc->bsent++;
|
||||
@ -1876,6 +1966,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
|
||||
u64 hw_tsf;
|
||||
|
||||
intval = sc->bintval & AR5K_BEACON_PERIOD;
|
||||
if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
|
||||
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
|
||||
if (intval < 15)
|
||||
ATH5K_WARN(sc, "intval %u is too low, min 15\n",
|
||||
intval);
|
||||
}
|
||||
if (WARN_ON(!intval))
|
||||
return;
|
||||
|
||||
@ -2323,6 +2419,10 @@ ath5k_init(struct ath5k_softc *sc)
|
||||
ath_hw_keyreset(common, (u16) i);
|
||||
|
||||
ath5k_hw_set_ack_bitrate_high(ah, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
|
||||
sc->bslot[i] = NULL;
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
mmiowb();
|
||||
@ -2382,7 +2482,6 @@ ath5k_stop_hw(struct ath5k_softc *sc)
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
|
||||
"putting device to sleep\n");
|
||||
}
|
||||
ath5k_txbuf_free_skb(sc, sc->bbuf);
|
||||
|
||||
mmiowb();
|
||||
mutex_unlock(&sc->lock);
|
||||
@ -2587,9 +2686,9 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
SET_IEEE80211_PERM_ADDR(hw, mac);
|
||||
memcpy(&sc->lladdr, mac, ETH_ALEN);
|
||||
/* All MAC address bits matter for ACKs */
|
||||
memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
|
||||
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
|
||||
ath5k_update_bssid_mask(sc, NULL);
|
||||
|
||||
regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
|
||||
ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
|
||||
@ -2687,31 +2786,91 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
int ret;
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ath5k_vif *avf = (void *)vif->drv_priv;
|
||||
|
||||
mutex_lock(&sc->lock);
|
||||
if (sc->vif) {
|
||||
ret = 0;
|
||||
|
||||
if ((vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_ADHOC)
|
||||
&& (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
|
||||
ret = -ELNRNG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sc->vif = vif;
|
||||
/* Don't allow other interfaces if one ad-hoc is configured.
|
||||
* TODO: Fix the problems with ad-hoc and multiple other interfaces.
|
||||
* We would need to operate the HW in ad-hoc mode to allow TSF updates
|
||||
* for the IBSS, but this breaks with additional AP or STA interfaces
|
||||
* at the moment. */
|
||||
if (sc->num_adhoc_vifs ||
|
||||
(sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
|
||||
ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
|
||||
ret = -ELNRNG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
sc->opmode = vif->type;
|
||||
avf->opmode = vif->type;
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
|
||||
sc->nvifs++;
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
|
||||
|
||||
/* Assign the vap/adhoc to a beacon xmit slot. */
|
||||
if ((avf->opmode == NL80211_IFTYPE_AP) ||
|
||||
(avf->opmode == NL80211_IFTYPE_ADHOC)) {
|
||||
int slot;
|
||||
|
||||
WARN_ON(list_empty(&sc->bcbuf));
|
||||
avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
|
||||
list);
|
||||
list_del(&avf->bbuf->list);
|
||||
|
||||
avf->bslot = 0;
|
||||
for (slot = 0; slot < ATH_BCBUF; slot++) {
|
||||
if (!sc->bslot[slot]) {
|
||||
avf->bslot = slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BUG_ON(sc->bslot[avf->bslot] != NULL);
|
||||
sc->bslot[avf->bslot] = vif;
|
||||
if (avf->opmode == NL80211_IFTYPE_AP)
|
||||
sc->num_ap_vifs++;
|
||||
else
|
||||
sc->num_adhoc_vifs++;
|
||||
}
|
||||
|
||||
/* Set combined mode - when APs are configured, operate in AP mode.
|
||||
* Otherwise use the mode of the new interface. This can currently
|
||||
* only deal with combinations of APs and STAs. Only one ad-hoc
|
||||
* interfaces is allowed above.
|
||||
*/
|
||||
if (sc->num_ap_vifs)
|
||||
sc->opmode = NL80211_IFTYPE_AP;
|
||||
else
|
||||
sc->opmode = vif->type;
|
||||
|
||||
ath5k_hw_set_opmode(ah, sc->opmode);
|
||||
|
||||
/* Any MAC address is fine, all others are included through the
|
||||
* filter.
|
||||
*/
|
||||
memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
|
||||
ath5k_hw_set_lladdr(sc->ah, vif->addr);
|
||||
ath5k_mode_setup(sc);
|
||||
|
||||
memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
|
||||
|
||||
ath5k_mode_setup(sc, vif);
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
@ -2724,15 +2883,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
u8 mac[ETH_ALEN] = {};
|
||||
struct ath5k_vif *avf = (void *)vif->drv_priv;
|
||||
unsigned int i;
|
||||
|
||||
mutex_lock(&sc->lock);
|
||||
if (sc->vif != vif)
|
||||
goto end;
|
||||
sc->nvifs--;
|
||||
|
||||
ath5k_hw_set_lladdr(sc->ah, mac);
|
||||
sc->vif = NULL;
|
||||
end:
|
||||
if (avf->bbuf) {
|
||||
ath5k_txbuf_free_skb(sc, avf->bbuf);
|
||||
list_add_tail(&avf->bbuf->list, &sc->bcbuf);
|
||||
for (i = 0; i < ATH_BCBUF; i++) {
|
||||
if (sc->bslot[i] == vif) {
|
||||
sc->bslot[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
avf->bbuf = NULL;
|
||||
}
|
||||
if (avf->opmode == NL80211_IFTYPE_AP)
|
||||
sc->num_ap_vifs--;
|
||||
else if (avf->opmode == NL80211_IFTYPE_ADHOC)
|
||||
sc->num_adhoc_vifs--;
|
||||
|
||||
ath5k_update_bssid_mask(sc, NULL);
|
||||
mutex_unlock(&sc->lock);
|
||||
}
|
||||
|
||||
@ -2815,6 +2988,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
|
||||
return ((u64)(mfilt[1]) << 32) | mfilt[0];
|
||||
}
|
||||
|
||||
static bool ath_any_vif_assoc(struct ath5k_softc *sc)
|
||||
{
|
||||
struct ath_vif_iter_data iter_data;
|
||||
iter_data.hw_macaddr = NULL;
|
||||
iter_data.any_assoc = false;
|
||||
iter_data.need_set_hw_addr = false;
|
||||
iter_data.found_active = true;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
|
||||
&iter_data);
|
||||
return iter_data.any_assoc;
|
||||
}
|
||||
|
||||
#define SUPPORTED_FIF_FLAGS \
|
||||
FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
|
||||
FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
|
||||
@ -2885,7 +3071,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
||||
|
||||
/* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
|
||||
* and probes for any BSSID */
|
||||
if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
|
||||
if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
|
||||
rfilt |= AR5K_RX_FILTER_BEACON;
|
||||
|
||||
/* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
|
||||
@ -3070,14 +3256,13 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changes)
|
||||
{
|
||||
struct ath5k_vif *avf = (void *)vif->drv_priv;
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&sc->lock);
|
||||
if (WARN_ON(sc->vif != vif))
|
||||
goto unlock;
|
||||
|
||||
if (changes & BSS_CHANGED_BSSID) {
|
||||
/* Cache for later use during resets */
|
||||
@ -3091,7 +3276,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
sc->bintval = bss_conf->beacon_int;
|
||||
|
||||
if (changes & BSS_CHANGED_ASSOC) {
|
||||
sc->assoc = bss_conf->assoc;
|
||||
avf->assoc = bss_conf->assoc;
|
||||
if (bss_conf->assoc)
|
||||
sc->assoc = bss_conf->assoc;
|
||||
else
|
||||
sc->assoc = ath_any_vif_assoc(sc);
|
||||
|
||||
if (sc->opmode == NL80211_IFTYPE_STATION)
|
||||
set_beacon_filter(hw, sc->assoc);
|
||||
ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
|
||||
@ -3119,7 +3309,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
BSS_CHANGED_BEACON_INT))
|
||||
ath5k_beacon_config(sc);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&sc->lock);
|
||||
}
|
||||
|
||||
@ -3394,6 +3583,8 @@ ath5k_pci_probe(struct pci_dev *pdev,
|
||||
hw->max_rate_tries = 11;
|
||||
}
|
||||
|
||||
hw->vif_data_size = sizeof(struct ath5k_vif);
|
||||
|
||||
/* Finish private driver data initialization */
|
||||
ret = ath5k_attach(pdev, hw);
|
||||
if (ret)
|
||||
|
@ -58,8 +58,7 @@
|
||||
|
||||
#define ATH_RXBUF 40 /* number of RX buffers */
|
||||
#define ATH_TXBUF 200 /* number of TX buffers */
|
||||
#define ATH_BCBUF 1 /* number of beacon buffers */
|
||||
|
||||
#define ATH_BCBUF 4 /* number of beacon buffers */
|
||||
#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */
|
||||
#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
|
||||
|
||||
@ -122,6 +121,13 @@ struct ath5k_statistics {
|
||||
/* frame errors */
|
||||
unsigned int rx_all_count; /* all RX frames, including errors */
|
||||
unsigned int tx_all_count; /* all TX frames, including errors */
|
||||
unsigned int rx_bytes_count; /* all RX bytes, including errored pks
|
||||
* and the MAC headers for each packet
|
||||
*/
|
||||
unsigned int tx_bytes_count; /* all TX bytes, including errored pkts
|
||||
* and the MAC headers and padding for
|
||||
* each packet.
|
||||
*/
|
||||
unsigned int rxerr_crc;
|
||||
unsigned int rxerr_phy;
|
||||
unsigned int rxerr_phy_code[32];
|
||||
@ -152,6 +158,14 @@ struct ath5k_statistics {
|
||||
#define ATH_CHAN_MAX (14+14+14+252+20)
|
||||
#endif
|
||||
|
||||
struct ath5k_vif {
|
||||
bool assoc; /* are we associated or not */
|
||||
enum nl80211_iftype opmode;
|
||||
int bslot;
|
||||
struct ath5k_buf *bbuf; /* beacon buffer */
|
||||
u8 lladdr[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* Software Carrier, keeps track of the driver state
|
||||
* associated with an instance of a device */
|
||||
struct ath5k_softc {
|
||||
@ -188,10 +202,11 @@ struct ath5k_softc {
|
||||
unsigned int curmode; /* current phy mode */
|
||||
struct ieee80211_channel *curchan; /* current h/w channel */
|
||||
|
||||
struct ieee80211_vif *vif;
|
||||
u16 nvifs;
|
||||
|
||||
enum ath5k_int imask; /* interrupt mask copy */
|
||||
|
||||
u8 lladdr[ETH_ALEN];
|
||||
u8 bssidmask[ETH_ALEN];
|
||||
|
||||
unsigned int led_pin, /* GPIO pin for driving LED */
|
||||
@ -219,7 +234,10 @@ struct ath5k_softc {
|
||||
|
||||
spinlock_t block; /* protects beacon */
|
||||
struct tasklet_struct beacontq; /* beacon intr tasklet */
|
||||
struct ath5k_buf *bbuf; /* beacon buffer */
|
||||
struct list_head bcbuf; /* beacon buffer */
|
||||
struct ieee80211_vif *bslot[ATH_BCBUF];
|
||||
u16 num_ap_vifs;
|
||||
u16 num_adhoc_vifs;
|
||||
unsigned int bhalq, /* SW q for outgoing beacons */
|
||||
bmisscount, /* missed beacon transmits */
|
||||
bintval, /* beacon interval in TU */
|
||||
|
@ -587,6 +587,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
|
||||
st->rxerr_jumbo*100/st->rx_all_count : 0);
|
||||
len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
|
||||
st->rx_all_count);
|
||||
len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n",
|
||||
st->rx_bytes_count);
|
||||
|
||||
len += snprintf(buf+len, sizeof(buf)-len,
|
||||
"\nTX\n---------------------\n");
|
||||
@ -604,6 +606,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
|
||||
st->txerr_filt*100/st->tx_all_count : 0);
|
||||
len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
|
||||
st->tx_all_count);
|
||||
len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n",
|
||||
st->tx_bytes_count);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
|
||||
* ieee80211_duration() for a brief description of
|
||||
* what rate we should choose to TX ACKs. */
|
||||
tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
|
||||
sc->vif, 10, rate));
|
||||
NULL, 10, rate));
|
||||
|
||||
ath5k_hw_reg_write(ah, tx_time, reg);
|
||||
|
||||
@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||
* XXX: rethink this after new mode changes to
|
||||
* mac80211 are integrated */
|
||||
if (ah->ah_version == AR5K_AR5212 &&
|
||||
ah->ah_sc->vif != NULL)
|
||||
ah->ah_sc->nvifs)
|
||||
ath5k_hw_write_rate_duration(ah, mode);
|
||||
|
||||
/*
|
||||
|
@ -103,31 +103,9 @@ static const struct ani_cck_level_entry cck_level_table[] = {
|
||||
#define ATH9K_ANI_CCK_DEF_LEVEL \
|
||||
2 /* default level - matches the INI settings */
|
||||
|
||||
/* Private to ani.c */
|
||||
static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
|
||||
static bool use_new_ani(struct ath_hw *ah)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
|
||||
}
|
||||
|
||||
int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
|
||||
if (ah->ani[i].c &&
|
||||
ah->ani[i].c->channel == chan->channel)
|
||||
return i;
|
||||
if (ah->ani[i].c == NULL) {
|
||||
ah->ani[i].c = chan;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
|
||||
"No more channel states left. Using channel 0\n");
|
||||
|
||||
return 0;
|
||||
return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
|
||||
}
|
||||
|
||||
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
||||
@ -140,82 +118,34 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
||||
stats->beacons += REG_READ(ah, AR_BEACON_CNT);
|
||||
}
|
||||
|
||||
static void ath9k_ani_restart_old(struct ath_hw *ah)
|
||||
static void ath9k_ani_restart(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 ofdm_base = 0, cck_base = 0;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
aniState->listenTime = 0;
|
||||
|
||||
if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
|
||||
aniState->ofdmPhyErrBase = 0;
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"OFDM Trigger is too high for hw counters\n");
|
||||
} else {
|
||||
aniState->ofdmPhyErrBase =
|
||||
AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
|
||||
}
|
||||
if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
|
||||
aniState->cckPhyErrBase = 0;
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"CCK Trigger is too high for hw counters\n");
|
||||
} else {
|
||||
aniState->cckPhyErrBase =
|
||||
AR_PHY_COUNTMAX - aniState->cckTrigHigh;
|
||||
if (!use_new_ani(ah)) {
|
||||
ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
||||
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"Writing ofdmbase=%u cckbase=%u\n",
|
||||
aniState->ofdmPhyErrBase,
|
||||
aniState->cckPhyErrBase);
|
||||
"Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
aniState->ofdmPhyErrCount = 0;
|
||||
aniState->cckPhyErrCount = 0;
|
||||
}
|
||||
|
||||
static void ath9k_ani_restart_new(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState->listenTime = 0;
|
||||
|
||||
aniState->ofdmPhyErrBase = 0;
|
||||
aniState->cckPhyErrBase = 0;
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"Writing ofdmbase=%08x cckbase=%08x\n",
|
||||
aniState->ofdmPhyErrBase,
|
||||
aniState->cckPhyErrBase);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
@ -229,10 +159,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
@ -301,10 +228,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1)) {
|
||||
@ -336,7 +260,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
|
||||
/* Adjust the OFDM Noise Immunity Level */
|
||||
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
@ -381,14 +305,19 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
|
||||
static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_ofdm_err_trigger_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
|
||||
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
|
||||
@ -399,7 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
|
||||
*/
|
||||
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
@ -438,14 +367,19 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
|
||||
entry_cck->mrc_cck_on);
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah)
|
||||
static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_cck_err_trigger_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
|
||||
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
|
||||
@ -456,7 +390,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
if (aniState->firstepLevel > 0) {
|
||||
@ -508,11 +442,16 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
|
||||
* only lower either OFDM or CCK errors per turn
|
||||
* we lower the other one next time
|
||||
*/
|
||||
static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
|
||||
static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_lower_immunity_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
/* lower OFDM noise immunity */
|
||||
if (aniState->ofdmNoiseImmunityLevel > 0 &&
|
||||
@ -544,52 +483,20 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
|
||||
if (conf_is_ht40(conf))
|
||||
return clockrate * 2;
|
||||
|
||||
return clockrate * 2;
|
||||
return clockrate;
|
||||
}
|
||||
|
||||
static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 txFrameCount, rxFrameCount, cycleCount;
|
||||
int32_t listenTime;
|
||||
int32_t listen_time;
|
||||
int32_t clock_rate;
|
||||
|
||||
txFrameCount = REG_READ(ah, AR_TFCNT);
|
||||
rxFrameCount = REG_READ(ah, AR_RFCNT);
|
||||
cycleCount = REG_READ(ah, AR_CCCNT);
|
||||
ath9k_hw_update_cycle_counters(ah);
|
||||
clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
|
||||
listen_time = ah->listen_time / clock_rate;
|
||||
ah->listen_time = 0;
|
||||
|
||||
aniState = ah->curani;
|
||||
if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
|
||||
listenTime = 0;
|
||||
ah->stats.ast_ani_lzero++;
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"1st call: aniState->cycleCount=%d\n",
|
||||
aniState->cycleCount);
|
||||
} else {
|
||||
int32_t ccdelta = cycleCount - aniState->cycleCount;
|
||||
int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
|
||||
int32_t tfdelta = txFrameCount - aniState->txFrameCount;
|
||||
int32_t clock_rate;
|
||||
|
||||
/*
|
||||
* convert HW counter values to ms using mode
|
||||
* specifix clock rate
|
||||
*/
|
||||
clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
|
||||
|
||||
listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"cyclecount=%d, rfcount=%d, "
|
||||
"tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
|
||||
ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
|
||||
}
|
||||
|
||||
aniState->cycleCount = cycleCount;
|
||||
aniState->txFrameCount = txFrameCount;
|
||||
aniState->rxFrameCount = rxFrameCount;
|
||||
|
||||
return listenTime;
|
||||
return listen_time;
|
||||
}
|
||||
|
||||
static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
@ -597,16 +504,13 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int index;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
index = ath9k_hw_get_ani_channel_idx(ah, chan);
|
||||
aniState = &ah->ani[index];
|
||||
ah->curani = aniState;
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
|
||||
if (ah->opmode != NL80211_IFTYPE_STATION
|
||||
&& ah->opmode != NL80211_IFTYPE_ADHOC) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"Reset ANI state opmode %u\n", ah->opmode);
|
||||
@ -635,17 +539,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
|
||||
ATH9K_RX_FILTER_PHYERR);
|
||||
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
ah->curani->ofdmTrigHigh =
|
||||
ah->config.ofdm_trig_high;
|
||||
ah->curani->ofdmTrigLow =
|
||||
ah->config.ofdm_trig_low;
|
||||
ah->curani->cckTrigHigh =
|
||||
ah->config.cck_trig_high;
|
||||
ah->curani->cckTrigLow =
|
||||
ah->config.cck_trig_low;
|
||||
}
|
||||
ath9k_ani_restart_old(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -667,7 +561,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
|
||||
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
|
||||
~ATH9K_RX_FILTER_PHYERR);
|
||||
ath9k_ani_restart_old(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
@ -675,7 +569,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -683,15 +576,18 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
* This routine should be called for every hardware reset and for
|
||||
* every channel change.
|
||||
*/
|
||||
static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
|
||||
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
if (!use_new_ani(ah))
|
||||
return ath9k_ani_reset_old(ah, is_scanning);
|
||||
|
||||
BUG_ON(aniState == NULL);
|
||||
ah->stats.ast_ani_reset++;
|
||||
|
||||
@ -761,7 +657,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
|
||||
* enable phy counters if hw supports or if not, enable phy
|
||||
* interrupts (so we can count each one)
|
||||
*/
|
||||
ath9k_ani_restart_new(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
@ -769,30 +665,30 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int32_t listenTime;
|
||||
u32 phyCnt1, phyCnt2;
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
u32 ofdm_base = 0;
|
||||
u32 cck_base = 0;
|
||||
u32 ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
u32 phyCnt1, phyCnt2;
|
||||
int32_t listenTime;
|
||||
|
||||
listenTime = ath9k_hw_ani_get_listen_time(ah);
|
||||
if (listenTime < 0) {
|
||||
ah->stats.ast_ani_lneg++;
|
||||
ath9k_ani_restart_old(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
||||
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
||||
}
|
||||
|
||||
aniState->listenTime += listenTime;
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
@ -800,145 +696,54 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
|
||||
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
|
||||
if (phyCnt1 < aniState->ofdmPhyErrBase ||
|
||||
phyCnt2 < aniState->cckPhyErrBase) {
|
||||
if (phyCnt1 < aniState->ofdmPhyErrBase) {
|
||||
if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
|
||||
if (phyCnt1 < ofdm_base) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"phyCnt1 0x%x, resetting "
|
||||
"counter value to 0x%x\n",
|
||||
phyCnt1,
|
||||
aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1,
|
||||
aniState->ofdmPhyErrBase);
|
||||
phyCnt1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
|
||||
AR_PHY_ERR_OFDM_TIMING);
|
||||
}
|
||||
if (phyCnt2 < aniState->cckPhyErrBase) {
|
||||
if (phyCnt2 < cck_base) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"phyCnt2 0x%x, resetting "
|
||||
"counter value to 0x%x\n",
|
||||
phyCnt2,
|
||||
aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2,
|
||||
aniState->cckPhyErrBase);
|
||||
phyCnt2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
|
||||
AR_PHY_ERR_CCK_TIMING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
|
||||
ofdmPhyErrCnt = phyCnt1 - ofdm_base;
|
||||
ah->stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
|
||||
cckPhyErrCnt = phyCnt2 - cck_base;
|
||||
ah->stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
|
||||
if (aniState->listenTime > 5 * ah->aniperiod) {
|
||||
if (aniState->ofdmPhyErrCount <= aniState->listenTime *
|
||||
aniState->ofdmTrigLow / 1000 &&
|
||||
aniState->cckPhyErrCount <= aniState->listenTime *
|
||||
aniState->cckTrigLow / 1000)
|
||||
ath9k_hw_ani_lower_immunity(ah);
|
||||
ath9k_ani_restart_old(ah);
|
||||
} else if (aniState->listenTime > ah->aniperiod) {
|
||||
if (aniState->ofdmPhyErrCount > aniState->listenTime *
|
||||
aniState->ofdmTrigHigh / 1000) {
|
||||
ath9k_hw_ani_ofdm_err_trigger_old(ah);
|
||||
ath9k_ani_restart_old(ah);
|
||||
} else if (aniState->cckPhyErrCount >
|
||||
aniState->listenTime * aniState->cckTrigHigh /
|
||||
1000) {
|
||||
ath9k_hw_ani_cck_err_trigger_old(ah);
|
||||
ath9k_ani_restart_old(ah);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int32_t listenTime;
|
||||
u32 phyCnt1, phyCnt2;
|
||||
u32 ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
u32 ofdmPhyErrRate, cckPhyErrRate;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = ah->curani;
|
||||
aniState = &ah->curchan->ani;
|
||||
if (WARN_ON(!aniState))
|
||||
return;
|
||||
|
||||
listenTime = ath9k_hw_ani_get_listen_time(ah);
|
||||
if (listenTime <= 0) {
|
||||
ah->stats.ast_ani_lneg++;
|
||||
/* restart ANI period if listenTime is invalid */
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"listenTime=%d - on new ani monitor\n",
|
||||
listenTime);
|
||||
ath9k_ani_restart_new(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
aniState->listenTime += listenTime;
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
|
||||
if (phyCnt1 < aniState->ofdmPhyErrBase ||
|
||||
phyCnt2 < aniState->cckPhyErrBase) {
|
||||
if (phyCnt1 < aniState->ofdmPhyErrBase) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"phyCnt1 0x%x, resetting "
|
||||
"counter value to 0x%x\n",
|
||||
phyCnt1,
|
||||
aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1,
|
||||
aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
|
||||
AR_PHY_ERR_OFDM_TIMING);
|
||||
}
|
||||
if (phyCnt2 < aniState->cckPhyErrBase) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"phyCnt2 0x%x, resetting "
|
||||
"counter value to 0x%x\n",
|
||||
phyCnt2,
|
||||
aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2,
|
||||
aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
|
||||
AR_PHY_ERR_CCK_TIMING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
|
||||
ah->stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
|
||||
ah->stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"Errors: OFDM=0x%08x-0x%08x=%d "
|
||||
"CCK=0x%08x-0x%08x=%d\n",
|
||||
phyCnt1,
|
||||
aniState->ofdmPhyErrBase,
|
||||
ofdmPhyErrCnt,
|
||||
phyCnt2,
|
||||
aniState->cckPhyErrBase,
|
||||
cckPhyErrCnt);
|
||||
ath9k_hw_ani_read_counters(ah);
|
||||
|
||||
ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
|
||||
aniState->listenTime;
|
||||
@ -948,61 +753,34 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"listenTime=%d OFDM:%d errs=%d/s CCK:%d "
|
||||
"errs=%d/s ofdm_turn=%d\n",
|
||||
listenTime, aniState->ofdmNoiseImmunityLevel,
|
||||
aniState->listenTime,
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
|
||||
cckPhyErrRate, aniState->ofdmsTurn);
|
||||
|
||||
if (aniState->listenTime > 5 * ah->aniperiod) {
|
||||
if (ofdmPhyErrRate <= aniState->ofdmTrigLow &&
|
||||
cckPhyErrRate <= aniState->cckTrigLow) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
|
||||
"CCK:%d errs=%d/s(<%d) -> "
|
||||
"ath9k_hw_ani_lower_immunity()\n",
|
||||
aniState->listenTime,
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
ofdmPhyErrRate,
|
||||
aniState->ofdmTrigLow,
|
||||
aniState->cckNoiseImmunityLevel,
|
||||
cckPhyErrRate,
|
||||
aniState->cckTrigLow);
|
||||
if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
|
||||
cckPhyErrRate <= ah->config.cck_trig_low) {
|
||||
ath9k_hw_ani_lower_immunity(ah);
|
||||
aniState->ofdmsTurn = !aniState->ofdmsTurn;
|
||||
}
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"1 listenTime=%d ofdm=%d/s cck=%d/s - "
|
||||
"calling ath9k_ani_restart_new()\n",
|
||||
aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
|
||||
ath9k_ani_restart_new(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
} else if (aniState->listenTime > ah->aniperiod) {
|
||||
/* check to see if need to raise immunity */
|
||||
if (ofdmPhyErrRate > aniState->ofdmTrigHigh &&
|
||||
(cckPhyErrRate <= aniState->cckTrigHigh ||
|
||||
if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
|
||||
(cckPhyErrRate <= ah->config.cck_trig_high ||
|
||||
aniState->ofdmsTurn)) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> "
|
||||
"ath9k_hw_ani_ofdm_err_trigger_new()\n",
|
||||
aniState->listenTime,
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
ofdmPhyErrRate,
|
||||
aniState->ofdmTrigHigh);
|
||||
ath9k_hw_ani_ofdm_err_trigger_new(ah);
|
||||
ath9k_ani_restart_new(ah);
|
||||
ath9k_hw_ani_ofdm_err_trigger(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
aniState->ofdmsTurn = false;
|
||||
} else if (cckPhyErrRate > aniState->cckTrigHigh) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"3 listenTime=%d CCK:%d errs=%d/s(>%d) -> "
|
||||
"ath9k_hw_ani_cck_err_trigger_new()\n",
|
||||
aniState->listenTime,
|
||||
aniState->cckNoiseImmunityLevel,
|
||||
cckPhyErrRate,
|
||||
aniState->cckTrigHigh);
|
||||
ath9k_hw_ani_cck_err_trigger_new(ah);
|
||||
ath9k_ani_restart_new(ah);
|
||||
} else if (cckPhyErrRate > ah->config.cck_trig_high) {
|
||||
ath9k_hw_ani_cck_err_trigger(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
aniState->ofdmsTurn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_ani_monitor);
|
||||
|
||||
void ath9k_enable_mib_counters(struct ath_hw *ah)
|
||||
{
|
||||
@ -1023,7 +801,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
/* Freeze the MIB counters, get the stats and then clear them */
|
||||
@ -1041,45 +818,52 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
|
||||
|
||||
u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
|
||||
u32 *rxc_pcnt,
|
||||
u32 *rxf_pcnt,
|
||||
u32 *txf_pcnt)
|
||||
void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
static u32 cycles, rx_clear, rx_frame, tx_frame;
|
||||
u32 good = 1;
|
||||
struct ath_cycle_counters cc;
|
||||
bool clear;
|
||||
|
||||
u32 rc = REG_READ(ah, AR_RCCNT);
|
||||
u32 rf = REG_READ(ah, AR_RFCNT);
|
||||
u32 tf = REG_READ(ah, AR_TFCNT);
|
||||
u32 cc = REG_READ(ah, AR_CCCNT);
|
||||
memcpy(&cc, &ah->cc, sizeof(cc));
|
||||
|
||||
if (cycles == 0 || cycles > cc) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"cycle counter wrap. ExtBusy = 0\n");
|
||||
good = 0;
|
||||
} else {
|
||||
u32 cc_d = cc - cycles;
|
||||
u32 rc_d = rc - rx_clear;
|
||||
u32 rf_d = rf - rx_frame;
|
||||
u32 tf_d = tf - tx_frame;
|
||||
/* freeze counters */
|
||||
REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
|
||||
|
||||
if (cc_d != 0) {
|
||||
*rxc_pcnt = rc_d * 100 / cc_d;
|
||||
*rxf_pcnt = rf_d * 100 / cc_d;
|
||||
*txf_pcnt = tf_d * 100 / cc_d;
|
||||
} else {
|
||||
good = 0;
|
||||
}
|
||||
ah->cc.cycles = REG_READ(ah, AR_CCCNT);
|
||||
if (ah->cc.cycles < cc.cycles) {
|
||||
clear = true;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
cycles = cc;
|
||||
rx_frame = rf;
|
||||
rx_clear = rc;
|
||||
tx_frame = tf;
|
||||
ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
|
||||
ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
|
||||
ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
|
||||
|
||||
return good;
|
||||
/* prevent wraparound */
|
||||
if (ah->cc.cycles & BIT(31))
|
||||
clear = true;
|
||||
|
||||
#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
|
||||
CC_DELTA(cycles, AR_CCCNT);
|
||||
CC_DELTA(rx_frame, AR_RFCNT);
|
||||
CC_DELTA(rx_clear, AR_RCCNT);
|
||||
CC_DELTA(tx_frame, AR_TFCNT);
|
||||
#undef CC_DELTA
|
||||
|
||||
ah->listen_time += (ah->cc.cycles - cc.cycles) -
|
||||
((ah->cc.rx_frame - cc.rx_frame) +
|
||||
(ah->cc.tx_frame - cc.tx_frame));
|
||||
|
||||
skip:
|
||||
if (clear) {
|
||||
REG_WRITE(ah, AR_CCCNT, 0);
|
||||
REG_WRITE(ah, AR_RFCNT, 0);
|
||||
REG_WRITE(ah, AR_RCCNT, 0);
|
||||
REG_WRITE(ah, AR_TFCNT, 0);
|
||||
memset(&ah->cc, 0, sizeof(ah->cc));
|
||||
}
|
||||
|
||||
/* unfreeze counters */
|
||||
REG_WRITE(ah, AR_MIBC, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1087,7 +871,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
|
||||
* any of the MIB counters overflow/trigger so don't assume we're
|
||||
* here because a PHY error counter triggered.
|
||||
*/
|
||||
static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
|
||||
void ath9k_hw_proc_mib_event(struct ath_hw *ah)
|
||||
{
|
||||
u32 phyCnt1, phyCnt2;
|
||||
|
||||
@ -1115,72 +899,15 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
|
||||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
u32 ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
|
||||
/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
|
||||
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
|
||||
ah->stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
if (!use_new_ani(ah))
|
||||
ath9k_hw_ani_read_counters(ah);
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
|
||||
ah->stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
|
||||
/*
|
||||
* NB: figure out which counter triggered. If both
|
||||
* trigger we'll only deal with one as the processing
|
||||
* clobbers the error counter so the trigger threshold
|
||||
* check will never be true.
|
||||
*/
|
||||
if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
|
||||
ath9k_hw_ani_ofdm_err_trigger_new(ah);
|
||||
if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
|
||||
ath9k_hw_ani_cck_err_trigger_old(ah);
|
||||
/* NB: always restart to insure the h/w counters are reset */
|
||||
ath9k_ani_restart_old(ah);
|
||||
ath9k_ani_restart(ah);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a MIB interrupt. We may potentially be invoked because
|
||||
* any of the MIB counters overflow/trigger so don't assume we're
|
||||
* here because a PHY error counter triggered.
|
||||
*/
|
||||
static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
|
||||
{
|
||||
u32 phyCnt1, phyCnt2;
|
||||
|
||||
/* Reset these counters regardless */
|
||||
REG_WRITE(ah, AR_FILT_OFDM, 0);
|
||||
REG_WRITE(ah, AR_FILT_CCK, 0);
|
||||
if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
|
||||
REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
|
||||
|
||||
/* Clear the mib counters and save them in the stats */
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
if (!DO_ANI(ah)) {
|
||||
/*
|
||||
* We must always clear the interrupt cause by
|
||||
* resetting the phy error regs.
|
||||
*/
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, 0);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NB: these are not reset-on-read */
|
||||
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
|
||||
/* NB: always restart to insure the h/w counters are reset */
|
||||
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
|
||||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK))
|
||||
ath9k_ani_restart_new(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
|
||||
|
||||
void ath9k_hw_ani_setup(struct ath_hw *ah)
|
||||
{
|
||||
@ -1206,61 +933,58 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
|
||||
|
||||
ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
|
||||
|
||||
memset(ah->ani, 0, sizeof(ah->ani));
|
||||
for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
|
||||
if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
|
||||
ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
|
||||
ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
|
||||
if (use_new_ani(ah)) {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
|
||||
|
||||
ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
|
||||
ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW;
|
||||
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
|
||||
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
|
||||
} else {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
|
||||
|
||||
ah->ani[i].spurImmunityLevel =
|
||||
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
|
||||
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
|
||||
struct ath9k_channel *chan = &ah->channels[i];
|
||||
struct ar5416AniState *ani = &chan->ani;
|
||||
|
||||
if (use_new_ani(ah)) {
|
||||
ani->spurImmunityLevel =
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
||||
|
||||
ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
|
||||
ah->ani[i].ofdmPhyErrBase = 0;
|
||||
ah->ani[i].cckPhyErrBase = 0;
|
||||
ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
ah->ani[i].mrcCCKOff =
|
||||
ani->mrcCCKOff =
|
||||
!ATH9K_ANI_ENABLE_MRC_CCK;
|
||||
else
|
||||
ah->ani[i].mrcCCKOff = true;
|
||||
ani->mrcCCKOff = true;
|
||||
|
||||
ah->ani[i].ofdmsTurn = true;
|
||||
ani->ofdmsTurn = true;
|
||||
} else {
|
||||
ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
|
||||
ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
|
||||
|
||||
ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
|
||||
ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
|
||||
|
||||
ah->ani[i].spurImmunityLevel =
|
||||
ani->spurImmunityLevel =
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
|
||||
ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
|
||||
ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
|
||||
|
||||
ah->ani[i].ofdmPhyErrBase =
|
||||
AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
|
||||
ah->ani[i].cckPhyErrBase =
|
||||
AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
|
||||
ah->ani[i].cckWeakSigThreshold =
|
||||
ani->cckWeakSigThreshold =
|
||||
ATH9K_ANI_CCK_WEAK_SIG_THR;
|
||||
}
|
||||
|
||||
ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
|
||||
ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
|
||||
ah->ani[i].ofdmWeakSigDetectOff =
|
||||
ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
|
||||
ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
|
||||
ani->ofdmWeakSigDetectOff =
|
||||
!ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
|
||||
ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
|
||||
}
|
||||
|
||||
/*
|
||||
* since we expect some ongoing maintenance on the tables, let's sanity
|
||||
* check here default level should not modify INI setting.
|
||||
*/
|
||||
if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
|
||||
if (use_new_ani(ah)) {
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
|
||||
@ -1274,50 +998,9 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
|
||||
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"Setting OfdmErrBase = 0x%08x\n",
|
||||
ah->ani[0].ofdmPhyErrBase);
|
||||
ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
|
||||
ah->ani[0].cckPhyErrBase);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ath9k_enable_mib_counters(ah);
|
||||
|
||||
if (ah->config.enable_ani)
|
||||
ah->proc_phyerr |= HAL_PROCESS_ANI;
|
||||
}
|
||||
|
||||
void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
priv_ops->ani_reset = ath9k_ani_reset_old;
|
||||
priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old;
|
||||
|
||||
ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
|
||||
ops->ani_monitor = ath9k_hw_ani_monitor_old;
|
||||
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
|
||||
}
|
||||
|
||||
void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
priv_ops->ani_reset = ath9k_ani_reset_new;
|
||||
priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
|
||||
|
||||
ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
|
||||
ops->ani_monitor = ath9k_hw_ani_monitor_new;
|
||||
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
|
||||
|
||||
ath9k_ani_restart(ah);
|
||||
ath9k_enable_mib_counters(ah);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#define HAL_PROCESS_ANI 0x00000001
|
||||
|
||||
#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
|
||||
#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
|
||||
|
||||
#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
|
||||
|
||||
@ -93,6 +93,13 @@ struct ath9k_mib_stats {
|
||||
u32 beacons;
|
||||
};
|
||||
|
||||
struct ath_cycle_counters {
|
||||
u32 cycles;
|
||||
u32 rx_frame;
|
||||
u32 rx_clear;
|
||||
u32 tx_frame;
|
||||
};
|
||||
|
||||
/* INI default values for ANI registers */
|
||||
struct ath9k_ani_default {
|
||||
u16 m1ThreshLow;
|
||||
@ -123,20 +130,11 @@ struct ar5416AniState {
|
||||
u8 ofdmWeakSigDetectOff;
|
||||
u8 cckWeakSigThreshold;
|
||||
u32 listenTime;
|
||||
u32 ofdmTrigHigh;
|
||||
u32 ofdmTrigLow;
|
||||
int32_t cckTrigHigh;
|
||||
int32_t cckTrigLow;
|
||||
int32_t rssiThrLow;
|
||||
int32_t rssiThrHigh;
|
||||
u32 noiseFloor;
|
||||
u32 txFrameCount;
|
||||
u32 rxFrameCount;
|
||||
u32 cycleCount;
|
||||
u32 ofdmPhyErrCount;
|
||||
u32 cckPhyErrCount;
|
||||
u32 ofdmPhyErrBase;
|
||||
u32 cckPhyErrBase;
|
||||
int16_t pktRssi[2];
|
||||
int16_t ofdmErrRssi[2];
|
||||
int16_t cckErrRssi[2];
|
||||
@ -166,8 +164,7 @@ struct ar5416Stats {
|
||||
|
||||
void ath9k_enable_mib_counters(struct ath_hw *ah);
|
||||
void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
|
||||
u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
|
||||
u32 *rxf_pcnt, u32 *txf_pcnt);
|
||||
void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
|
||||
void ath9k_hw_ani_setup(struct ath_hw *ah);
|
||||
void ath9k_hw_ani_init(struct ath_hw *ah);
|
||||
int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
|
||||
|
@ -613,14 +613,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
|
||||
rx_chainmask = ah->rxchainmask;
|
||||
tx_chainmask = ah->txchainmask;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
switch (rx_chainmask) {
|
||||
case 0x5:
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
|
||||
AR_PHY_SWAP_ALT_CHAIN);
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
case 0x3:
|
||||
if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
|
||||
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
|
||||
@ -630,17 +627,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
|
||||
case 0x1:
|
||||
case 0x2:
|
||||
case 0x7:
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
|
||||
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
|
||||
break;
|
||||
default:
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
break;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (tx_chainmask == 0x5) {
|
||||
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
|
||||
@ -726,7 +724,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
|
||||
@ -818,7 +815,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
|
||||
@ -849,7 +845,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9271(ah)) {
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
|
||||
@ -1053,7 +1048,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd,
|
||||
int param)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
@ -1225,8 +1220,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
|
||||
aniState->firstepLevel,
|
||||
aniState->listenTime);
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
|
||||
aniState->cycleCount,
|
||||
"ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
|
||||
@ -1237,9 +1231,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd,
|
||||
int param)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar5416AniState *aniState = &chan->ani;
|
||||
s32 value, value2;
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
@ -1478,15 +1472,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
|
||||
"MRCcck=%s listenTime=%d CC=%d listen=%d "
|
||||
"MRCcck=%s listenTime=%d "
|
||||
"ofdmErrs=%d cckErrs=%d\n",
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
||||
aniState->firstepLevel,
|
||||
!aniState->mrcCCKOff ? "on" : "off",
|
||||
aniState->listenTime,
|
||||
aniState->cycleCount,
|
||||
aniState->listenTime,
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
return true;
|
||||
@ -1526,16 +1518,12 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
|
||||
*/
|
||||
static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar5416AniState *aniState = &chan->ani;
|
||||
struct ath9k_ani_default *iniDef;
|
||||
int index;
|
||||
u32 val;
|
||||
|
||||
index = ath9k_hw_get_ani_channel_idx(ah, chan);
|
||||
aniState = &ah->ani[index];
|
||||
ah->curani = aniState;
|
||||
iniDef = &aniState->iniDef;
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
@ -1579,8 +1567,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCKOff = true; /* not available on pre AR9003 */
|
||||
|
||||
aniState->cycleCount = 0;
|
||||
}
|
||||
|
||||
static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
|
||||
|
@ -20,6 +20,13 @@
|
||||
|
||||
#define AR9285_CLCAL_REDO_THRESH 1
|
||||
|
||||
enum ar9002_cal_types {
|
||||
ADC_GAIN_CAL = BIT(0),
|
||||
ADC_DC_CAL = BIT(1),
|
||||
IQ_MISMATCH_CAL = BIT(2),
|
||||
};
|
||||
|
||||
|
||||
static void ar9002_hw_setup_calibration(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal)
|
||||
{
|
||||
@ -45,13 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"starting ADC DC Calibration\n");
|
||||
break;
|
||||
case ADC_DC_INIT_CAL:
|
||||
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"starting Init ADC DC Calibration\n");
|
||||
break;
|
||||
case TEMP_COMP_CAL:
|
||||
break; /* Not supported */
|
||||
}
|
||||
|
||||
REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
|
||||
@ -96,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
|
||||
return iscaldone;
|
||||
}
|
||||
|
||||
/* Assumes you are talking about the currently configured channel */
|
||||
static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType)
|
||||
{
|
||||
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
|
||||
|
||||
switch (calType & ah->supp_cals) {
|
||||
case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
|
||||
return true;
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
|
||||
conf_is_ht20(conf)))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
|
||||
{
|
||||
int i;
|
||||
@ -541,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
|
||||
REG_WRITE(ah, regList[i][0], regList[i][1]);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
|
||||
@ -877,24 +857,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
|
||||
/* Enable IQ, ADC Gain and ADC DC offset CALs */
|
||||
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
|
||||
ah->supp_cals = IQ_MISMATCH_CAL;
|
||||
|
||||
if (AR_SREV_9160_10_OR_LATER(ah) &&
|
||||
!(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
|
||||
ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
|
||||
|
||||
|
||||
INIT_CAL(&ah->adcgain_caldata);
|
||||
INSERT_CAL(ah, &ah->adcgain_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling ADC Gain Calibration.\n");
|
||||
}
|
||||
if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
|
||||
|
||||
INIT_CAL(&ah->adcdc_caldata);
|
||||
INSERT_CAL(ah, &ah->adcdc_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling ADC DC Calibration.\n");
|
||||
}
|
||||
if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
|
||||
INIT_CAL(&ah->iq_caldata);
|
||||
INSERT_CAL(ah, &ah->iq_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling IQ Calibration.\n");
|
||||
}
|
||||
|
||||
INIT_CAL(&ah->iq_caldata);
|
||||
INSERT_CAL(ah, &ah->iq_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling IQ Calibration.\n");
|
||||
|
||||
ah->cal_list_curr = ah->cal_list;
|
||||
|
||||
@ -950,13 +934,6 @@ static const struct ath9k_percal_data adc_dc_cal_single_sample = {
|
||||
ar9002_hw_adc_dccal_collect,
|
||||
ar9002_hw_adc_dccal_calibrate
|
||||
};
|
||||
static const struct ath9k_percal_data adc_init_dc_cal = {
|
||||
ADC_DC_INIT_CAL,
|
||||
MIN_CAL_SAMPLES,
|
||||
INIT_LOG_COUNT,
|
||||
ar9002_hw_adc_dccal_collect,
|
||||
ar9002_hw_adc_dccal_calibrate
|
||||
};
|
||||
|
||||
static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
|
||||
{
|
||||
@ -973,16 +950,12 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
|
||||
&adc_gain_cal_single_sample;
|
||||
ah->adcdc_caldata.calData =
|
||||
&adc_dc_cal_single_sample;
|
||||
ah->adcdc_calinitdata.calData =
|
||||
&adc_init_dc_cal;
|
||||
} else {
|
||||
ah->iq_caldata.calData = &iq_cal_multi_sample;
|
||||
ah->adcgain_caldata.calData =
|
||||
&adc_gain_cal_multi_sample;
|
||||
ah->adcdc_caldata.calData =
|
||||
&adc_dc_cal_multi_sample;
|
||||
ah->adcdc_calinitdata.calData =
|
||||
&adc_init_dc_cal;
|
||||
}
|
||||
ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
|
||||
}
|
||||
@ -996,7 +969,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
|
||||
priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
|
||||
priv_ops->init_cal = ar9002_hw_init_cal;
|
||||
priv_ops->setup_calibration = ar9002_hw_setup_calibration;
|
||||
priv_ops->iscal_supported = ar9002_hw_iscal_supported;
|
||||
|
||||
ops->calibrate = ar9002_hw_calibrate;
|
||||
}
|
||||
|
@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
|
||||
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
|
||||
@ -574,11 +572,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
|
||||
|
||||
ar9002_hw_attach_calib_ops(ah);
|
||||
ar9002_hw_attach_mac_ops(ah);
|
||||
|
||||
if (modparam_force_new_ani)
|
||||
ath9k_hw_attach_ani_ops_new(ah);
|
||||
else
|
||||
ath9k_hw_attach_ani_ops_old(ah);
|
||||
}
|
||||
|
||||
void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
@ -627,6 +620,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
}
|
||||
|
@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ar9002_olc_init(struct ath_hw *ah)
|
||||
|
@ -18,6 +18,11 @@
|
||||
#include "hw-ops.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
enum ar9003_cal_types {
|
||||
IQ_MISMATCH_CAL = BIT(0),
|
||||
TEMP_COMP_CAL = BIT(1),
|
||||
};
|
||||
|
||||
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal)
|
||||
{
|
||||
@ -50,11 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"starting Temperature Compensation Calibration\n");
|
||||
break;
|
||||
case ADC_DC_INIT_CAL:
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
/* Not yet */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
|
||||
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
|
||||
{
|
||||
ah->iq_caldata.calData = &iq_cal_single_sample;
|
||||
ah->supp_cals = IQ_MISMATCH_CAL;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType)
|
||||
{
|
||||
switch (calType & ah->supp_cals) {
|
||||
case IQ_MISMATCH_CAL:
|
||||
/*
|
||||
* XXX: Run IQ Mismatch for non-CCK only
|
||||
* Note that CHANNEL_B is never set though.
|
||||
*/
|
||||
return true;
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
return false;
|
||||
case TEMP_COMP_CAL:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -773,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
|
||||
/* Initialize list pointers */
|
||||
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
||||
ah->supp_cals = IQ_MISMATCH_CAL;
|
||||
|
||||
if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
|
||||
if (ah->supp_cals & IQ_MISMATCH_CAL) {
|
||||
INIT_CAL(&ah->iq_caldata);
|
||||
INSERT_CAL(ah, &ah->iq_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling IQ Calibration.\n");
|
||||
}
|
||||
|
||||
if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
|
||||
if (ah->supp_cals & TEMP_COMP_CAL) {
|
||||
INIT_CAL(&ah->tempCompCalData);
|
||||
INSERT_CAL(ah, &ah->tempCompCalData);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
@ -808,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
|
||||
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
|
||||
priv_ops->init_cal = ar9003_hw_init_cal;
|
||||
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
|
||||
priv_ops->iscal_supported = ar9003_hw_iscal_supported;
|
||||
|
||||
ops->calibrate = ar9003_hw_calibrate;
|
||||
}
|
||||
|
@ -333,6 +333,4 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
|
||||
ar9003_hw_attach_phy_ops(ah);
|
||||
ar9003_hw_attach_calib_ops(ah);
|
||||
ar9003_hw_attach_mac_ops(ah);
|
||||
|
||||
ath9k_hw_attach_ani_ops_new(ah);
|
||||
}
|
||||
|
@ -747,9 +747,9 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
|
||||
static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd, int param)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar5416AniState *aniState = &chan->ani;
|
||||
s32 value, value2;
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
|
||||
"MRCcck=%s listenTime=%d CC=%d listen=%d "
|
||||
"MRCcck=%s listenTime=%d "
|
||||
"ofdmErrs=%d cckErrs=%d\n",
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
||||
aniState->firstepLevel,
|
||||
!aniState->mrcCCKOff ? "on" : "off",
|
||||
aniState->listenTime,
|
||||
aniState->cycleCount,
|
||||
aniState->listenTime,
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
return true;
|
||||
@ -1067,12 +1065,9 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ath9k_ani_default *iniDef;
|
||||
int index;
|
||||
u32 val;
|
||||
|
||||
index = ath9k_hw_get_ani_channel_idx(ah, chan);
|
||||
aniState = &ah->ani[index];
|
||||
ah->curani = aniState;
|
||||
aniState = &ah->curchan->ani;
|
||||
iniDef = &aniState->iniDef;
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
@ -1116,8 +1111,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
|
||||
|
||||
aniState->cycleCount = 0;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
@ -1232,7 +1225,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
|
||||
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
|
||||
u32 status;
|
||||
|
||||
if (likely(!(common->debug_mask & ATH_DBG_RESET)))
|
||||
return;
|
||||
@ -1261,11 +1254,13 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
|
||||
"** BB mode: BB_gen_controls=0x%08x **\n",
|
||||
REG_READ(ah, AR_PHY_GEN_CTRL));
|
||||
|
||||
if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
|
||||
ath9k_hw_update_cycle_counters(ah);
|
||||
#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
|
||||
if (ah->cc_delta.cycles)
|
||||
ath_print(common, ATH_DBG_RESET,
|
||||
"** BB busy times: rx_clear=%d%%, "
|
||||
"rx_frame=%d%%, tx_frame=%d%% **\n",
|
||||
rxc_pcnt, rxf_pcnt, txf_pcnt);
|
||||
PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
|
||||
|
||||
ath_print(common, ATH_DBG_RESET,
|
||||
"==== BB update: done ====\n\n");
|
||||
|
@ -241,7 +241,6 @@ struct ath_buf {
|
||||
dma_addr_t bf_daddr; /* physical addr of desc */
|
||||
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
|
||||
bool bf_stale;
|
||||
bool bf_isnullfunc;
|
||||
bool bf_tx_aborted;
|
||||
u16 bf_flags;
|
||||
struct ath_buf_state bf_state;
|
||||
@ -349,7 +348,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn);
|
||||
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
|
||||
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
|
||||
void ath9k_enable_ps(struct ath_softc *sc);
|
||||
|
||||
/********/
|
||||
/* VIFs */
|
||||
@ -573,8 +571,6 @@ struct ath_ant_comb {
|
||||
#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
|
||||
#define PS_WAIT_FOR_TX_ACK BIT(3)
|
||||
#define PS_BEACON_SYNC BIT(4)
|
||||
#define PS_NULLFUNC_COMPLETED BIT(5)
|
||||
#define PS_ENABLED BIT(6)
|
||||
|
||||
struct ath_wiphy;
|
||||
struct ath_rate_table;
|
||||
|
@ -186,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
|
||||
if (!(ah->supp_cals & currCal->calData->calType))
|
||||
return true;
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
}
|
||||
}
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
|
||||
@ -346,34 +345,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
struct ieee80211_channel *c = chan->chan;
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
|
||||
if (!caldata)
|
||||
return false;
|
||||
|
||||
chan->channelFlags &= (~CHANNEL_CW_INT);
|
||||
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF did not complete in calibration window\n");
|
||||
nf = 0;
|
||||
caldata->rawNoiseFloor = nf;
|
||||
return false;
|
||||
} else {
|
||||
ath9k_hw_do_getnf(ah, nfarray);
|
||||
ath9k_hw_nf_sanitize(ah, nfarray);
|
||||
nf = nfarray[0];
|
||||
if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
|
||||
&& nf > nfThresh) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"noise floor failed detected; "
|
||||
"detected %d, threshold %d\n",
|
||||
nf, nfThresh);
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
}
|
||||
}
|
||||
|
||||
ath9k_hw_do_getnf(ah, nfarray);
|
||||
ath9k_hw_nf_sanitize(ah, nfarray);
|
||||
nf = nfarray[0];
|
||||
if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
|
||||
&& nf > nfThresh) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"noise floor failed detected; "
|
||||
"detected %d, threshold %d\n",
|
||||
nf, nfThresh);
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
}
|
||||
|
||||
if (!caldata) {
|
||||
chan->noisefloor = nf;
|
||||
return false;
|
||||
}
|
||||
|
||||
h = caldata->nfCalHist;
|
||||
caldata->nfcal_pending = false;
|
||||
ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
|
||||
caldata->rawNoiseFloor = h[0].privNF;
|
||||
chan->noisefloor = h[0].privNF;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -401,10 +400,10 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
|
||||
|
||||
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
if (!ah->caldata || !ah->caldata->rawNoiseFloor)
|
||||
if (!ah->curchan || !ah->curchan->noisefloor)
|
||||
return ath9k_hw_get_default_nf(ah, chan);
|
||||
|
||||
return ah->caldata->rawNoiseFloor;
|
||||
return ah->curchan->noisefloor;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_getchan_noise);
|
||||
|
||||
|
@ -58,14 +58,6 @@ struct ar5416IniArray {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
enum ath9k_cal_types {
|
||||
ADC_DC_INIT_CAL = 0x1,
|
||||
ADC_GAIN_CAL = 0x2,
|
||||
ADC_DC_CAL = 0x4,
|
||||
IQ_MISMATCH_CAL = 0x8,
|
||||
TEMP_COMP_CAL = 0x10,
|
||||
};
|
||||
|
||||
enum ath9k_cal_state {
|
||||
CAL_INACTIVE,
|
||||
CAL_WAITING,
|
||||
@ -80,7 +72,7 @@ enum ath9k_cal_state {
|
||||
#define PER_MAX_LOG_COUNT 10
|
||||
|
||||
struct ath9k_percal_data {
|
||||
enum ath9k_cal_types calType;
|
||||
u32 calType;
|
||||
u32 calNumSamples;
|
||||
u32 calCountMax;
|
||||
void (*calCollect) (struct ath_hw *);
|
||||
|
@ -488,6 +488,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_wiphy *aphy = sc->pri_wiphy;
|
||||
struct ieee80211_channel *chan = aphy->hw->conf.channel;
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
int i;
|
||||
@ -498,7 +500,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
|
||||
"primary: %s (%s chan=%d ht=%d)\n",
|
||||
wiphy_name(sc->pri_wiphy->hw->wiphy),
|
||||
ath_wiphy_state_str(sc->pri_wiphy->state),
|
||||
sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
|
||||
ieee80211_frequency_to_channel(chan->center_freq),
|
||||
aphy->chan_is_ht);
|
||||
|
||||
put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
|
||||
put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
|
||||
@ -545,11 +548,13 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
|
||||
struct ath_wiphy *aphy = sc->sec_wiphy[i];
|
||||
if (aphy == NULL)
|
||||
continue;
|
||||
chan = aphy->hw->conf.channel;
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"secondary: %s (%s chan=%d ht=%d)\n",
|
||||
wiphy_name(aphy->hw->wiphy),
|
||||
ath_wiphy_state_str(aphy->state),
|
||||
aphy->chan_idx, aphy->chan_is_ht);
|
||||
"secondary: %s (%s chan=%d ht=%d)\n",
|
||||
wiphy_name(aphy->hw->wiphy),
|
||||
ath_wiphy_state_str(aphy->state),
|
||||
ieee80211_frequency_to_channel(chan->center_freq),
|
||||
aphy->chan_is_ht);
|
||||
}
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
@ -696,6 +701,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
PR("DESC CFG Error: ", desc_cfg_err);
|
||||
PR("DATA Underrun: ", data_underrun);
|
||||
PR("DELIM Underrun: ", delim_underrun);
|
||||
PR("TX-Pkts-All: ", tx_pkts_all);
|
||||
PR("TX-Bytes-All: ", tx_bytes_all);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
@ -709,6 +716,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_buf *bf, struct ath_tx_status *ts)
|
||||
{
|
||||
TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
|
||||
sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
|
||||
|
||||
if (bf_isampdu(bf)) {
|
||||
if (bf_isxretried(bf))
|
||||
TX_STAT_INC(txq->axq_qnum, a_xretries);
|
||||
@ -803,6 +813,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
|
||||
PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
|
||||
PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%18s : %10u\n", "RX-Pkts-All",
|
||||
sc->debug.stats.rxstats.rx_pkts_all);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%18s : %10u\n", "RX-Bytes-All",
|
||||
sc->debug.stats.rxstats.rx_bytes_all);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
@ -821,6 +838,9 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
|
||||
|
||||
u32 phyerr;
|
||||
|
||||
RX_STAT_INC(rx_pkts_all);
|
||||
sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
|
||||
|
||||
if (rs->rs_status & ATH9K_RXERR_CRC)
|
||||
RX_STAT_INC(crc_err);
|
||||
if (rs->rs_status & ATH9K_RXERR_DECRYPT)
|
||||
|
@ -89,6 +89,10 @@ struct ath_rc_stats {
|
||||
|
||||
/**
|
||||
* struct ath_tx_stats - Statistics about TX
|
||||
* @tx_pkts_all: No. of total frames transmitted, including ones that
|
||||
may have had errors.
|
||||
* @tx_bytes_all: No. of total bytes transmitted, including ones that
|
||||
may have had errors.
|
||||
* @queued: Total MPDUs (non-aggr) queued
|
||||
* @completed: Total MPDUs (non-aggr) completed
|
||||
* @a_aggr: Total no. of aggregates queued
|
||||
@ -107,6 +111,8 @@ struct ath_rc_stats {
|
||||
* @delim_urn: TX delimiter underrun errors
|
||||
*/
|
||||
struct ath_tx_stats {
|
||||
u32 tx_pkts_all;
|
||||
u32 tx_bytes_all;
|
||||
u32 queued;
|
||||
u32 completed;
|
||||
u32 a_aggr;
|
||||
@ -124,6 +130,10 @@ struct ath_tx_stats {
|
||||
|
||||
/**
|
||||
* struct ath_rx_stats - RX Statistics
|
||||
* @rx_pkts_all: No. of total frames received, including ones that
|
||||
may have had errors.
|
||||
* @rx_bytes_all: No. of total bytes received, including ones that
|
||||
may have had errors.
|
||||
* @crc_err: No. of frames with incorrect CRC value
|
||||
* @decrypt_crc_err: No. of frames whose CRC check failed after
|
||||
decryption process completed
|
||||
@ -136,6 +146,8 @@ struct ath_tx_stats {
|
||||
* @phy_err_stats: Individual PHY error statistics
|
||||
*/
|
||||
struct ath_rx_stats {
|
||||
u32 rx_pkts_all;
|
||||
u32 rx_bytes_all;
|
||||
u32 crc_err;
|
||||
u32 decrypt_crc_err;
|
||||
u32 phy_err;
|
||||
|
@ -179,6 +179,9 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
|
||||
struct modal_eep_4k_header *pModal = &eep->modalHeader;
|
||||
struct base_eep_header_4k *pBase = &eep->baseEepHeader;
|
||||
u16 ver_minor;
|
||||
|
||||
ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK;
|
||||
|
||||
switch (param) {
|
||||
case EEP_NFTHRESH_2:
|
||||
@ -204,7 +207,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
case EEP_DB_2:
|
||||
return pModal->db1_1;
|
||||
case EEP_MINOR_REV:
|
||||
return pBase->version & AR5416_EEP_VER_MINOR_MASK;
|
||||
return ver_minor;
|
||||
case EEP_TX_MASK:
|
||||
return pBase->txMask;
|
||||
case EEP_RX_MASK:
|
||||
@ -217,6 +220,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
return pModal->version;
|
||||
case EEP_ANT_DIV_CTL1:
|
||||
return pModal->antdiv_ctl1;
|
||||
case EEP_TXGAIN_TYPE:
|
||||
if (ver_minor >= AR5416_EEP_MINOR_VER_19)
|
||||
return pBase->txGainType;
|
||||
else
|
||||
return AR5416_EEP_TXGAIN_ORIGINAL;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -500,7 +508,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
}
|
||||
|
||||
@ -832,7 +839,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
|
||||
|
@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
|
||||
atomic_inc(&priv->wmi->mwrite_cnt);
|
||||
}
|
||||
|
||||
static void ath9k_disable_regwrite_buffer(void *hw_priv)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
|
||||
atomic_dec(&priv->wmi->mwrite_cnt);
|
||||
}
|
||||
|
||||
static void ath9k_regwrite_flush(void *hw_priv)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
@ -397,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv)
|
||||
u32 rsp_status;
|
||||
int r;
|
||||
|
||||
atomic_dec(&priv->wmi->mwrite_cnt);
|
||||
|
||||
mutex_lock(&priv->wmi->multi_write_mutex);
|
||||
|
||||
if (priv->wmi->multi_write_idx) {
|
||||
@ -420,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = {
|
||||
.read = ath9k_regread,
|
||||
.write = ath9k_regwrite,
|
||||
.enable_write_buffer = ath9k_enable_regwrite_buffer,
|
||||
.disable_write_buffer = ath9k_disable_regwrite_buffer,
|
||||
.write_flush = ath9k_regwrite_flush,
|
||||
};
|
||||
|
||||
|
@ -760,23 +760,12 @@ void ath9k_ani_work(struct work_struct *work)
|
||||
ath9k_hw_ani_monitor(ah, ah->curchan);
|
||||
|
||||
/* Perform calibration if necessary */
|
||||
if (longcal || shortcal) {
|
||||
if (longcal || shortcal)
|
||||
common->ani.caldone =
|
||||
ath9k_hw_calibrate(ah, ah->curchan,
|
||||
common->rx_chainmask,
|
||||
longcal);
|
||||
|
||||
if (longcal)
|
||||
common->ani.noise_floor =
|
||||
ath9k_hw_getchan_noise(ah, ah->curchan);
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
" calibrate chan %u/%x nf: %d\n",
|
||||
ah->curchan->channel,
|
||||
ah->curchan->channelFlags,
|
||||
common->ani.noise_floor);
|
||||
}
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
}
|
||||
|
||||
|
@ -128,17 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
|
||||
ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_procmibevent(struct ath_hw *ah)
|
||||
{
|
||||
ath9k_hw_ops(ah)->ani_proc_mib_event(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_ani_monitor(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
ath9k_hw_ops(ah)->ani_monitor(ah, chan);
|
||||
}
|
||||
|
||||
/* Private hardware call ops */
|
||||
|
||||
/* PHY ops */
|
||||
@ -276,15 +265,4 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
|
||||
ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
|
||||
}
|
||||
|
||||
static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning);
|
||||
}
|
||||
|
||||
#endif /* ATH9K_HW_OPS_H */
|
||||
|
@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
/* This should work for all families including legacy */
|
||||
@ -371,10 +370,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
|
||||
ah->config.pcie_clock_req = 0;
|
||||
ah->config.pcie_waen = 0;
|
||||
ah->config.analog_shiftreg = 1;
|
||||
ah->config.ofdm_trig_low = 200;
|
||||
ah->config.ofdm_trig_high = 500;
|
||||
ah->config.cck_trig_high = 200;
|
||||
ah->config.cck_trig_low = 100;
|
||||
ah->config.enable_ani = true;
|
||||
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
@ -676,7 +671,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
@ -741,7 +735,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
|
||||
@ -885,7 +878,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
/*
|
||||
* Restore TX Trigger Level to its pre-reset value.
|
||||
@ -933,7 +925,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
ath9k_hw_reset_txstatus_ring(ah);
|
||||
@ -1031,7 +1022,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
||||
REG_WRITE(ah, AR_RTC_RC, rst_flags);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
udelay(50);
|
||||
|
||||
@ -1070,7 +1060,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
|
||||
udelay(2);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah))
|
||||
udelay(2);
|
||||
@ -1239,7 +1228,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
|
||||
return -EIO;
|
||||
|
||||
if (curchan && !ah->chip_fullsleep && ah->caldata)
|
||||
if (curchan && !ah->chip_fullsleep)
|
||||
ath9k_hw_getnf(ah, curchan);
|
||||
|
||||
ah->caldata = caldata;
|
||||
@ -1374,7 +1363,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
r = ath9k_hw_rf_set_freq(ah, chan);
|
||||
if (r)
|
||||
@ -1386,7 +1374,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ah->intr_txqs = 0;
|
||||
for (i = 0; i < ah->caps.total_queues; i++)
|
||||
@ -1434,7 +1421,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
/*
|
||||
* For big endian systems turn on swapping for descriptors
|
||||
@ -1684,7 +1670,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
|
||||
REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
beacon_period &= ~ATH9K_BEACON_ENA;
|
||||
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
|
||||
@ -1712,7 +1697,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_RSSI_THR,
|
||||
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
|
||||
@ -1758,7 +1742,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_SET_BIT(ah, AR_TIMER_MODE,
|
||||
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
|
||||
@ -2176,7 +2159,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
|
||||
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setrxfilter);
|
||||
|
||||
|
@ -70,19 +70,13 @@
|
||||
|
||||
#define ENABLE_REGWRITE_BUFFER(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
|
||||
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
|
||||
} while (0)
|
||||
|
||||
#define DISABLE_REGWRITE_BUFFER(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
|
||||
} while (0)
|
||||
|
||||
#define REGWRITE_BUFFER_FLUSH(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
if (ath9k_hw_common(_ah)->ops->write_flush) \
|
||||
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
|
||||
} while (0)
|
||||
|
||||
@ -342,7 +336,6 @@ struct ath9k_hw_cal_data {
|
||||
int32_t CalValid;
|
||||
int8_t iCoff;
|
||||
int8_t qCoff;
|
||||
int16_t rawNoiseFloor;
|
||||
bool paprd_done;
|
||||
bool nfcal_pending;
|
||||
bool nfcal_interference;
|
||||
@ -353,9 +346,11 @@ struct ath9k_hw_cal_data {
|
||||
|
||||
struct ath9k_channel {
|
||||
struct ieee80211_channel *chan;
|
||||
struct ar5416AniState ani;
|
||||
u16 channel;
|
||||
u32 channelFlags;
|
||||
u32 chanmode;
|
||||
s16 noisefloor;
|
||||
};
|
||||
|
||||
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
|
||||
@ -514,14 +509,6 @@ struct ath_hw_antcomb_conf {
|
||||
* @setup_calibration: set up calibration
|
||||
* @iscal_supported: used to query if a type of calibration is supported
|
||||
*
|
||||
* @ani_reset: reset ANI parameters to default values
|
||||
* @ani_lower_immunity: lower the noise immunity level. The level controls
|
||||
* the power-based packet detection on hardware. If a power jump is
|
||||
* detected the adapter takes it as an indication that a packet has
|
||||
* arrived. The level ranges from 0-5. Each level corresponds to a
|
||||
* few dB more of noise immunity. If you have a strong time-varying
|
||||
* interference that is causing false detections (OFDM timing errors or
|
||||
* CCK timing errors) the level can be increased.
|
||||
* @ani_cache_ini_regs: cache the values for ANI from the initial
|
||||
* register settings through the register initialization.
|
||||
*/
|
||||
@ -535,8 +522,6 @@ struct ath_hw_private_ops {
|
||||
bool (*macversion_supported)(u32 macversion);
|
||||
void (*setup_calibration)(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal);
|
||||
bool (*iscal_supported)(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType);
|
||||
|
||||
/* PHY ops */
|
||||
int (*rf_set_freq)(struct ath_hw *ah,
|
||||
@ -568,8 +553,6 @@ struct ath_hw_private_ops {
|
||||
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
|
||||
|
||||
/* ANI */
|
||||
void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
|
||||
void (*ani_lower_immunity)(struct ath_hw *ah);
|
||||
void (*ani_cache_ini_regs)(struct ath_hw *ah);
|
||||
};
|
||||
|
||||
@ -581,11 +564,6 @@ struct ath_hw_private_ops {
|
||||
*
|
||||
* @config_pci_powersave:
|
||||
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
|
||||
*
|
||||
* @ani_proc_mib_event: process MIB events, this would happen upon specific ANI
|
||||
* thresholds being reached or having overflowed.
|
||||
* @ani_monitor: called periodically by the core driver to collect
|
||||
* MIB stats and adjust ANI if specific thresholds have been reached.
|
||||
*/
|
||||
struct ath_hw_ops {
|
||||
void (*config_pci_powersave)(struct ath_hw *ah,
|
||||
@ -626,9 +604,6 @@ struct ath_hw_ops {
|
||||
u32 burstDuration);
|
||||
void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
|
||||
u32 vmf);
|
||||
|
||||
void (*ani_proc_mib_event)(struct ath_hw *ah);
|
||||
void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
};
|
||||
|
||||
struct ath_nf_limits {
|
||||
@ -689,10 +664,9 @@ struct ath_hw {
|
||||
u32 atim_window;
|
||||
|
||||
/* Calibration */
|
||||
enum ath9k_cal_types supp_cals;
|
||||
u32 supp_cals;
|
||||
struct ath9k_cal_list iq_caldata;
|
||||
struct ath9k_cal_list adcgain_caldata;
|
||||
struct ath9k_cal_list adcdc_calinitdata;
|
||||
struct ath9k_cal_list adcdc_caldata;
|
||||
struct ath9k_cal_list tempCompCalData;
|
||||
struct ath9k_cal_list *cal_list;
|
||||
@ -761,13 +735,13 @@ struct ath_hw {
|
||||
/* ANI */
|
||||
u32 proc_phyerr;
|
||||
u32 aniperiod;
|
||||
struct ar5416AniState *curani;
|
||||
struct ar5416AniState ani[255];
|
||||
int totalSizeDesired[5];
|
||||
int coarse_high[5];
|
||||
int coarse_low[5];
|
||||
int firpwr[5];
|
||||
enum ath9k_ani_cmd ani_function;
|
||||
struct ath_cycle_counters cc, cc_delta;
|
||||
int32_t listen_time;
|
||||
|
||||
/* Bluetooth coexistance */
|
||||
struct ath_btcoex_hw btcoex_hw;
|
||||
@ -988,8 +962,9 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
* older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
|
||||
*/
|
||||
extern int modparam_force_new_ani;
|
||||
void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah);
|
||||
void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah);
|
||||
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
|
||||
void ath9k_hw_proc_mib_event(struct ath_hw *ah);
|
||||
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
#define ATH_PCIE_CAP_LINK_CTRL 0x70
|
||||
#define ATH_PCIE_CAP_LINK_L0S 1
|
||||
|
@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
|
||||
* on 5 MHz steps, we support the channels which we know
|
||||
* we have calibration data for all cards though to make
|
||||
* this static */
|
||||
static struct ieee80211_channel ath9k_2ghz_chantable[] = {
|
||||
static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
|
||||
CHAN2G(2412, 0), /* Channel 1 */
|
||||
CHAN2G(2417, 1), /* Channel 2 */
|
||||
CHAN2G(2422, 2), /* Channel 3 */
|
||||
@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = {
|
||||
* on 5 MHz steps, we support the channels which we know
|
||||
* we have calibration data for all cards though to make
|
||||
* this static */
|
||||
static struct ieee80211_channel ath9k_5ghz_chantable[] = {
|
||||
static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
|
||||
/* _We_ call this UNII 1 */
|
||||
CHAN5G(5180, 14), /* Channel 36 */
|
||||
CHAN5G(5200, 15), /* Channel 40 */
|
||||
@ -477,10 +477,17 @@ err:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void ath9k_init_channels_rates(struct ath_softc *sc)
|
||||
static int ath9k_init_channels_rates(struct ath_softc *sc)
|
||||
{
|
||||
void *channels;
|
||||
|
||||
if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
|
||||
sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
|
||||
channels = kmemdup(ath9k_2ghz_chantable,
|
||||
sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
|
||||
if (!channels)
|
||||
return -ENOMEM;
|
||||
|
||||
sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
|
||||
sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
|
||||
sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
|
||||
ARRAY_SIZE(ath9k_2ghz_chantable);
|
||||
@ -490,7 +497,15 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
|
||||
}
|
||||
|
||||
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
|
||||
sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
|
||||
channels = kmemdup(ath9k_5ghz_chantable,
|
||||
sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
|
||||
if (!channels) {
|
||||
if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
|
||||
kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
|
||||
sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
|
||||
sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
|
||||
ARRAY_SIZE(ath9k_5ghz_chantable);
|
||||
@ -499,6 +514,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
|
||||
sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
|
||||
ARRAY_SIZE(ath9k_legacy_rates) - 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_init_misc(struct ath_softc *sc)
|
||||
@ -506,7 +522,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
int i = 0;
|
||||
|
||||
common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
|
||||
setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
|
||||
|
||||
sc->config.txpowlimit = ATH_TXPOWER_MAX;
|
||||
@ -595,8 +610,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
if (ret)
|
||||
goto err_btcoex;
|
||||
|
||||
ret = ath9k_init_channels_rates(sc);
|
||||
if (ret)
|
||||
goto err_btcoex;
|
||||
|
||||
ath9k_init_crypto(sc);
|
||||
ath9k_init_channels_rates(sc);
|
||||
ath9k_init_misc(sc);
|
||||
|
||||
return 0;
|
||||
@ -639,6 +657,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_WDS) |
|
||||
BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
@ -756,6 +775,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
|
||||
kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
|
||||
|
||||
if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
|
||||
kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
|
||||
|
||||
if ((sc->btcoex.no_stomp_timer) &&
|
||||
sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
|
||||
ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
|
||||
|
@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
|
||||
@ -492,8 +491,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
REG_WRITE(ah, AR_DMISC(q),
|
||||
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
if (qi->tqi_cbrPeriod) {
|
||||
REG_WRITE(ah, AR_QCBRCFG(q),
|
||||
SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
|
||||
@ -509,8 +506,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
AR_Q_RDYTIMECFG_EN);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
REG_WRITE(ah, AR_DCHNTIME(q),
|
||||
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
|
||||
(qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
|
||||
@ -530,7 +525,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
|
||||
REG_WRITE(ah, AR_DMISC(q),
|
||||
@ -553,7 +547,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
| AR_D_MISC_POST_FR_BKOFF_DIS);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
/*
|
||||
* cwmin and cwmax should be 0 for beacon queue
|
||||
@ -585,7 +578,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
break;
|
||||
case ATH9K_TX_QUEUE_PSPOLL:
|
||||
|
@ -459,16 +459,6 @@ void ath_ani_calibrate(unsigned long data)
|
||||
ah->curchan,
|
||||
common->rx_chainmask,
|
||||
longcal);
|
||||
|
||||
if (longcal)
|
||||
common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
|
||||
ah->curchan);
|
||||
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
" calibrate chan %u/%x nf: %d\n",
|
||||
ah->curchan->channel,
|
||||
ah->curchan->channelFlags,
|
||||
common->ani.noise_floor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,7 +713,7 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
* it will clear whatever condition caused
|
||||
* the interrupt.
|
||||
*/
|
||||
ath9k_hw_procmibevent(ah);
|
||||
ath9k_hw_proc_mib_event(ah);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
}
|
||||
|
||||
@ -1384,6 +1374,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
|
||||
case NL80211_IFTYPE_STATION:
|
||||
ic_opmode = NL80211_IFTYPE_STATION;
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
ic_opmode = NL80211_IFTYPE_WDS;
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
@ -1491,7 +1484,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
void ath9k_enable_ps(struct ath_softc *sc)
|
||||
static void ath9k_enable_ps(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
@ -1505,13 +1498,32 @@ void ath9k_enable_ps(struct ath_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_disable_ps(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
sc->ps_enabled = false;
|
||||
ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
|
||||
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
|
||||
ath9k_hw_setrxabort(ah, 0);
|
||||
sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
PS_WAIT_FOR_TX_ACK);
|
||||
if (ah->imask & ATH9K_INT_TIM_TIMER) {
|
||||
ah->imask &= ~ATH9K_INT_TIM_TIMER;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
bool disable_radio;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
@ -1558,35 +1570,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||
if (conf->flags & IEEE80211_CONF_PS) {
|
||||
sc->ps_flags |= PS_ENABLED;
|
||||
/*
|
||||
* At this point we know hardware has received an ACK
|
||||
* of a previously sent null data frame.
|
||||
*/
|
||||
if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
|
||||
sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
|
||||
ath9k_enable_ps(sc);
|
||||
}
|
||||
} else {
|
||||
sc->ps_enabled = false;
|
||||
sc->ps_flags &= ~(PS_ENABLED |
|
||||
PS_NULLFUNC_COMPLETED);
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
|
||||
if (!(ah->caps.hw_caps &
|
||||
ATH9K_HW_CAP_AUTOSLEEP)) {
|
||||
ath9k_hw_setrxabort(sc->sc_ah, 0);
|
||||
sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
PS_WAIT_FOR_TX_ACK);
|
||||
if (ah->imask & ATH9K_INT_TIM_TIMER) {
|
||||
ah->imask &= ~ATH9K_INT_TIM_TIMER;
|
||||
ath9k_hw_set_interrupts(sc->sc_ah,
|
||||
ah->imask);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conf->flags & IEEE80211_CONF_PS)
|
||||
ath9k_enable_ps(sc);
|
||||
else
|
||||
ath9k_disable_ps(sc);
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
}
|
||||
|
||||
@ -2004,15 +1991,32 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ath9k_channel *chan;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
if (sband && idx >= sband->n_channels) {
|
||||
idx -= sband->n_channels;
|
||||
sband = NULL;
|
||||
}
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = common->ani.noise_floor;
|
||||
if (!sband)
|
||||
sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (!sband || idx >= sband->n_channels)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = &sband->channels[idx];
|
||||
chan = &ah->channels[survey->channel->hw_value];
|
||||
survey->filled = 0;
|
||||
|
||||
if (chan == ah->curchan)
|
||||
survey->filled |= SURVEY_INFO_IN_USE;
|
||||
|
||||
if (chan->noisefloor) {
|
||||
survey->filled |= SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = chan->noisefloor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1648,13 +1648,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
|
||||
|
||||
bf->bf_buf_addr = bf->bf_dmacontext;
|
||||
|
||||
/* tag if this is a nullfunc frame to enable PS when AP acks it */
|
||||
if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
|
||||
bf->bf_isnullfunc = true;
|
||||
sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
|
||||
} else
|
||||
bf->bf_isnullfunc = false;
|
||||
|
||||
bf->bf_tx_aborted = false;
|
||||
|
||||
return 0;
|
||||
@ -2081,18 +2074,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We now know the nullfunc frame has been ACKed so we
|
||||
* can disable RX.
|
||||
*/
|
||||
if (bf->bf_isnullfunc &&
|
||||
(ts.ts_status & ATH9K_TX_ACKED)) {
|
||||
if ((sc->ps_flags & PS_ENABLED))
|
||||
ath9k_enable_ps(sc);
|
||||
else
|
||||
sc->ps_flags |= PS_NULLFUNC_COMPLETED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove ath_buf's of the same transmit unit from txq,
|
||||
* however leave the last descriptor back as the holding
|
||||
@ -2236,17 +2217,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
|
||||
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
|
||||
|
||||
/*
|
||||
* Make sure null func frame is acked before configuring
|
||||
* hw into ps mode.
|
||||
*/
|
||||
if (bf->bf_isnullfunc && txok) {
|
||||
if ((sc->ps_flags & PS_ENABLED))
|
||||
ath9k_enable_ps(sc);
|
||||
else
|
||||
sc->ps_flags |= PS_NULLFUNC_COMPLETED;
|
||||
}
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
if (txs.ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
|
@ -279,6 +279,7 @@ struct ar9170 {
|
||||
unsigned int beacon_max_len;
|
||||
bool rx_stream;
|
||||
bool tx_stream;
|
||||
bool rx_filter;
|
||||
unsigned int mem_blocks;
|
||||
unsigned int mem_block_size;
|
||||
unsigned int rx_size;
|
||||
@ -314,6 +315,7 @@ struct ar9170 {
|
||||
u64 cur_mc_hash;
|
||||
u32 cur_filter;
|
||||
unsigned int filter_state;
|
||||
unsigned int rx_filter_caps;
|
||||
bool sniffer_enabled;
|
||||
|
||||
/* MAC */
|
||||
|
@ -59,6 +59,16 @@ static inline int carl9170_flush_cab(struct ar9170 *ar,
|
||||
return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
|
||||
}
|
||||
|
||||
static inline int carl9170_rx_filter(struct ar9170 *ar,
|
||||
const unsigned int _rx_filter)
|
||||
{
|
||||
__le32 rx_filter = cpu_to_le32(_rx_filter);
|
||||
|
||||
return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER,
|
||||
sizeof(rx_filter), (u8 *)&rx_filter,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
|
||||
const enum carl9170_cmd_oids cmd, const unsigned int len);
|
||||
|
||||
|
@ -257,6 +257,13 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
|
||||
if (SUPP(CARL9170FW_USB_UP_STREAM))
|
||||
ar->fw.rx_stream = true;
|
||||
|
||||
if (SUPP(CARL9170FW_RX_FILTER)) {
|
||||
ar->fw.rx_filter = true;
|
||||
ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL |
|
||||
FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS |
|
||||
FIF_PROMISC_IN_BSS;
|
||||
}
|
||||
|
||||
ar->fw.vif_num = otus_desc->vif_num;
|
||||
ar->fw.cmd_bufs = otus_desc->cmd_bufs;
|
||||
ar->fw.address = le32_to_cpu(otus_desc->fw_address);
|
||||
|
@ -53,6 +53,7 @@ enum carl9170_cmd_oids {
|
||||
CARL9170_CMD_REBOOT = 0x04,
|
||||
CARL9170_CMD_BCN_CTRL = 0x05,
|
||||
CARL9170_CMD_READ_TSF = 0x06,
|
||||
CARL9170_CMD_RX_FILTER = 0x07,
|
||||
|
||||
/* CAM */
|
||||
CARL9170_CMD_EKEY = 0x10,
|
||||
@ -153,6 +154,20 @@ struct carl9170_psm {
|
||||
} __packed;
|
||||
#define CARL9170_PSM_SIZE 4
|
||||
|
||||
struct carl9170_rx_filter_cmd {
|
||||
__le32 rx_filter;
|
||||
} __packed;
|
||||
#define CARL9170_RX_FILTER_CMD_SIZE 4
|
||||
|
||||
#define CARL9170_RX_FILTER_BAD 0x01
|
||||
#define CARL9170_RX_FILTER_OTHER_RA 0x02
|
||||
#define CARL9170_RX_FILTER_DECRY_FAIL 0x04
|
||||
#define CARL9170_RX_FILTER_CTL_OTHER 0x08
|
||||
#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10
|
||||
#define CARL9170_RX_FILTER_CTL_BACKR 0x20
|
||||
#define CARL9170_RX_FILTER_MGMT 0x40
|
||||
#define CARL9170_RX_FILTER_DATA 0x80
|
||||
|
||||
struct carl9170_bcn_ctrl_cmd {
|
||||
__le32 vif_id;
|
||||
__le32 mode;
|
||||
@ -188,6 +203,7 @@ struct carl9170_cmd {
|
||||
struct carl9170_rf_init rf_init;
|
||||
struct carl9170_psm psm;
|
||||
struct carl9170_bcn_ctrl_cmd bcn_ctrl;
|
||||
struct carl9170_rx_filter_cmd rx_filter;
|
||||
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
@ -66,6 +66,9 @@ enum carl9170fw_feature_list {
|
||||
/* Firmware PSM support | CARL9170_CMD_PSM */
|
||||
CARL9170FW_PSM,
|
||||
|
||||
/* Firmware RX filter | CARL9170_CMD_RX_FILTER */
|
||||
CARL9170FW_RX_FILTER,
|
||||
|
||||
/* KEEP LAST */
|
||||
__CARL9170FW_FEATURE_NUM
|
||||
};
|
||||
@ -142,7 +145,7 @@ struct carl9170fw_fix_desc {
|
||||
(sizeof(struct carl9170fw_fix_desc))
|
||||
|
||||
#define CARL9170FW_DBG_DESC_MIN_VER 1
|
||||
#define CARL9170FW_DBG_DESC_CUR_VER 2
|
||||
#define CARL9170FW_DBG_DESC_CUR_VER 3
|
||||
struct carl9170fw_dbg_desc {
|
||||
struct carl9170fw_desc_head head;
|
||||
|
||||
@ -150,6 +153,7 @@ struct carl9170fw_dbg_desc {
|
||||
__le32 counter_addr;
|
||||
__le32 rx_total_addr;
|
||||
__le32 rx_overrun_addr;
|
||||
__le32 rx_filter;
|
||||
|
||||
/* Put your debugging definitions here */
|
||||
} __packed;
|
||||
|
@ -731,6 +731,9 @@ struct ar9170_stream {
|
||||
#define SET_VAL(reg, value, newvalue) \
|
||||
(value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg))
|
||||
|
||||
#define SET_CONSTVAL(reg, newvalue) \
|
||||
(((newvalue) << reg##_S) & reg)
|
||||
|
||||
#define MOD_VAL(reg, value, newvalue) \
|
||||
(((value) & ~reg) | (((newvalue) << reg##_S) & reg))
|
||||
#endif /* __CARL9170_SHARED_HW_H */
|
||||
|
@ -380,6 +380,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (ar->fw.rx_filter) {
|
||||
err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA |
|
||||
CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER,
|
||||
AR9170_DMA_TRIGGER_RXQ);
|
||||
if (err)
|
||||
@ -840,8 +847,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
|
||||
struct ar9170 *ar = hw->priv;
|
||||
|
||||
/* mask supported flags */
|
||||
*new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL |
|
||||
FIF_OTHER_BSS | FIF_PROMISC_IN_BSS;
|
||||
*new_flags &= FIF_ALLMULTI | ar->rx_filter_caps;
|
||||
|
||||
if (!IS_ACCEPTING_CMD(ar))
|
||||
return;
|
||||
@ -867,6 +873,26 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
|
||||
WARN_ON(carl9170_set_operating_mode(ar));
|
||||
}
|
||||
|
||||
if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) {
|
||||
u32 rx_filter = 0;
|
||||
|
||||
if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)))
|
||||
rx_filter |= CARL9170_RX_FILTER_BAD;
|
||||
|
||||
if (!(*new_flags & FIF_CONTROL))
|
||||
rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
|
||||
|
||||
if (!(*new_flags & FIF_PSPOLL))
|
||||
rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
|
||||
|
||||
if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) {
|
||||
rx_filter |= CARL9170_RX_FILTER_OTHER_RA;
|
||||
rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL;
|
||||
}
|
||||
|
||||
WARN_ON(carl9170_rx_filter(ar, rx_filter));
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->mutex);
|
||||
}
|
||||
|
||||
|
@ -423,8 +423,8 @@
|
||||
#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
|
||||
#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
|
||||
|
||||
#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
|
||||
#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c)
|
||||
#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
|
||||
#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000
|
||||
#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
|
||||
#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00
|
||||
@ -561,7 +561,4 @@
|
||||
#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
|
||||
#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
|
||||
|
||||
#define REDUCE_CHAIN_0 0x00000050
|
||||
#define REDUCE_CHAIN_1 0x00000051
|
||||
|
||||
#endif /* __CARL9170_SHARED_PHY_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __CARL9170_SHARED_VERSION_H
|
||||
#define __CARL9170_SHARED_VERSION_H
|
||||
#define CARL9170FW_VERSION_YEAR 10
|
||||
#define CARL9170FW_VERSION_MONTH 8
|
||||
#define CARL9170FW_VERSION_DAY 30
|
||||
#define CARL9170FW_VERSION_GIT "1.8.8.1"
|
||||
#define CARL9170FW_VERSION_MONTH 9
|
||||
#define CARL9170FW_VERSION_DAY 28
|
||||
#define CARL9170FW_VERSION_GIT "1.8.8.3"
|
||||
#endif /* __CARL9170_SHARED_VERSION_H */
|
||||
|
@ -186,7 +186,8 @@ enum {
|
||||
#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */
|
||||
#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */
|
||||
#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
|
||||
#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */
|
||||
#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */
|
||||
#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */
|
||||
#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
|
||||
/* TSSI information */
|
||||
#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
|
||||
|
@ -294,8 +294,10 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
|
||||
*/
|
||||
channelcookie = new_channel;
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
|
||||
channelcookie |= 0x100;
|
||||
//FIXME set 40Mhz flag if required
|
||||
channelcookie |= B43_SHM_SH_CHAN_5GHZ;
|
||||
/* FIXME: set 40Mhz flag if required */
|
||||
if (0)
|
||||
channelcookie |= B43_SHM_SH_CHAN_40MHZ;
|
||||
savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
|
||||
|
||||
|
@ -73,7 +73,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
|
||||
u16 value, u8 core, bool off);
|
||||
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
|
||||
u16 value, u8 core);
|
||||
static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
|
||||
|
||||
static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
|
||||
{
|
||||
@ -223,7 +222,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
|
||||
if (i)
|
||||
b43err(dev->wl, "radio post init timeout\n");
|
||||
b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
|
||||
nphy_channel_switch(dev, dev->phy.channel);
|
||||
b43_switch_channel(dev, dev->phy.channel);
|
||||
b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
|
||||
b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
|
||||
b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
|
||||
@ -3351,12 +3350,6 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
|
||||
|
||||
b43_chantab_phy_upload(dev, e);
|
||||
|
||||
tmp = chanspec.channel;
|
||||
if (chanspec.b_freq == 1)
|
||||
tmp |= 0x0100;
|
||||
if (chanspec.b_width == 3)
|
||||
tmp |= 0x0200;
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
|
||||
|
||||
if (nphy->radio_chanspec.channel == 14) {
|
||||
b43_nphy_classifier(dev, 2, 0);
|
||||
@ -3438,18 +3431,6 @@ static int b43_nphy_set_chanspec(struct b43_wldev *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tune the hardware to a new channel */
|
||||
static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
|
||||
struct b43_chanspec chanspec;
|
||||
chanspec = nphy->radio_chanspec;
|
||||
chanspec.channel = channel;
|
||||
|
||||
return b43_nphy_set_chanspec(dev, chanspec);
|
||||
}
|
||||
|
||||
static int b43_nphy_op_allocate(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy;
|
||||
@ -3570,7 +3551,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
|
||||
} else {
|
||||
if (dev->phy.rev >= 3) {
|
||||
b43_radio_init2056(dev);
|
||||
b43_nphy_set_chanspec(dev, nphy->radio_chanspec);
|
||||
b43_switch_channel(dev, dev->phy.channel);
|
||||
} else {
|
||||
b43_radio_init2055(dev);
|
||||
}
|
||||
@ -3586,6 +3567,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
|
||||
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct b43_chanspec chanspec;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if ((new_channel < 1) || (new_channel > 14))
|
||||
return -EINVAL;
|
||||
@ -3594,7 +3578,10 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return nphy_channel_switch(dev, new_channel);
|
||||
chanspec = nphy->radio_chanspec;
|
||||
chanspec.channel = new_channel;
|
||||
|
||||
return b43_nphy_set_chanspec(dev, chanspec);
|
||||
}
|
||||
|
||||
static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
|
||||
|
@ -11470,6 +11470,10 @@ static int ipw_net_init(struct net_device *dev)
|
||||
bg_band->channels = kcalloc(geo->bg_channels,
|
||||
sizeof(struct ieee80211_channel),
|
||||
GFP_KERNEL);
|
||||
if (!bg_band->channels) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
/* translate geo->bg to bg_band.channels */
|
||||
for (i = 0; i < geo->bg_channels; i++) {
|
||||
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
|
||||
@ -11505,6 +11509,10 @@ static int ipw_net_init(struct net_device *dev)
|
||||
a_band->channels = kcalloc(geo->a_channels,
|
||||
sizeof(struct ieee80211_channel),
|
||||
GFP_KERNEL);
|
||||
if (!a_band->channels) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
/* translate geo->bg to a_band.channels */
|
||||
for (i = 0; i < geo->a_channels; i++) {
|
||||
a_band->channels[i].band = IEEE80211_BAND_2GHZ;
|
||||
|
@ -50,14 +50,20 @@
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MAX 3
|
||||
#define IWL100_UCODE_API_MAX 5
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MIN 1
|
||||
#define IWL100_UCODE_API_MIN 5
|
||||
|
||||
#define IWL1000_FW_PRE "iwlwifi-1000-"
|
||||
#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
|
||||
#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
|
||||
|
||||
#define IWL100_FW_PRE "iwlwifi-100-"
|
||||
#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
|
||||
#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
|
||||
|
||||
|
||||
/*
|
||||
* For 1000, use advance thermal throttling critical temperature threshold,
|
||||
@ -120,13 +126,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
priv->hw_params.scd_bc_tbls_size =
|
||||
priv->cfg->num_of_queues *
|
||||
priv->cfg->base_params->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
@ -244,29 +250,16 @@ static const struct iwl_ops iwl1000_ops = {
|
||||
.led = &iwlagn_led_ops,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl1000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
static struct iwl_base_params iwl1000_base_params = {
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
|
||||
.shadow_ram_support = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
|
||||
@ -277,6 +270,26 @@ struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
static struct iwl_ht_params iwl1000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
|
||||
@ -284,30 +297,45 @@ struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.ops = &iwl1000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
|
||||
.shadow_ram_support = false,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 128,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.name = "Intel(R) 100 Series 1x1 BGN",
|
||||
.fw_name_pre = IWL100_FW_PRE,
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl100_bg_cfg = {
|
||||
.name = "Intel(R) 100 Series 1x1 BG",
|
||||
.fw_name_pre = IWL100_FW_PRE,
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
|
||||
|
@ -406,7 +406,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
|
||||
unsigned int plcp_msec;
|
||||
unsigned long plcp_received_jiffies;
|
||||
|
||||
if (priv->cfg->plcp_delta_threshold ==
|
||||
if (priv->cfg->base_params->plcp_delta_threshold ==
|
||||
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
|
||||
IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
|
||||
return rc;
|
||||
@ -432,7 +432,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
|
||||
|
||||
if ((combined_plcp_delta > 0) &&
|
||||
((combined_plcp_delta * 100) / plcp_msec) >
|
||||
priv->cfg->plcp_delta_threshold) {
|
||||
priv->cfg->base_params->plcp_delta_threshold) {
|
||||
/*
|
||||
* if plcp_err exceed the threshold, the following
|
||||
* data is printed in csv format:
|
||||
@ -444,7 +444,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
|
||||
*/
|
||||
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
|
||||
"%u, %d, %u mSecs\n",
|
||||
priv->cfg->plcp_delta_threshold,
|
||||
priv->cfg->base_params->plcp_delta_threshold,
|
||||
le32_to_cpu(current_stat.rx.ofdm.plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
/*
|
||||
@ -2421,7 +2421,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* Assign number of Usable TX queues */
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
|
||||
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
|
||||
@ -2722,22 +2722,12 @@ static const struct iwl_ops iwl3945_ops = {
|
||||
.led = &iwl3945_led_ops,
|
||||
};
|
||||
|
||||
static struct iwl_cfg iwl3945_bg_cfg = {
|
||||
.name = "3945BG",
|
||||
.fw_name_pre = IWL3945_FW_PRE,
|
||||
.ucode_api_max = IWL3945_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL3945_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
static struct iwl_base_params iwl3945_base_params = {
|
||||
.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
|
||||
.ops = &iwl3945_ops,
|
||||
.num_of_queues = IWL39_NUM_QUEUES,
|
||||
.mod_params = &iwl3945_mod_params,
|
||||
.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = false,
|
||||
.use_bsm = true,
|
||||
.use_isr_legacy = true,
|
||||
.ht_greenfield_support = false,
|
||||
.led_compensation = 64,
|
||||
.broken_powersave = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
@ -2746,25 +2736,28 @@ static struct iwl_cfg iwl3945_bg_cfg = {
|
||||
.tx_power_by_driver = true,
|
||||
};
|
||||
|
||||
static struct iwl_cfg iwl3945_bg_cfg = {
|
||||
.name = "3945BG",
|
||||
.fw_name_pre = IWL3945_FW_PRE,
|
||||
.ucode_api_max = IWL3945_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL3945_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
|
||||
.ops = &iwl3945_ops,
|
||||
.mod_params = &iwl3945_mod_params,
|
||||
.base_params = &iwl3945_base_params,
|
||||
};
|
||||
|
||||
static struct iwl_cfg iwl3945_abg_cfg = {
|
||||
.name = "3945ABG",
|
||||
.fw_name_pre = IWL3945_FW_PRE,
|
||||
.ucode_api_max = IWL3945_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL3945_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
|
||||
.ops = &iwl3945_ops,
|
||||
.num_of_queues = IWL39_NUM_QUEUES,
|
||||
.mod_params = &iwl3945_mod_params,
|
||||
.use_isr_legacy = true,
|
||||
.ht_greenfield_support = false,
|
||||
.led_compensation = 64,
|
||||
.broken_powersave = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.tx_power_by_driver = true,
|
||||
.base_params = &iwl3945_base_params,
|
||||
};
|
||||
|
||||
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
|
||||
|
@ -647,13 +647,13 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
|
||||
priv->hw_params.scd_bc_tbls_size =
|
||||
priv->cfg->num_of_queues *
|
||||
priv->cfg->base_params->num_of_queues *
|
||||
sizeof(struct iwl4965_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
|
||||
@ -1724,13 +1724,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
|
||||
u16 ssn_idx, u8 tx_fifo)
|
||||
{
|
||||
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
|
||||
(IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
|
||||
<= txq_id)) {
|
||||
(IWL49_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
|
||||
IWL_WARN(priv,
|
||||
"queue number out of range: %d, must be %d to %d\n",
|
||||
txq_id, IWL49_FIRST_AMPDU_QUEUE,
|
||||
IWL49_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->num_of_ampdu_queues - 1);
|
||||
priv->cfg->base_params->num_of_ampdu_queues - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1792,13 +1792,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
int ret;
|
||||
|
||||
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
|
||||
(IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
|
||||
<= txq_id)) {
|
||||
(IWL49_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
|
||||
IWL_WARN(priv,
|
||||
"queue number out of range: %d, must be %d to %d\n",
|
||||
txq_id, IWL49_FIRST_AMPDU_QUEUE,
|
||||
IWL49_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->num_of_ampdu_queues - 1);
|
||||
priv->cfg->base_params->num_of_ampdu_queues - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2302,26 +2302,14 @@ static const struct iwl_ops iwl4965_ops = {
|
||||
.led = &iwlagn_led_ops,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl4965_agn_cfg = {
|
||||
.name = "Intel(R) Wireless WiFi Link 4965AGN",
|
||||
.fw_name_pre = IWL4965_FW_PRE,
|
||||
.ucode_api_max = IWL4965_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL4965_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
static struct iwl_base_params iwl4965_base_params = {
|
||||
.eeprom_size = IWL4965_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
|
||||
.ops = &iwl4965_ops,
|
||||
.num_of_queues = IWL49_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = true,
|
||||
.use_isr_legacy = true,
|
||||
.ht_greenfield_support = false,
|
||||
.broken_powersave = true,
|
||||
.led_compensation = 61,
|
||||
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
|
||||
@ -2333,6 +2321,21 @@ struct iwl_cfg iwl4965_agn_cfg = {
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl4965_agn_cfg = {
|
||||
.name = "Intel(R) Wireless WiFi Link 4965AGN",
|
||||
.fw_name_pre = IWL4965_FW_PRE,
|
||||
.ucode_api_max = IWL4965_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL4965_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
|
||||
.ops = &iwl4965_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl4965_base_params,
|
||||
/*
|
||||
* Force use of chains B and C for scan RX on 5 GHz band
|
||||
* because the device has off-channel reception on chain A.
|
||||
|
@ -170,13 +170,13 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
priv->hw_params.scd_bc_tbls_size =
|
||||
priv->cfg->num_of_queues *
|
||||
priv->cfg->base_params->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
@ -217,13 +217,13 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
priv->hw_params.scd_bc_tbls_size =
|
||||
priv->cfg->num_of_queues *
|
||||
priv->cfg->base_params->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
@ -504,27 +504,14 @@ static const struct iwl_ops iwl5150_ops = {
|
||||
.led = &iwlagn_led_ops,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl5000_ops,
|
||||
static struct iwl_base_params iwl5000_base_params = {
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
@ -534,6 +521,26 @@ struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
static struct iwl_ht_params iwl5000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_bgn_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 BGN",
|
||||
@ -541,29 +548,14 @@ struct iwl_cfg iwl5100_bgn_cfg = {
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl5000_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_abg_cfg = {
|
||||
@ -572,27 +564,13 @@ struct iwl_cfg iwl5100_abg_cfg = {
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl5000_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_agn_cfg = {
|
||||
@ -601,29 +579,14 @@ struct iwl_cfg iwl5100_agn_cfg = {
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl5000_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5350_agn_cfg = {
|
||||
@ -632,29 +595,14 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl5000_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5150_agn_cfg = {
|
||||
@ -663,29 +611,14 @@ struct iwl_cfg iwl5150_agn_cfg = {
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl5150_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -695,27 +628,13 @@ struct iwl_cfg iwl5150_abg_cfg = {
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl5150_ops,
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
|
@ -51,13 +51,15 @@
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MAX 4
|
||||
#define IWL6050_UCODE_API_MAX 4
|
||||
#define IWL6050_UCODE_API_MAX 5
|
||||
#define IWL6000G2_UCODE_API_MAX 5
|
||||
#define IWL130_UCODE_API_MAX 5
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MIN 4
|
||||
#define IWL6050_UCODE_API_MIN 4
|
||||
#define IWL6000G2_UCODE_API_MIN 4
|
||||
#define IWL130_UCODE_API_MIN 5
|
||||
|
||||
#define IWL6000_FW_PRE "iwlwifi-6000-"
|
||||
#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
|
||||
@ -75,6 +77,9 @@
|
||||
#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
|
||||
#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
|
||||
|
||||
#define IWL130_FW_PRE "iwlwifi-130-"
|
||||
#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
|
||||
#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
|
||||
|
||||
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
{
|
||||
@ -83,15 +88,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
|
||||
}
|
||||
|
||||
/* Indicate calibration version to uCode. */
|
||||
static void iwl6000_set_calib_version(struct iwl_priv *priv)
|
||||
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->need_dc_calib &&
|
||||
(priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6))
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
}
|
||||
|
||||
static void iwl6050g2_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_6050_1x2);
|
||||
}
|
||||
|
||||
/* NIC configuration for 6000 series */
|
||||
static void iwl6000_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
@ -117,9 +131,11 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
|
||||
iwl_write32(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
|
||||
}
|
||||
/* else do nothing, uCode configured */
|
||||
if (priv->cfg->ops->lib->temp_ops.set_calib_version)
|
||||
priv->cfg->ops->lib->temp_ops.set_calib_version(priv);
|
||||
/* do additional nic configuration if needed */
|
||||
if (priv->cfg->ops->nic &&
|
||||
priv->cfg->ops->nic->additional_nic_config) {
|
||||
priv->cfg->ops->nic->additional_nic_config(priv);
|
||||
}
|
||||
}
|
||||
|
||||
static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
|
||||
@ -151,13 +167,13 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
priv->hw_params.scd_bc_tbls_size =
|
||||
priv->cfg->num_of_queues *
|
||||
priv->cfg->base_params->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
@ -188,7 +204,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
BIT(IWL_CALIB_TX_IQ) |
|
||||
BIT(IWL_CALIB_BASE_BAND);
|
||||
if (priv->cfg->need_dc_calib)
|
||||
priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC);
|
||||
priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
|
||||
|
||||
priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
|
||||
|
||||
@ -320,7 +336,6 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
.set_ct_kill = iwl6000_set_ct_threshold,
|
||||
.set_calib_version = iwl6000_set_calib_version,
|
||||
},
|
||||
.manage_ibss_station = iwlagn_manage_ibss_station,
|
||||
.update_bcast_stations = iwl_update_bcast_stations,
|
||||
@ -396,7 +411,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
.set_ct_kill = iwl6000_set_ct_threshold,
|
||||
.set_calib_version = iwl6000_set_calib_version,
|
||||
},
|
||||
.manage_ibss_station = iwlagn_manage_ibss_station,
|
||||
.update_bcast_stations = iwl_update_bcast_stations,
|
||||
@ -419,6 +433,14 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct iwl_nic_ops iwl6050_nic_ops = {
|
||||
.additional_nic_config = &iwl6050_additional_nic_config,
|
||||
};
|
||||
|
||||
static struct iwl_nic_ops iwl6050g2_nic_ops = {
|
||||
.additional_nic_config = &iwl6050g2_additional_nic_config,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6000_ops = {
|
||||
.lib = &iwl6000_lib,
|
||||
.hcmd = &iwlagn_hcmd,
|
||||
@ -426,6 +448,22 @@ static const struct iwl_ops iwl6000_ops = {
|
||||
.led = &iwlagn_led_ops,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6050_ops = {
|
||||
.lib = &iwl6000_lib,
|
||||
.hcmd = &iwlagn_hcmd,
|
||||
.utils = &iwlagn_hcmd_utils,
|
||||
.led = &iwlagn_led_ops,
|
||||
.nic = &iwl6050_nic_ops,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6050g2_ops = {
|
||||
.lib = &iwl6000_lib,
|
||||
.hcmd = &iwlagn_hcmd,
|
||||
.utils = &iwlagn_hcmd_utils,
|
||||
.led = &iwlagn_led_ops,
|
||||
.nic = &iwl6050g2_nic_ops,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6000g2b_ops = {
|
||||
.lib = &iwl6000g2b_lib,
|
||||
.hcmd = &iwlagn_bt_hcmd,
|
||||
@ -433,30 +471,16 @@ static const struct iwl_ops iwl6000g2b_ops = {
|
||||
.led = &iwlagn_led_ops,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2a_2agn_cfg = {
|
||||
.name = "6000 Series 2x2 AGN Gen2a",
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
static struct iwl_base_params iwl6000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
@ -468,6 +492,58 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
static struct iwl_base_params iwl6050_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1500,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
static struct iwl_ht_params iwl6000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
static struct iwl_bt_params iwl6000_bt_params = {
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2a_2agn_cfg = {
|
||||
.name = "6000 Series 2x2 AGN Gen2a",
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -477,32 +553,13 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -512,32 +569,13 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -547,41 +585,18 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
||||
@ -590,39 +605,17 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
||||
@ -631,41 +624,18 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
||||
@ -674,39 +644,17 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
||||
@ -715,41 +663,18 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bg_cfg = {
|
||||
@ -758,39 +683,17 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
|
||||
.max_event_log_size = 512,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.advanced_bt_coexist = true,
|
||||
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
|
||||
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -802,35 +705,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2abg_cfg = {
|
||||
@ -839,33 +722,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
@ -874,33 +738,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
@ -909,35 +754,14 @@ struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1500,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -947,35 +771,14 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1500,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6050g2_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -985,33 +788,13 @@ struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1500,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.ops = &iwl6050_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
@ -1021,38 +804,58 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
.led_compensation = 51,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.chain_noise_scale = 1000,
|
||||
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
|
||||
.max_event_log_size = 1024,
|
||||
.ucode_tracing = true,
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bgn_cfg = {
|
||||
.name = "Intel(R) 130 Series 1x1 BGN",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL130_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL130_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G|IWL_SKU_N,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bg_cfg = {
|
||||
.name = "Intel(R) 130 Series 1x2 BG",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL130_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL130_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_G,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
|
||||
|
@ -631,7 +631,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
|
||||
rx.general.common);
|
||||
ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
|
||||
@ -786,7 +787,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
|
||||
rx.general.common);
|
||||
} else {
|
||||
@ -801,7 +803,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
|
||||
rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
|
||||
rxon_chnum = le16_to_cpu(ctx->staging.channel);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
|
||||
stat_resp)->flag &
|
||||
STATISTICS_REPLY_FLG_BAND_24G_MSK);
|
||||
@ -861,16 +864,17 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
/* If this is the "chain_noise_num_beacons", determine:
|
||||
* 1) Disconnected antennas (using signal strengths)
|
||||
* 2) Differential gain (using silence noise) to balance receivers */
|
||||
if (data->beacon_count != priv->cfg->chain_noise_num_beacons)
|
||||
if (data->beacon_count !=
|
||||
priv->cfg->base_params->chain_noise_num_beacons)
|
||||
return;
|
||||
|
||||
/* Analyze signal for disconnected antenna */
|
||||
average_sig[0] =
|
||||
(data->chain_signal_a) / priv->cfg->chain_noise_num_beacons;
|
||||
average_sig[1] =
|
||||
(data->chain_signal_b) / priv->cfg->chain_noise_num_beacons;
|
||||
average_sig[2] =
|
||||
(data->chain_signal_c) / priv->cfg->chain_noise_num_beacons;
|
||||
average_sig[0] = data->chain_signal_a /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
average_sig[1] = data->chain_signal_b /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
average_sig[2] = data->chain_signal_c /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
|
||||
if (average_sig[0] >= average_sig[1]) {
|
||||
max_average_sig = average_sig[0];
|
||||
@ -920,7 +924,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
* To be safe, simply mask out any chains that we know
|
||||
* are not on the device.
|
||||
*/
|
||||
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
priv->bt_full_concurrent) {
|
||||
/* operated as 1x1 in full concurrency mode */
|
||||
active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
|
||||
} else
|
||||
@ -967,12 +973,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
active_chains);
|
||||
|
||||
/* Analyze noise for rx balance */
|
||||
average_noise[0] =
|
||||
((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons);
|
||||
average_noise[1] =
|
||||
((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons);
|
||||
average_noise[2] =
|
||||
((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons);
|
||||
average_noise[0] = data->chain_noise_a /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
average_noise[1] = data->chain_noise_b /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
average_noise[2] = data->chain_noise_c /
|
||||
priv->cfg->base_params->chain_noise_num_beacons;
|
||||
|
||||
for (i = 0; i < NUM_RX_CHAINS; i++) {
|
||||
if (!(data->disconn_array[i]) &&
|
||||
|
@ -39,7 +39,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
|
||||
int p = 0;
|
||||
u32 flag;
|
||||
|
||||
if (priv->cfg->bt_statistics)
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics)
|
||||
flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
|
||||
else
|
||||
flag = le32_to_cpu(priv->_agn.statistics.flag);
|
||||
@ -88,7 +89,8 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
ofdm = &priv->_agn.statistics_bt.rx.ofdm;
|
||||
cck = &priv->_agn.statistics_bt.rx.cck;
|
||||
general = &priv->_agn.statistics_bt.rx.general.common;
|
||||
@ -534,7 +536,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
tx = &priv->_agn.statistics_bt.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics_bt.tx;
|
||||
delta_tx = &priv->_agn.delta_statistics_bt.tx;
|
||||
@ -734,7 +737,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
general = &priv->_agn.statistics_bt.general.common;
|
||||
dbg = &priv->_agn.statistics_bt.general.common.dbg;
|
||||
div = &priv->_agn.statistics_bt.general.common.div;
|
||||
|
@ -137,7 +137,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
|
||||
continue;
|
||||
}
|
||||
|
||||
delta_g = (priv->cfg->chain_noise_scale *
|
||||
delta_g = (priv->cfg->base_params->chain_noise_scale *
|
||||
((s32)average_noise[default_chain] -
|
||||
(s32)average_noise[i])) / 1500;
|
||||
|
||||
@ -222,7 +222,8 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->cfg->use_rts_for_aggregation &&
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation &&
|
||||
info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
||||
return;
|
||||
|
@ -59,7 +59,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
|
||||
int iwl_alloc_isr_ict(struct iwl_priv *priv)
|
||||
{
|
||||
|
||||
if (priv->cfg->use_isr_legacy)
|
||||
if (priv->cfg->base_params->use_isr_legacy)
|
||||
return 0;
|
||||
/* allocate shrared data table */
|
||||
priv->_agn.ict_tbl_vir =
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-sta.h"
|
||||
|
||||
static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
|
||||
static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
|
||||
{
|
||||
return le32_to_cpup((__le32 *)&tx_resp->status +
|
||||
tx_resp->frame_count) & MAX_SN;
|
||||
@ -172,7 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
|
||||
|
||||
static void iwlagn_set_tx_status(struct iwl_priv *priv,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct iwl5000_tx_resp *tx_resp,
|
||||
struct iwlagn_tx_resp *tx_resp,
|
||||
int txq_id, bool is_agg)
|
||||
{
|
||||
u16 status = le16_to_cpu(tx_resp->status.status);
|
||||
@ -223,7 +223,7 @@ const char *iwl_get_agg_tx_fail_reason(u16 status)
|
||||
|
||||
static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
struct iwl_ht_agg *agg,
|
||||
struct iwl5000_tx_resp *tx_resp,
|
||||
struct iwlagn_tx_resp *tx_resp,
|
||||
int txq_id, u16 start_idx)
|
||||
{
|
||||
u16 status;
|
||||
@ -390,7 +390,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
|
||||
int index = SEQ_TO_INDEX(sequence);
|
||||
struct iwl_tx_queue *txq = &priv->txq[txq_id];
|
||||
struct ieee80211_tx_info *info;
|
||||
struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
|
||||
struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
|
||||
u32 status = le16_to_cpu(tx_resp->status.status);
|
||||
int tid;
|
||||
int sta_id;
|
||||
@ -408,8 +408,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
|
||||
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
|
||||
tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
|
||||
sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
|
||||
tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
|
||||
IWLAGN_TX_RES_TID_POS;
|
||||
sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
|
||||
IWLAGN_TX_RES_RA_POS;
|
||||
|
||||
spin_lock_irqsave(&priv->sta_lock, flags);
|
||||
if (txq->sched_retry) {
|
||||
@ -422,7 +424,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
|
||||
* notification again.
|
||||
*/
|
||||
if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
|
||||
priv->cfg->advanced_bt_coexist) {
|
||||
priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
IWL_WARN(priv, "receive reply tx with bt_kill\n");
|
||||
}
|
||||
iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
|
||||
@ -490,7 +493,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr)
|
||||
|
||||
int iwlagn_send_tx_power(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
|
||||
struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
|
||||
u8 tx_ant_cfg_cmd;
|
||||
|
||||
/* half dBm need to multiply */
|
||||
@ -511,8 +514,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
|
||||
*/
|
||||
tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
|
||||
}
|
||||
tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
|
||||
tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
|
||||
tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
|
||||
tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
|
||||
|
||||
if (IWL_UCODE_API(priv->ucode_ver) == 1)
|
||||
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
|
||||
@ -589,7 +592,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
|
||||
size_t offset)
|
||||
{
|
||||
u32 address = eeprom_indirect_address(priv, offset);
|
||||
BUG_ON(address >= priv->cfg->eeprom_size);
|
||||
BUG_ON(address >= priv->cfg->base_params->eeprom_size);
|
||||
return &priv->eeprom[address];
|
||||
}
|
||||
|
||||
@ -637,7 +640,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||
const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
|
||||
u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
|
||||
|
||||
if (!priv->cfg->use_isr_legacy)
|
||||
if (!priv->cfg->base_params->use_isr_legacy)
|
||||
rb_timeout = RX_RB_TIMEOUT;
|
||||
|
||||
if (priv->cfg->mod_params->amsdu_size_8K)
|
||||
@ -1424,7 +1427,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
* Internal scans are passive, so we can indiscriminately set
|
||||
* the BT ignore flag on 2.4 GHz since it applies to TX only.
|
||||
*/
|
||||
if (priv->cfg->advanced_bt_coexist)
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist)
|
||||
scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
|
||||
scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
|
||||
break;
|
||||
@ -1463,10 +1467,12 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
if (priv->cfg->scan_tx_antennas[band])
|
||||
scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
|
||||
|
||||
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
priv->bt_full_concurrent) {
|
||||
/* operated as 1x1 in full concurrency mode */
|
||||
scan_tx_antennas =
|
||||
first_antenna(priv->cfg->scan_tx_antennas[band]);
|
||||
scan_tx_antennas = first_antenna(
|
||||
priv->cfg->scan_tx_antennas[band]);
|
||||
}
|
||||
|
||||
priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
|
||||
@ -1487,7 +1493,9 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
|
||||
rx_ant = first_antenna(active_chains);
|
||||
}
|
||||
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
priv->bt_full_concurrent) {
|
||||
/* operated as 1x1 in full concurrency mode */
|
||||
rx_ant = first_antenna(rx_ant);
|
||||
}
|
||||
@ -1777,7 +1785,10 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
|
||||
BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
|
||||
sizeof(bt_cmd.bt3_lookup_table));
|
||||
|
||||
bt_cmd.prio_boost = priv->cfg->bt_prio_boost;
|
||||
if (priv->cfg->bt_params)
|
||||
bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost;
|
||||
else
|
||||
bt_cmd.prio_boost = 0;
|
||||
bt_cmd.kill_ack_mask = priv->kill_ack_mask;
|
||||
bt_cmd.kill_cts_mask = priv->kill_cts_mask;
|
||||
bt_cmd.valid = priv->bt_valid;
|
||||
|
@ -2939,11 +2939,14 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
|
||||
* overwrite if needed, pass aggregation time limit
|
||||
* to uCode in uSec
|
||||
*/
|
||||
if (priv && priv->cfg->agg_time_limit &&
|
||||
priv->cfg->agg_time_limit >= LINK_QUAL_AGG_TIME_LIMIT_MIN &&
|
||||
priv->cfg->agg_time_limit <= LINK_QUAL_AGG_TIME_LIMIT_MAX)
|
||||
if (priv && priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->agg_time_limit &&
|
||||
priv->cfg->bt_params->agg_time_limit >=
|
||||
LINK_QUAL_AGG_TIME_LIMIT_MIN &&
|
||||
priv->cfg->bt_params->agg_time_limit <=
|
||||
LINK_QUAL_AGG_TIME_LIMIT_MAX)
|
||||
lq_cmd->agg_params.agg_time_limit =
|
||||
cpu_to_le16(priv->cfg->agg_time_limit);
|
||||
cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
|
||||
}
|
||||
|
||||
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
|
||||
|
@ -73,7 +73,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
|
||||
int bcn_silence_a, bcn_silence_b, bcn_silence_c;
|
||||
int last_rx_noise;
|
||||
|
||||
if (priv->cfg->bt_statistics)
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics)
|
||||
rx_info = &(priv->_agn.statistics_bt.rx.general.common);
|
||||
else
|
||||
rx_info = &(priv->_agn.statistics.rx.general);
|
||||
@ -124,7 +125,8 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
|
||||
struct statistics_general_common *general, *accum_general;
|
||||
struct statistics_tx *tx, *accum_tx;
|
||||
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
prev_stats = (__le32 *)&priv->_agn.statistics_bt;
|
||||
accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
|
||||
size = sizeof(struct iwl_bt_notif_statistics);
|
||||
@ -183,7 +185,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
unsigned int plcp_msec;
|
||||
unsigned long plcp_received_jiffies;
|
||||
|
||||
if (priv->cfg->plcp_delta_threshold ==
|
||||
if (priv->cfg->base_params->plcp_delta_threshold ==
|
||||
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
|
||||
IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
|
||||
return rc;
|
||||
@ -205,7 +207,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
struct statistics_rx_phy *ofdm;
|
||||
struct statistics_rx_ht_phy *ofdm_ht;
|
||||
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
ofdm = &pkt->u.stats_bt.rx.ofdm;
|
||||
ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
|
||||
combined_plcp_delta =
|
||||
@ -229,7 +232,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
|
||||
if ((combined_plcp_delta > 0) &&
|
||||
((combined_plcp_delta * 100) / plcp_msec) >
|
||||
priv->cfg->plcp_delta_threshold) {
|
||||
priv->cfg->base_params->plcp_delta_threshold) {
|
||||
/*
|
||||
* if plcp_err exceed the threshold,
|
||||
* the following data is printed in csv format:
|
||||
@ -242,13 +245,13 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
* plcp_msec
|
||||
*/
|
||||
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
|
||||
"%u, %u, %u, %u, %d, %u mSecs\n",
|
||||
priv->cfg->plcp_delta_threshold,
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
"%u, %u, %u, %u, %d, %u mSecs\n",
|
||||
priv->cfg->base_params->plcp_delta_threshold,
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
|
||||
rc = false;
|
||||
}
|
||||
@ -262,7 +265,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
|
||||
int change;
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
IWL_DEBUG_RX(priv,
|
||||
"Statistics notification received (%d vs %d).\n",
|
||||
(int)sizeof(struct iwl_bt_notif_statistics),
|
||||
@ -300,7 +304,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
|
||||
|
||||
iwl_recover_from_statistics(priv, pkt);
|
||||
|
||||
if (priv->cfg->bt_statistics)
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics)
|
||||
memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
|
||||
sizeof(priv->_agn.statistics_bt));
|
||||
else
|
||||
|
@ -114,7 +114,7 @@ static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
|
||||
s32 temp = priv->temperature; /* degrees CELSIUS except specified */
|
||||
bool within_margin = false;
|
||||
|
||||
if (priv->cfg->temperature_kelvin)
|
||||
if (priv->cfg->base_params->temperature_kelvin)
|
||||
temp = KELVIN_TO_CELSIUS(priv->temperature);
|
||||
|
||||
if (!priv->thermal_throttle.advanced_tt)
|
||||
@ -591,7 +591,7 @@ static void iwl_bg_tt_work(struct work_struct *work)
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (priv->cfg->temperature_kelvin)
|
||||
if (priv->cfg->base_params->temperature_kelvin)
|
||||
temp = KELVIN_TO_CELSIUS(priv->temperature);
|
||||
|
||||
if (!priv->thermal_throttle.advanced_tt)
|
||||
@ -640,7 +640,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
|
||||
INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
|
||||
INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
|
||||
|
||||
if (priv->cfg->adv_thermal_throttle) {
|
||||
if (priv->cfg->base_params->adv_thermal_throttle) {
|
||||
IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
|
||||
tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
|
||||
IWL_TI_STATE_MAX, GFP_KERNEL);
|
||||
|
@ -224,13 +224,13 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
int ret;
|
||||
|
||||
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
|
||||
(IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
|
||||
<= txq_id)) {
|
||||
(IWLAGN_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
|
||||
IWL_WARN(priv,
|
||||
"queue number out of range: %d, must be %d to %d\n",
|
||||
txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
|
||||
IWLAGN_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->num_of_ampdu_queues - 1);
|
||||
priv->cfg->base_params->num_of_ampdu_queues - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -286,13 +286,13 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
|
||||
u16 ssn_idx, u8 tx_fifo)
|
||||
{
|
||||
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
|
||||
(IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
|
||||
<= txq_id)) {
|
||||
(IWLAGN_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
|
||||
IWL_ERR(priv,
|
||||
"queue number out of range: %d, must be %d to %d\n",
|
||||
txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
|
||||
IWLAGN_FIRST_AMPDU_QUEUE +
|
||||
priv->cfg->num_of_ampdu_queues - 1);
|
||||
priv->cfg->base_params->num_of_ampdu_queues - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -350,7 +350,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
|
||||
if (ieee80211_is_back_req(fc))
|
||||
tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
|
||||
else if (info->band == IEEE80211_BAND_2GHZ &&
|
||||
priv->cfg->advanced_bt_coexist &&
|
||||
priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
(ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
|
||||
ieee80211_is_reassoc_req(fc) ||
|
||||
skb->protocol == cpu_to_be16(ETH_P_PAE)))
|
||||
@ -444,7 +445,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
|
||||
rate_flags |= RATE_MCS_CCK_MSK;
|
||||
|
||||
/* Set up antennas */
|
||||
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
priv->bt_full_concurrent) {
|
||||
/* operated as 1x1 in full concurrency mode */
|
||||
priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
|
||||
first_antenna(priv->hw_params.valid_tx_ant));
|
||||
|
@ -307,7 +307,8 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (priv->cfg->advanced_bt_coexist) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
/*
|
||||
* Tell uCode we are ready to perform calibration
|
||||
* need to perform this before any calibration
|
||||
@ -330,7 +331,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_wimax_coex_cmd coex_cmd;
|
||||
|
||||
if (priv->cfg->support_wimax_coexist) {
|
||||
if (priv->cfg->base_params->support_wimax_coexist) {
|
||||
/* UnMask wake up src at associated sleep */
|
||||
coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
|
||||
|
||||
|
@ -2256,13 +2256,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
if (pieces.init_evtlog_size)
|
||||
priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
|
||||
else
|
||||
priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size;
|
||||
priv->_agn.init_evtlog_size =
|
||||
priv->cfg->base_params->max_event_log_size;
|
||||
priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
|
||||
priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
|
||||
if (pieces.inst_evtlog_size)
|
||||
priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
|
||||
else
|
||||
priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
|
||||
priv->_agn.inst_evtlog_size =
|
||||
priv->cfg->base_params->max_event_log_size;
|
||||
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
|
||||
|
||||
if (ucode_capa.pan) {
|
||||
@ -2732,7 +2734,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
priv->thermal_throttle.ct_kill_toggle = false;
|
||||
|
||||
if (priv->cfg->support_ct_kill_exit) {
|
||||
if (priv->cfg->base_params->support_ct_kill_exit) {
|
||||
adv_cmd.critical_temperature_enter =
|
||||
cpu_to_le32(priv->hw_params.ct_kill_threshold);
|
||||
adv_cmd.critical_temperature_exit =
|
||||
@ -2765,6 +2767,23 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
|
||||
{
|
||||
struct iwl_calib_cfg_cmd calib_cfg_cmd;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = CALIBRATION_CFG_CMD,
|
||||
.len = sizeof(struct iwl_calib_cfg_cmd),
|
||||
.data = &calib_cfg_cmd,
|
||||
};
|
||||
|
||||
memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
|
||||
calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
|
||||
calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
|
||||
|
||||
return iwl_send_cmd(priv, &cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* iwl_alive_start - called after REPLY_ALIVE notification received
|
||||
* from protocol/runtime uCode (initialization uCode's
|
||||
@ -2801,6 +2820,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (priv->hw_params.calib_rt_cfg)
|
||||
iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
|
||||
|
||||
|
||||
/* After the ALIVE response, we can send host commands to the uCode */
|
||||
set_bit(STATUS_ALIVE, &priv->status);
|
||||
|
||||
@ -2808,13 +2831,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
/* Enable timer to monitor the driver queues */
|
||||
mod_timer(&priv->monitor_recover,
|
||||
jiffies +
|
||||
msecs_to_jiffies(priv->cfg->monitor_recover_period));
|
||||
msecs_to_jiffies(
|
||||
priv->cfg->base_params->monitor_recover_period));
|
||||
}
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
return;
|
||||
|
||||
if (priv->cfg->advanced_bt_coexist) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
/* Configure Bluetooth device coexistence support */
|
||||
priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
|
||||
priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
|
||||
@ -2854,7 +2879,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
|
||||
}
|
||||
|
||||
if (!priv->cfg->advanced_bt_coexist) {
|
||||
if (priv->cfg->bt_params &&
|
||||
!priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
/* Configure Bluetooth device coexistence support */
|
||||
priv->cfg->ops->hcmd->send_bt_config(priv);
|
||||
}
|
||||
@ -2907,7 +2933,11 @@ static void __iwl_down(struct iwl_priv *priv)
|
||||
|
||||
/* reset BT coex data */
|
||||
priv->bt_status = 0;
|
||||
priv->bt_traffic_load = priv->cfg->bt_init_traffic_load;
|
||||
if (priv->cfg->bt_params)
|
||||
priv->bt_traffic_load =
|
||||
priv->cfg->bt_params->bt_init_traffic_load;
|
||||
else
|
||||
priv->bt_traffic_load = 0;
|
||||
priv->bt_sco_active = false;
|
||||
priv->bt_full_concurrent = false;
|
||||
priv->bt_ci_compliance = 0;
|
||||
@ -3201,7 +3231,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (priv->start_calib) {
|
||||
if (priv->cfg->bt_statistics) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->bt_statistics) {
|
||||
iwl_chain_noise_calibration(priv,
|
||||
(void *)&priv->_agn.statistics_bt);
|
||||
iwl_sensitivity_calibration(priv,
|
||||
@ -3400,7 +3431,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
|
||||
IEEE80211_HW_NEED_DTIM_PERIOD |
|
||||
IEEE80211_HW_SPECTRUM_MGMT;
|
||||
|
||||
if (!priv->cfg->broken_powersave)
|
||||
if (!priv->cfg->base_params->broken_powersave)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
|
||||
|
||||
@ -3725,7 +3756,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
}
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
ret = 0;
|
||||
if (priv->cfg->use_rts_for_aggregation) {
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation) {
|
||||
struct iwl_station_priv *sta_priv =
|
||||
(void *) sta->drv_priv;
|
||||
/*
|
||||
@ -3739,7 +3771,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
}
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_OPERATIONAL:
|
||||
if (priv->cfg->use_rts_for_aggregation) {
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation) {
|
||||
struct iwl_station_priv *sta_priv =
|
||||
(void *) sta->drv_priv;
|
||||
|
||||
@ -4057,7 +4090,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
priv->cfg->ops->lib->recover_from_tx_stall;
|
||||
}
|
||||
|
||||
if (!priv->cfg->use_isr_legacy)
|
||||
if (!priv->cfg->base_params->use_isr_legacy)
|
||||
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
|
||||
iwl_irq_tasklet, (unsigned long)priv);
|
||||
else
|
||||
@ -4142,7 +4175,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
|
||||
iwl_init_scan_params(priv);
|
||||
|
||||
/* init bt coex */
|
||||
if (priv->cfg->advanced_bt_coexist) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
|
||||
priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
|
||||
priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
|
||||
@ -4273,9 +4307,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
/* Disabling hardware scan means that mac80211 will perform scans
|
||||
* "the hard way", rather than using device's scan. */
|
||||
if (cfg->mod_params->disable_hw_scan) {
|
||||
if (iwl_debug_level & IWL_DL_INFO)
|
||||
dev_printk(KERN_DEBUG, &(pdev->dev),
|
||||
"Disabling hw_scan\n");
|
||||
dev_printk(KERN_DEBUG, &(pdev->dev),
|
||||
"sw scan support is deprecated\n");
|
||||
iwl_hw_ops.hw_scan = NULL;
|
||||
}
|
||||
|
||||
@ -4788,6 +4821,22 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
||||
{IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
|
||||
|
||||
/* 100 Series WiFi */
|
||||
{IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
|
||||
|
||||
/* 130 Series WiFi */
|
||||
{IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
|
||||
|
||||
#endif /* CONFIG_IWL5000 */
|
||||
|
||||
{0}
|
||||
@ -4876,7 +4925,8 @@ module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
|
||||
module_param_named(
|
||||
disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
|
||||
MODULE_PARM_DESC(disable_hw_scan,
|
||||
"disable hardware scanning (default 0) (deprecated)");
|
||||
|
||||
module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
|
||||
S_IRUGO);
|
||||
|
@ -92,6 +92,10 @@ extern struct iwl_cfg iwl6050_2abg_cfg;
|
||||
extern struct iwl_cfg iwl6050g2_bgn_cfg;
|
||||
extern struct iwl_cfg iwl1000_bgn_cfg;
|
||||
extern struct iwl_cfg iwl1000_bg_cfg;
|
||||
extern struct iwl_cfg iwl100_bgn_cfg;
|
||||
extern struct iwl_cfg iwl100_bg_cfg;
|
||||
extern struct iwl_cfg iwl130_bgn_cfg;
|
||||
extern struct iwl_cfg iwl130_bg_cfg;
|
||||
|
||||
extern struct iwl_mod_params iwlagn_mod_params;
|
||||
extern struct iwl_hcmd_ops iwlagn_hcmd;
|
||||
|
@ -420,12 +420,12 @@ struct iwl4965_tx_power_db {
|
||||
|
||||
/**
|
||||
* Command REPLY_TX_POWER_DBM_CMD = 0x98
|
||||
* struct iwl5000_tx_power_dbm_cmd
|
||||
* struct iwlagn_tx_power_dbm_cmd
|
||||
*/
|
||||
#define IWL50_TX_POWER_AUTO 0x7f
|
||||
#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6)
|
||||
#define IWLAGN_TX_POWER_AUTO 0x7f
|
||||
#define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6)
|
||||
|
||||
struct iwl5000_tx_power_dbm_cmd {
|
||||
struct iwlagn_tx_power_dbm_cmd {
|
||||
s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
|
||||
u8 flags;
|
||||
s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
|
||||
@ -1042,7 +1042,7 @@ struct iwl4965_keyinfo {
|
||||
u8 key[16]; /* 16-byte unicast decryption key */
|
||||
} __packed;
|
||||
|
||||
/* 5000 */
|
||||
/* agn */
|
||||
struct iwl_keyinfo {
|
||||
__le16 key_flags;
|
||||
u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
|
||||
@ -1168,7 +1168,7 @@ struct iwl4965_addsta_cmd {
|
||||
__le16 reserved2;
|
||||
} __packed;
|
||||
|
||||
/* 5000 */
|
||||
/* agn */
|
||||
struct iwl_addsta_cmd {
|
||||
u8 mode; /* 1: modify existing, 0: add new station */
|
||||
u8 reserved[3];
|
||||
@ -1959,12 +1959,12 @@ struct iwl4965_tx_resp {
|
||||
#define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80
|
||||
|
||||
/* refer to ra_tid */
|
||||
#define IWL50_TX_RES_TID_POS 0
|
||||
#define IWL50_TX_RES_TID_MSK 0x0f
|
||||
#define IWL50_TX_RES_RA_POS 4
|
||||
#define IWL50_TX_RES_RA_MSK 0xf0
|
||||
#define IWLAGN_TX_RES_TID_POS 0
|
||||
#define IWLAGN_TX_RES_TID_MSK 0x0f
|
||||
#define IWLAGN_TX_RES_RA_POS 4
|
||||
#define IWLAGN_TX_RES_RA_MSK 0xf0
|
||||
|
||||
struct iwl5000_tx_resp {
|
||||
struct iwlagn_tx_resp {
|
||||
u8 frame_count; /* 1 no aggregation, >1 aggregation */
|
||||
u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
|
||||
u8 failure_rts; /* # failures due to unsuccessful RTS */
|
||||
@ -3800,6 +3800,21 @@ enum {
|
||||
|
||||
#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff)
|
||||
|
||||
/* This enum defines the bitmap of various calibrations to enable in both
|
||||
* init ucode and runtime ucode through CALIBRATION_CFG_CMD.
|
||||
*/
|
||||
enum iwl_ucode_calib_cfg {
|
||||
IWL_CALIB_CFG_RX_BB_IDX,
|
||||
IWL_CALIB_CFG_DC_IDX,
|
||||
IWL_CALIB_CFG_TX_IQ_IDX,
|
||||
IWL_CALIB_CFG_RX_IQ_IDX,
|
||||
IWL_CALIB_CFG_NOISE_IDX,
|
||||
IWL_CALIB_CFG_CRYSTAL_IDX,
|
||||
IWL_CALIB_CFG_TEMPERATURE_IDX,
|
||||
IWL_CALIB_CFG_PAPD_IDX,
|
||||
};
|
||||
|
||||
|
||||
struct iwl_calib_cfg_elmnt_s {
|
||||
__le32 is_enable;
|
||||
__le32 start;
|
||||
|
@ -232,7 +232,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
|
||||
|
||||
ht_info->ht_supported = true;
|
||||
|
||||
if (priv->cfg->ht_greenfield_support)
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->ht_greenfield_support)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
|
||||
ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
|
||||
max_bit_rate = MAX_BIT_RATE_20_MHZ;
|
||||
@ -247,11 +248,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
|
||||
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
|
||||
if (priv->cfg->ampdu_factor)
|
||||
ht_info->ampdu_factor = priv->cfg->ampdu_factor;
|
||||
if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor)
|
||||
ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor;
|
||||
ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
|
||||
if (priv->cfg->ampdu_density)
|
||||
ht_info->ampdu_density = priv->cfg->ampdu_density;
|
||||
if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density)
|
||||
ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density;
|
||||
|
||||
ht_info->mcs.rx_mask[0] = 0xFF;
|
||||
if (rx_chains_num >= 2)
|
||||
@ -850,8 +851,10 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
|
||||
*/
|
||||
static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
|
||||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
(priv->bt_full_concurrent ||
|
||||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
|
||||
/*
|
||||
* only use chain 'A' in bt high traffic load or
|
||||
* full concurrency mode
|
||||
@ -919,8 +922,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
else
|
||||
active_chains = priv->hw_params.valid_rx_ant;
|
||||
|
||||
if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
|
||||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
(priv->bt_full_concurrent ||
|
||||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
|
||||
/*
|
||||
* only use chain 'A' in bt high traffic load or
|
||||
* full concurrency mode
|
||||
@ -1362,7 +1367,7 @@ int iwl_apm_init(struct iwl_priv *priv)
|
||||
* If not (unlikely), enable L0S, so there is at least some
|
||||
* power savings, even without L1.
|
||||
*/
|
||||
if (priv->cfg->set_l0s) {
|
||||
if (priv->cfg->base_params->set_l0s) {
|
||||
lctl = iwl_pcie_link_ctl(priv);
|
||||
if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
|
||||
PCI_CFG_LINK_CTRL_VAL_L1_EN) {
|
||||
@ -1379,8 +1384,9 @@ int iwl_apm_init(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* Configure analog phase-lock-loop before activating to D0A */
|
||||
if (priv->cfg->pll_cfg_val)
|
||||
iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
|
||||
if (priv->cfg->base_params->pll_cfg_val)
|
||||
iwl_set_bit(priv, CSR_ANA_PLL_CFG,
|
||||
priv->cfg->base_params->pll_cfg_val);
|
||||
|
||||
/*
|
||||
* Set "initialization complete" bit to move adapter from
|
||||
@ -1411,7 +1417,7 @@ int iwl_apm_init(struct iwl_priv *priv)
|
||||
* do not disable clocks. This preserves any hardware bits already
|
||||
* set by default in "CLK_CTRL_REG" after reset.
|
||||
*/
|
||||
if (priv->cfg->use_bsm)
|
||||
if (priv->cfg->base_params->use_bsm)
|
||||
iwl_write_prph(priv, APMG_CLK_EN_REG,
|
||||
APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
|
||||
else
|
||||
@ -2003,7 +2009,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (WARN_ON(!iwl_is_ready_rf(priv))) {
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
IWL_WARN(priv, "Try to add interface when device not ready\n");
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -2053,7 +2060,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (priv->cfg->advanced_bt_coexist &&
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
/*
|
||||
* pretend to have high BT traffic as long as we
|
||||
@ -2316,7 +2324,8 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv)
|
||||
{
|
||||
if (!priv->txq)
|
||||
priv->txq = kzalloc(
|
||||
sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
|
||||
sizeof(struct iwl_tx_queue) *
|
||||
priv->cfg->base_params->num_of_queues,
|
||||
GFP_KERNEL);
|
||||
if (!priv->txq) {
|
||||
IWL_ERR(priv, "Not enough memory for txq\n");
|
||||
@ -2736,11 +2745,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return -EINVAL;
|
||||
|
||||
if (test_bit(STATUS_SCANNING, &priv->status)) {
|
||||
IWL_DEBUG_INFO(priv, "scan in progress.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mode >= IWL_MAX_FORCE_RESET) {
|
||||
IWL_DEBUG_INFO(priv, "invalid reset request.\n");
|
||||
return -EINVAL;
|
||||
@ -2827,33 +2831,34 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
|
||||
txq = &priv->txq[cnt];
|
||||
q = &txq->q;
|
||||
/* queue is empty, skip */
|
||||
if (q->read_ptr != q->write_ptr) {
|
||||
if (q->read_ptr == q->last_read_ptr) {
|
||||
/* a queue has not been read from last time */
|
||||
if (q->repeat_same_read_ptr > MAX_REPEAT) {
|
||||
IWL_ERR(priv,
|
||||
"queue %d stuck %d time. Fw reload.\n",
|
||||
q->id, q->repeat_same_read_ptr);
|
||||
q->repeat_same_read_ptr = 0;
|
||||
iwl_force_reset(priv, IWL_FW_RESET, false);
|
||||
} else {
|
||||
q->repeat_same_read_ptr++;
|
||||
IWL_DEBUG_RADIO(priv,
|
||||
"queue %d, not read %d time\n",
|
||||
q->id,
|
||||
q->repeat_same_read_ptr);
|
||||
if (!priv->cfg->advanced_bt_coexist) {
|
||||
mod_timer(&priv->monitor_recover,
|
||||
jiffies + msecs_to_jiffies(
|
||||
IWL_ONE_HUNDRED_MSECS));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
q->last_read_ptr = q->read_ptr;
|
||||
if (q->read_ptr == q->write_ptr)
|
||||
return 0;
|
||||
|
||||
if (q->read_ptr == q->last_read_ptr) {
|
||||
/* a queue has not been read from last time */
|
||||
if (q->repeat_same_read_ptr > MAX_REPEAT) {
|
||||
IWL_ERR(priv,
|
||||
"queue %d stuck %d time. Fw reload.\n",
|
||||
q->id, q->repeat_same_read_ptr);
|
||||
q->repeat_same_read_ptr = 0;
|
||||
iwl_force_reset(priv, IWL_FW_RESET, false);
|
||||
} else {
|
||||
q->repeat_same_read_ptr++;
|
||||
IWL_DEBUG_RADIO(priv,
|
||||
"queue %d, not read %d time\n",
|
||||
q->id,
|
||||
q->repeat_same_read_ptr);
|
||||
if (priv->cfg->bt_params &&
|
||||
!priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
mod_timer(&priv->monitor_recover,
|
||||
jiffies + msecs_to_jiffies(
|
||||
IWL_ONE_HUNDRED_MSECS));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
q->last_read_ptr = q->read_ptr;
|
||||
q->repeat_same_read_ptr = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2880,13 +2885,13 @@ void iwl_bg_monitor_recover(unsigned long data)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (priv->cfg->monitor_recover_period) {
|
||||
if (priv->cfg->base_params->monitor_recover_period) {
|
||||
/*
|
||||
* Reschedule the timer to occur in
|
||||
* priv->cfg->monitor_recover_period
|
||||
* priv->cfg->base_params->monitor_recover_period
|
||||
*/
|
||||
mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
|
||||
priv->cfg->monitor_recover_period));
|
||||
priv->cfg->base_params->monitor_recover_period));
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_bg_monitor_recover);
|
||||
|
@ -137,7 +137,6 @@ struct iwl_debugfs_ops {
|
||||
struct iwl_temp_ops {
|
||||
void (*temperature)(struct iwl_priv *priv);
|
||||
void (*set_ct_kill)(struct iwl_priv *priv);
|
||||
void (*set_calib_version)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_tt_ops {
|
||||
@ -233,11 +232,17 @@ struct iwl_led_ops {
|
||||
int (*off)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
/* NIC specific ops */
|
||||
struct iwl_nic_ops {
|
||||
void (*additional_nic_config)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_ops {
|
||||
const struct iwl_lib_ops *lib;
|
||||
const struct iwl_hcmd_ops *hcmd;
|
||||
const struct iwl_hcmd_utils_ops *utils;
|
||||
const struct iwl_led_ops *led;
|
||||
const struct iwl_nic_ops *nic;
|
||||
};
|
||||
|
||||
struct iwl_mod_params {
|
||||
@ -250,20 +255,12 @@ struct iwl_mod_params {
|
||||
int restart_fw; /* def: 1 = restart firmware */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_cfg
|
||||
* @fw_name_pre: Firmware filename prefix. The api version and extension
|
||||
* (.ucode) will be added to filename before loading from disk. The
|
||||
* filename is constructed as fw_name_pre<api>.ucode.
|
||||
* @ucode_api_max: Highest version of uCode API supported by driver.
|
||||
* @ucode_api_min: Lowest version of uCode API supported by driver.
|
||||
* @pa_type: used by 6000 series only to identify the type of Power Amplifier
|
||||
/*
|
||||
* @max_ll_items: max number of OTP blocks
|
||||
* @shadow_ram_support: shadow support for OTP memory
|
||||
* @led_compensation: compensate on the led on/off time per HW according
|
||||
* to the deviation to achieve the desired led frequency.
|
||||
* The detail algorithm is described in iwl-led.c
|
||||
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
|
||||
* @chain_noise_num_beacons: number of beacons used to compute chain noise
|
||||
* @adv_thermal_throttle: support advance thermal throttle
|
||||
* @support_ct_kill_exit: support ct kill exit condition
|
||||
@ -281,66 +278,21 @@ struct iwl_mod_params {
|
||||
* sensitivity calibration operation
|
||||
* @chain_noise_calib_by_driver: driver has the capability to perform
|
||||
* chain noise calibration operation
|
||||
* @scan_antennas: available antenna for scan operation
|
||||
* @advanced_bt_coexist: support advanced bt coexist
|
||||
* @bt_init_traffic_load: specify initial bt traffic load
|
||||
* @bt_prio_boost: default bt priority boost value
|
||||
* @need_dc_calib: need to perform init dc calibration
|
||||
* @bt_statistics: use BT version of statistics notification
|
||||
* @agg_time_limit: maximum number of uSec in aggregation
|
||||
* @ampdu_factor: Maximum A-MPDU length factor
|
||||
* @ampdu_density: Minimum A-MPDU spacing
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt API version. The
|
||||
* driver specifies which APIs it supports (with @ucode_api_max being the
|
||||
* highest and @ucode_api_min the lowest). Firmware will only be loaded if
|
||||
* it has a supported API version. The firmware's API version will be
|
||||
* stored in @iwl_priv, enabling the driver to make runtime changes based
|
||||
* on firmware version used.
|
||||
*
|
||||
* For example,
|
||||
* if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
|
||||
* Driver interacts with Firmware API version >= 2.
|
||||
* } else {
|
||||
* Driver interacts with Firmware API version 1.
|
||||
* }
|
||||
*
|
||||
* The ideal usage of this infrastructure is to treat a new ucode API
|
||||
* release as a new hardware revision. That is, through utilizing the
|
||||
* iwl_hcmd_utils_ops etc. we accommodate different command structures
|
||||
* and flows between hardware versions (4965/5000) as well as their API
|
||||
* versions.
|
||||
*
|
||||
*/
|
||||
struct iwl_cfg {
|
||||
const char *name;
|
||||
const char *fw_name_pre;
|
||||
const unsigned int ucode_api_max;
|
||||
const unsigned int ucode_api_min;
|
||||
unsigned int sku;
|
||||
*/
|
||||
struct iwl_base_params {
|
||||
int eeprom_size;
|
||||
u16 eeprom_ver;
|
||||
u16 eeprom_calib_ver;
|
||||
int num_of_queues; /* def: HW dependent */
|
||||
int num_of_ampdu_queues;/* def: HW dependent */
|
||||
const struct iwl_ops *ops;
|
||||
const struct iwl_mod_params *mod_params;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
|
||||
/* for iwl_apm_init() */
|
||||
u32 pll_cfg_val;
|
||||
bool set_l0s;
|
||||
bool use_bsm;
|
||||
|
||||
bool use_isr_legacy;
|
||||
enum iwl_pa_type pa_type;
|
||||
const u16 max_ll_items;
|
||||
const bool shadow_ram_support;
|
||||
const bool ht_greenfield_support;
|
||||
u16 led_compensation;
|
||||
const bool broken_powersave;
|
||||
bool use_rts_for_aggregation;
|
||||
int chain_noise_num_beacons;
|
||||
const bool supports_idle;
|
||||
bool adv_thermal_throttle;
|
||||
@ -356,17 +308,89 @@ struct iwl_cfg {
|
||||
const bool ucode_tracing;
|
||||
const bool sensitivity_calib_by_driver;
|
||||
const bool chain_noise_calib_by_driver;
|
||||
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
|
||||
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
|
||||
};
|
||||
/*
|
||||
* @advanced_bt_coexist: support advanced bt coexist
|
||||
* @bt_init_traffic_load: specify initial bt traffic load
|
||||
* @bt_prio_boost: default bt priority boost value
|
||||
* @bt_statistics: use BT version of statistics notification
|
||||
* @agg_time_limit: maximum number of uSec in aggregation
|
||||
* @ampdu_factor: Maximum A-MPDU length factor
|
||||
* @ampdu_density: Minimum A-MPDU spacing
|
||||
*/
|
||||
struct iwl_bt_params {
|
||||
bool advanced_bt_coexist;
|
||||
u8 bt_init_traffic_load;
|
||||
u8 bt_prio_boost;
|
||||
const bool need_dc_calib;
|
||||
const bool bt_statistics;
|
||||
u16 agg_time_limit;
|
||||
u8 ampdu_factor;
|
||||
u8 ampdu_density;
|
||||
};
|
||||
/*
|
||||
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
|
||||
*/
|
||||
struct iwl_ht_params {
|
||||
const bool ht_greenfield_support; /* if used set to true */
|
||||
bool use_rts_for_aggregation;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_cfg
|
||||
* @fw_name_pre: Firmware filename prefix. The api version and extension
|
||||
* (.ucode) will be added to filename before loading from disk. The
|
||||
* filename is constructed as fw_name_pre<api>.ucode.
|
||||
* @ucode_api_max: Highest version of uCode API supported by driver.
|
||||
* @ucode_api_min: Lowest version of uCode API supported by driver.
|
||||
* @pa_type: used by 6000 series only to identify the type of Power Amplifier
|
||||
* @need_dc_calib: need to perform init dc calibration
|
||||
* @scan_antennas: available antenna for scan operation
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt API version. The
|
||||
* driver specifies which APIs it supports (with @ucode_api_max being the
|
||||
* highest and @ucode_api_min the lowest). Firmware will only be loaded if
|
||||
* it has a supported API version. The firmware's API version will be
|
||||
* stored in @iwl_priv, enabling the driver to make runtime changes based
|
||||
* on firmware version used.
|
||||
*
|
||||
* For example,
|
||||
* if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
|
||||
* Driver interacts with Firmware API version >= 2.
|
||||
* } else {
|
||||
* Driver interacts with Firmware API version 1.
|
||||
* }
|
||||
*
|
||||
* The ideal usage of this infrastructure is to treat a new ucode API
|
||||
* release as a new hardware revision. That is, through utilizing the
|
||||
* iwl_hcmd_utils_ops etc. we accommodate different command structures
|
||||
* and flows between hardware versions (4965/5000) as well as their API
|
||||
* versions.
|
||||
*
|
||||
*/
|
||||
struct iwl_cfg {
|
||||
/* params specific to an individual device within a device family */
|
||||
const char *name;
|
||||
const char *fw_name_pre;
|
||||
const unsigned int ucode_api_max;
|
||||
const unsigned int ucode_api_min;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
unsigned int sku;
|
||||
u16 eeprom_ver;
|
||||
u16 eeprom_calib_ver;
|
||||
const struct iwl_ops *ops;
|
||||
/* module based parameters which can be set from modprobe cmd */
|
||||
const struct iwl_mod_params *mod_params;
|
||||
/* params not likely to change within a device family */
|
||||
struct iwl_base_params *base_params;
|
||||
/* params likely to change within a device family */
|
||||
struct iwl_ht_params *ht_params;
|
||||
struct iwl_bt_params *bt_params;
|
||||
enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */
|
||||
const bool need_dc_calib; /* if used set to true */
|
||||
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
|
||||
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
|
||||
};
|
||||
|
||||
/***************************
|
||||
* L i b *
|
||||
|
@ -371,7 +371,8 @@
|
||||
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
|
||||
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
|
||||
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
|
||||
#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
|
||||
#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
|
||||
#define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008)
|
||||
|
||||
/* GIO Chicken Bits (PCI Express bus link power management) */
|
||||
#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
|
||||
|
@ -356,7 +356,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
|
||||
const u8 *ptr;
|
||||
char *buf;
|
||||
u16 eeprom_ver;
|
||||
size_t eeprom_len = priv->cfg->eeprom_size;
|
||||
size_t eeprom_len = priv->cfg->base_params->eeprom_size;
|
||||
buf_size = 4 * eeprom_len + 256;
|
||||
|
||||
if (eeprom_len % 16) {
|
||||
@ -872,7 +872,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
|
||||
struct iwl_rx_queue *rxq = &priv->rxq;
|
||||
char *buf;
|
||||
int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
|
||||
(priv->cfg->num_of_queues * 32 * 8) + 400;
|
||||
(priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
|
||||
const u8 *ptr;
|
||||
ssize_t ret;
|
||||
|
||||
@ -971,7 +971,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
|
||||
int pos = 0;
|
||||
int cnt;
|
||||
int ret;
|
||||
const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues;
|
||||
const size_t bufsz = sizeof(char) * 64 *
|
||||
priv->cfg->base_params->num_of_queues;
|
||||
|
||||
if (!priv->txq) {
|
||||
IWL_ERR(priv, "txq not ready\n");
|
||||
@ -1415,7 +1416,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
|
||||
const size_t bufsz = sizeof(buf);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
|
||||
priv->cfg->plcp_delta_threshold);
|
||||
priv->cfg->base_params->plcp_delta_threshold);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
@ -1437,10 +1438,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
|
||||
return -EINVAL;
|
||||
if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
|
||||
(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
|
||||
priv->cfg->plcp_delta_threshold =
|
||||
priv->cfg->base_params->plcp_delta_threshold =
|
||||
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
|
||||
else
|
||||
priv->cfg->plcp_delta_threshold = plcp;
|
||||
priv->cfg->base_params->plcp_delta_threshold = plcp;
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1550,13 +1551,14 @@ static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
|
||||
if (sscanf(buf, "%d", &period) != 1)
|
||||
return -EINVAL;
|
||||
if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
|
||||
priv->cfg->monitor_recover_period = IWL_DEF_MONITORING_PERIOD;
|
||||
priv->cfg->base_params->monitor_recover_period =
|
||||
IWL_DEF_MONITORING_PERIOD;
|
||||
else
|
||||
priv->cfg->monitor_recover_period = period;
|
||||
priv->cfg->base_params->monitor_recover_period = period;
|
||||
|
||||
if (priv->cfg->monitor_recover_period)
|
||||
if (priv->cfg->base_params->monitor_recover_period)
|
||||
mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
|
||||
priv->cfg->monitor_recover_period));
|
||||
priv->cfg->base_params->monitor_recover_period));
|
||||
else
|
||||
del_timer_sync(&priv->monitor_recover);
|
||||
return count;
|
||||
@ -1614,9 +1616,14 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
|
||||
char buf[40];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n",
|
||||
(priv->cfg->use_rts_for_aggregation) ? "rts/cts" :
|
||||
"cts-to-self");
|
||||
if (priv->cfg->ht_params)
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"use %s for aggregation\n",
|
||||
(priv->cfg->ht_params->use_rts_for_aggregation) ?
|
||||
"rts/cts" : "cts-to-self");
|
||||
else
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "N/A");
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
@ -1629,6 +1636,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
|
||||
int buf_size;
|
||||
int rts;
|
||||
|
||||
if (!priv->cfg->ht_params)
|
||||
return -EINVAL;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf_size = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
@ -1636,9 +1646,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
|
||||
if (sscanf(buf, "%d", &rts) != 1)
|
||||
return -EINVAL;
|
||||
if (rts)
|
||||
priv->cfg->use_rts_for_aggregation = true;
|
||||
priv->cfg->ht_params->use_rts_for_aggregation = true;
|
||||
else
|
||||
priv->cfg->use_rts_for_aggregation = false;
|
||||
priv->cfg->ht_params->use_rts_for_aggregation = false;
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1716,7 +1726,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
|
||||
if (!priv->cfg->broken_powersave) {
|
||||
if (!priv->cfg->base_params->broken_powersave) {
|
||||
DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
|
||||
S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
|
||||
@ -1743,27 +1753,27 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
|
||||
|
||||
if (priv->cfg->sensitivity_calib_by_driver)
|
||||
if (priv->cfg->base_params->sensitivity_calib_by_driver)
|
||||
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
|
||||
if (priv->cfg->chain_noise_calib_by_driver)
|
||||
if (priv->cfg->base_params->chain_noise_calib_by_driver)
|
||||
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
|
||||
if (priv->cfg->ucode_tracing)
|
||||
if (priv->cfg->base_params->ucode_tracing)
|
||||
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
|
||||
if (priv->cfg->bt_statistics)
|
||||
if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)
|
||||
DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
|
||||
if (priv->cfg->advanced_bt_coexist)
|
||||
if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
|
||||
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
|
||||
if (priv->cfg->sensitivity_calib_by_driver)
|
||||
if (priv->cfg->base_params->sensitivity_calib_by_driver)
|
||||
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
|
||||
&priv->disable_sens_cal);
|
||||
if (priv->cfg->chain_noise_calib_by_driver)
|
||||
if (priv->cfg->base_params->chain_noise_calib_by_driver)
|
||||
DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
|
||||
&priv->disable_chain_noise_cal);
|
||||
if (priv->cfg->tx_power_by_driver)
|
||||
if (priv->cfg->base_params->tx_power_by_driver)
|
||||
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
|
||||
&priv->disable_tx_power_cal);
|
||||
return 0;
|
||||
|
@ -684,6 +684,7 @@ struct iwl_sensitivity_ranges {
|
||||
* @ct_kill_threshold: temperature threshold
|
||||
* @beacon_time_tsf_bits: number of valid tsf bits for beacon time
|
||||
* @calib_init_cfg: setup initial calibrations for the hw
|
||||
* @calib_rt_cfg: setup runtime calibrations for the hw
|
||||
* @struct iwl_sensitivity_ranges: range of sensitivity values
|
||||
*/
|
||||
struct iwl_hw_params {
|
||||
@ -710,6 +711,7 @@ struct iwl_hw_params {
|
||||
/* for 1000, 6000 series and up */
|
||||
u16 beacon_time_tsf_bits;
|
||||
u32 calib_init_cfg;
|
||||
u32 calib_rt_cfg;
|
||||
const struct iwl_sensitivity_ranges *sens;
|
||||
};
|
||||
|
||||
|
@ -332,7 +332,7 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
|
||||
|
||||
const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
|
||||
{
|
||||
BUG_ON(offset >= priv->cfg->eeprom_size);
|
||||
BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
|
||||
return &priv->eeprom[offset];
|
||||
}
|
||||
EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
|
||||
@ -364,7 +364,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
|
||||
* CSR auto clock gate disable bit -
|
||||
* this is only applicable for HW with OTP shadow RAM
|
||||
*/
|
||||
if (priv->cfg->shadow_ram_support)
|
||||
if (priv->cfg->base_params->shadow_ram_support)
|
||||
iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG,
|
||||
CSR_RESET_LINK_PWR_MGMT_DISABLED);
|
||||
}
|
||||
@ -484,7 +484,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
|
||||
}
|
||||
/* more in the link list, continue */
|
||||
usedblocks++;
|
||||
} while (usedblocks <= priv->cfg->max_ll_items);
|
||||
} while (usedblocks <= priv->cfg->base_params->max_ll_items);
|
||||
|
||||
/* OTP has no valid blocks */
|
||||
IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
|
||||
@ -512,8 +512,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
||||
if (priv->nvm_device_type == -ENOENT)
|
||||
return -ENOENT;
|
||||
/* allocate eeprom */
|
||||
IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
|
||||
sz = priv->cfg->eeprom_size;
|
||||
sz = priv->cfg->base_params->eeprom_size;
|
||||
IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz);
|
||||
priv->eeprom = kzalloc(sz, GFP_KERNEL);
|
||||
if (!priv->eeprom) {
|
||||
ret = -ENOMEM;
|
||||
@ -554,7 +554,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
||||
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
|
||||
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
|
||||
/* traversing the linked list if no shadow ram supported */
|
||||
if (!priv->cfg->shadow_ram_support) {
|
||||
if (!priv->cfg->base_params->shadow_ram_support) {
|
||||
if (iwl_find_otp_image(priv, &validblockaddr)) {
|
||||
ret = -ENOENT;
|
||||
goto done;
|
||||
|
@ -108,13 +108,13 @@ static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx)
|
||||
BUG_ON(idx > IWL_MAX_BLINK_TBL);
|
||||
|
||||
IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n",
|
||||
priv->cfg->led_compensation);
|
||||
priv->cfg->base_params->led_compensation);
|
||||
led_cmd.on =
|
||||
iwl_blink_compensation(priv, blink_tbl[idx].on_time,
|
||||
priv->cfg->led_compensation);
|
||||
priv->cfg->base_params->led_compensation);
|
||||
led_cmd.off =
|
||||
iwl_blink_compensation(priv, blink_tbl[idx].off_time,
|
||||
priv->cfg->led_compensation);
|
||||
priv->cfg->base_params->led_compensation);
|
||||
|
||||
return priv->cfg->ops->led->cmd(priv, &led_cmd);
|
||||
}
|
||||
|
@ -278,9 +278,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
||||
|
||||
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
|
||||
|
||||
if (priv->cfg->broken_powersave)
|
||||
if (priv->cfg->base_params->broken_powersave)
|
||||
iwl_power_sleep_cam_cmd(priv, &cmd);
|
||||
else if (priv->cfg->supports_idle &&
|
||||
else if (priv->cfg->base_params->supports_idle &&
|
||||
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
|
||||
iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
|
||||
else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
|
||||
|
@ -259,7 +259,8 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
|
||||
if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
|
||||
priv->cfg->advanced_bt_coexist &&
|
||||
priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist &&
|
||||
priv->bt_status != scan_notif->bt_status) {
|
||||
if (scan_notif->bt_status) {
|
||||
/* BT on */
|
||||
|
@ -1581,16 +1581,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
||||
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
|
||||
next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
|
||||
|
||||
if (capacity > priv->cfg->max_event_log_size) {
|
||||
if (capacity > priv->cfg->base_params->max_event_log_size) {
|
||||
IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
|
||||
capacity, priv->cfg->max_event_log_size);
|
||||
capacity = priv->cfg->max_event_log_size;
|
||||
capacity, priv->cfg->base_params->max_event_log_size);
|
||||
capacity = priv->cfg->base_params->max_event_log_size;
|
||||
}
|
||||
|
||||
if (next_entry > priv->cfg->max_event_log_size) {
|
||||
if (next_entry > priv->cfg->base_params->max_event_log_size) {
|
||||
IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
|
||||
next_entry, priv->cfg->max_event_log_size);
|
||||
next_entry = priv->cfg->max_event_log_size;
|
||||
next_entry, priv->cfg->base_params->max_event_log_size);
|
||||
next_entry = priv->cfg->base_params->max_event_log_size;
|
||||
}
|
||||
|
||||
size = num_wraps ? capacity : next_entry;
|
||||
@ -2519,7 +2519,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
|
||||
/* Enable timer to monitor the driver queues */
|
||||
mod_timer(&priv->monitor_recover,
|
||||
jiffies +
|
||||
msecs_to_jiffies(priv->cfg->monitor_recover_period));
|
||||
msecs_to_jiffies(
|
||||
priv->cfg->base_params->monitor_recover_period));
|
||||
}
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
@ -3881,7 +3882,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
|
||||
hw->flags = IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_SPECTRUM_MGMT;
|
||||
|
||||
if (!priv->cfg->broken_powersave)
|
||||
if (!priv->cfg->base_params->broken_powersave)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
|
||||
|
||||
@ -3966,7 +3967,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
||||
* "the hard way", rather than using device's scan.
|
||||
*/
|
||||
if (iwl3945_mod_params.disable_hw_scan) {
|
||||
IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
|
||||
IWL_ERR(priv, "sw scan support is deprecated\n");
|
||||
iwl3945_hw_ops.hw_scan = NULL;
|
||||
}
|
||||
|
||||
@ -4291,7 +4292,8 @@ MODULE_PARM_DESC(debug, "debug output mask");
|
||||
#endif
|
||||
module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
|
||||
int, S_IRUGO);
|
||||
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
|
||||
MODULE_PARM_DESC(disable_hw_scan,
|
||||
"disable hardware scanning (default 0) (deprecated)");
|
||||
module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
|
||||
|
||||
|
@ -161,7 +161,7 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index,
|
||||
}
|
||||
|
||||
static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
u8 key_index, const u8 *mac_addr,
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct iwm_priv *iwm = ndev_to_iwm(ndev);
|
||||
@ -181,7 +181,8 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
|
||||
static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
u8 key_index, const u8 *mac_addr, void *cookie,
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr,
|
||||
void *cookie,
|
||||
void (*callback)(void *cookie,
|
||||
struct key_params*))
|
||||
{
|
||||
@ -206,7 +207,7 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
|
||||
|
||||
static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
u8 key_index, const u8 *mac_addr)
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
struct iwm_priv *iwm = ndev_to_iwm(ndev);
|
||||
struct iwm_key *key = &iwm->keys[key_index];
|
||||
|
@ -1440,7 +1440,7 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
|
||||
|
||||
|
||||
static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 idx, const u8 *mac_addr,
|
||||
u8 idx, bool pairwise, const u8 *mac_addr,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
@ -1500,7 +1500,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
|
||||
|
||||
static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, const u8 *mac_addr)
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CFG80211);
|
||||
|
@ -33,8 +33,17 @@ MODULE_ALIAS("prism54usb");
|
||||
MODULE_FIRMWARE("isl3886usb");
|
||||
MODULE_FIRMWARE("isl3887usb");
|
||||
|
||||
/*
|
||||
* Note:
|
||||
*
|
||||
* Always update our wiki's device list (located at:
|
||||
* http://wireless.kernel.org/en/users/Drivers/p54/devices ),
|
||||
* whenever you add a new device.
|
||||
*/
|
||||
|
||||
static struct usb_device_id p54u_table[] __devinitdata = {
|
||||
/* Version 1 devices (pci chip + net2280) */
|
||||
{USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
|
||||
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
|
||||
{USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
|
||||
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
|
||||
@ -47,7 +56,9 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
||||
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
|
||||
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
|
||||
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
|
||||
{USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
|
||||
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
|
||||
{USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
|
||||
{USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
|
||||
{USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
|
||||
{USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
|
||||
@ -60,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
||||
{USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
|
||||
{USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
|
||||
{USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
|
||||
{USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
|
||||
{USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
|
||||
{USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
|
||||
{USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
|
||||
@ -80,6 +92,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
||||
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
|
||||
{USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
|
||||
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
|
||||
{USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
|
||||
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
|
||||
{USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
|
||||
{USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
|
||||
|
@ -540,11 +540,11 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
|
||||
|
||||
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, const u8 *mac_addr,
|
||||
struct key_params *params);
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr,
|
||||
struct key_params *params);
|
||||
|
||||
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, const u8 *mac_addr);
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr);
|
||||
|
||||
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index);
|
||||
@ -2308,8 +2308,8 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
|
||||
}
|
||||
|
||||
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, const u8 *mac_addr,
|
||||
struct key_params *params)
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
|
||||
struct usbnet *usbdev = priv->usbdev;
|
||||
@ -2344,7 +2344,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
}
|
||||
|
||||
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, const u8 *mac_addr)
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
|
||||
struct usbnet *usbdev = priv->usbdev;
|
||||
|
@ -1674,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
/*
|
||||
* Initialize all hw fields.
|
||||
*
|
||||
* Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
|
||||
* capable of sending the buffered frames out after the DTIM
|
||||
* transmission using rt2x00lib_beacondone. This will send out
|
||||
* multicast and broadcast traffic immediately instead of buffering it
|
||||
* infinitly and thus dropping it after some time.
|
||||
*/
|
||||
rt2x00dev->hw->flags =
|
||||
IEEE80211_HW_RX_INCLUDES_FCS |
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_PS_NULLFUNC_STACK;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
|
||||
Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
|
||||
Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
|
||||
Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
|
||||
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
|
||||
Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
|
||||
@ -710,8 +711,14 @@
|
||||
|
||||
/*
|
||||
* TBTT_SYNC_CFG:
|
||||
* BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots
|
||||
* BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots
|
||||
*/
|
||||
#define TBTT_SYNC_CFG 0x1118
|
||||
#define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff)
|
||||
#define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00)
|
||||
#define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000)
|
||||
#define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000)
|
||||
|
||||
/*
|
||||
* TSF_TIMER_DW0: Local lsb TSF timer, read-only
|
||||
@ -747,15 +754,20 @@
|
||||
#define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002)
|
||||
|
||||
/*
|
||||
* CH_IDLE_STA: channel idle time
|
||||
* CH_IDLE_STA: channel idle time (in us)
|
||||
*/
|
||||
#define CH_IDLE_STA 0x1130
|
||||
|
||||
/*
|
||||
* CH_BUSY_STA: channel busy time
|
||||
* CH_BUSY_STA: channel busy time on primary channel (in us)
|
||||
*/
|
||||
#define CH_BUSY_STA 0x1134
|
||||
|
||||
/*
|
||||
* CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us)
|
||||
*/
|
||||
#define CH_BUSY_STA_SEC 0x1138
|
||||
|
||||
/*
|
||||
* MAC_STATUS_CFG:
|
||||
* BBP_RF_BUSY: When set to 0, BBP and RF are stable.
|
||||
@ -1342,6 +1354,9 @@
|
||||
* PID_TYPE: The PID latched from the PID field in the TXWI, can be used
|
||||
* to match a frame with its tx result (even though the PID is
|
||||
* only 4 bits wide).
|
||||
* PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3)
|
||||
* PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3)
|
||||
* This identification number is calculated by ((idx % 3) + 1).
|
||||
* TX_SUCCESS: Indicates tx success (1) or failure (0)
|
||||
* TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0)
|
||||
* TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0)
|
||||
@ -1353,6 +1368,8 @@
|
||||
#define TX_STA_FIFO 0x1718
|
||||
#define TX_STA_FIFO_VALID FIELD32(0x00000001)
|
||||
#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e)
|
||||
#define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006)
|
||||
#define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018)
|
||||
#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020)
|
||||
#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040)
|
||||
#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080)
|
||||
@ -1435,6 +1452,24 @@
|
||||
|
||||
/*
|
||||
* Security key table memory.
|
||||
*
|
||||
* The pairwise key table shares some memory with the beacon frame
|
||||
* buffers 6 and 7. That basically means that when beacon 6 & 7
|
||||
* are used we should only use the reduced pairwise key table which
|
||||
* has a maximum of 222 entries.
|
||||
*
|
||||
* ---------------------------------------------
|
||||
* |0x4000 | Pairwise Key | Reduced Pairwise |
|
||||
* | | Table | Key Table |
|
||||
* | | Size: 256 * 32 | Size: 222 * 32 |
|
||||
* |0x5BC0 | |-------------------
|
||||
* | | | Beacon 6 |
|
||||
* |0x5DC0 | |-------------------
|
||||
* | | | Beacon 7 |
|
||||
* |0x5FC0 | |-------------------
|
||||
* |0x5FFF | |
|
||||
* --------------------------
|
||||
*
|
||||
* MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
|
||||
* PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
|
||||
* MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
|
||||
@ -1584,7 +1619,8 @@ struct mac_iveiv_entry {
|
||||
* 2. Extract memory from FCE table for BCN 4~5
|
||||
* 3. Extract memory from Pair-wise key table for BCN 6~7
|
||||
* It occupied those memory of wcid 238~253 for BCN 6
|
||||
* and wcid 222~237 for BCN 7
|
||||
* and wcid 222~237 for BCN 7 (see Security key table memory
|
||||
* for more info).
|
||||
*
|
||||
* IMPORTANT NOTE: Not sure why legacy driver does this,
|
||||
* but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
|
||||
@ -1963,10 +1999,17 @@ struct mac_iveiv_entry {
|
||||
* FRAG: 1 To inform TKIP engine this is a fragment.
|
||||
* MIMO_PS: The remote peer is in dynamic MIMO-PS mode
|
||||
* TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
|
||||
* BW: Channel bandwidth 20MHz or 40 MHz
|
||||
* BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will
|
||||
* duplicate the frame to both channels).
|
||||
* STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
|
||||
* AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will
|
||||
* aggregate consecutive frames with the same RA and QoS TID.
|
||||
* aggregate consecutive frames with the same RA and QoS TID. If
|
||||
* a frame A with the same RA and QoS TID but AMPDU=0 is queued
|
||||
* directly after a frame B with AMPDU=1, frame A might still
|
||||
* get aggregated into the AMPDU started by frame B. So, setting
|
||||
* AMPDU to 0 does _not_ necessarily mean the frame is sent as
|
||||
* MPDU, it can still end up in an AMPDU if the previous frame
|
||||
* was tagged as AMPDU.
|
||||
*/
|
||||
#define TXWI_W0_FRAG FIELD32(0x00000001)
|
||||
#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
|
||||
@ -1993,6 +2036,10 @@ struct mac_iveiv_entry {
|
||||
* frame was processed. If multiple frames are aggregated together
|
||||
* (AMPDU==1) the reported tx status will always contain the packet
|
||||
* id of the first frame. 0: Don't report tx status for this frame.
|
||||
* PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3)
|
||||
* PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3)
|
||||
* This identification number is calculated by ((idx % 3) + 1).
|
||||
* The (+1) is required to prevent PACKETID to become 0.
|
||||
*/
|
||||
#define TXWI_W1_ACK FIELD32(0x00000001)
|
||||
#define TXWI_W1_NSEQ FIELD32(0x00000002)
|
||||
@ -2000,6 +2047,8 @@ struct mac_iveiv_entry {
|
||||
#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00)
|
||||
#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
|
||||
#define TXWI_W1_PACKETID FIELD32(0xf0000000)
|
||||
#define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000)
|
||||
#define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000)
|
||||
|
||||
/*
|
||||
* Word2
|
||||
|
@ -483,7 +483,8 @@ void rt2800_write_tx_data(struct queue_entry *entry,
|
||||
txdesc->key_idx : 0xff);
|
||||
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
|
||||
txdesc->length);
|
||||
rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1);
|
||||
rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
|
||||
rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
|
||||
rt2x00_desc_write(txwi, 1, word);
|
||||
|
||||
/*
|
||||
@ -630,15 +631,90 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
struct txdone_entry_desc txdesc;
|
||||
u32 word;
|
||||
u16 mcs, real_mcs;
|
||||
int aggr, ampdu;
|
||||
__le32 *txwi;
|
||||
|
||||
/*
|
||||
* Obtain the status about this packet.
|
||||
*/
|
||||
txdesc.flags = 0;
|
||||
txwi = rt2800_drv_get_txwi(entry);
|
||||
rt2x00_desc_read(txwi, 0, &word);
|
||||
|
||||
mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
|
||||
ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU);
|
||||
|
||||
real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
|
||||
aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
|
||||
|
||||
/*
|
||||
* If a frame was meant to be sent as a single non-aggregated MPDU
|
||||
* but ended up in an aggregate the used tx rate doesn't correlate
|
||||
* with the one specified in the TXWI as the whole aggregate is sent
|
||||
* with the same rate.
|
||||
*
|
||||
* For example: two frames are sent to rt2x00, the first one sets
|
||||
* AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0
|
||||
* and requests MCS15. If the hw aggregates both frames into one
|
||||
* AMDPU the tx status for both frames will contain MCS7 although
|
||||
* the frame was sent successfully.
|
||||
*
|
||||
* Hence, replace the requested rate with the real tx rate to not
|
||||
* confuse the rate control algortihm by providing clearly wrong
|
||||
* data.
|
||||
*/
|
||||
if (aggr == 1 && ampdu == 0 && real_mcs != mcs) {
|
||||
skbdesc->tx_rate_idx = real_mcs;
|
||||
mcs = real_mcs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ralink has a retry mechanism using a global fallback
|
||||
* table. We setup this fallback table to try the immediate
|
||||
* lower rate for all rates. In the TX_STA_FIFO, the MCS field
|
||||
* always contains the MCS used for the last transmission, be
|
||||
* it successful or not.
|
||||
*/
|
||||
if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) {
|
||||
/*
|
||||
* Transmission succeeded. The number of retries is
|
||||
* mcs - real_mcs
|
||||
*/
|
||||
__set_bit(TXDONE_SUCCESS, &txdesc.flags);
|
||||
txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
|
||||
} else {
|
||||
/*
|
||||
* Transmission failed. The number of retries is
|
||||
* always 7 in this case (for a total number of 8
|
||||
* frames sent).
|
||||
*/
|
||||
__set_bit(TXDONE_FAILURE, &txdesc.flags);
|
||||
txdesc.retry = rt2x00dev->long_retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* the frame was retried at least once
|
||||
* -> hw used fallback rates
|
||||
*/
|
||||
if (txdesc.retry)
|
||||
__set_bit(TXDONE_FALLBACK, &txdesc.flags);
|
||||
|
||||
rt2x00lib_txdone(entry, &txdesc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
|
||||
|
||||
void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
struct queue_entry *entry;
|
||||
__le32 *txwi;
|
||||
struct txdone_entry_desc txdesc;
|
||||
u32 word;
|
||||
u32 reg;
|
||||
u16 mcs, real_mcs;
|
||||
u8 pid;
|
||||
int i;
|
||||
|
||||
@ -660,7 +736,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
* Skip this entry when it contains an invalid
|
||||
* queue identication number.
|
||||
*/
|
||||
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
|
||||
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
|
||||
if (pid >= QID_RX)
|
||||
continue;
|
||||
|
||||
@ -673,7 +749,6 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
* order. We first check that the queue is not empty.
|
||||
*/
|
||||
entry = NULL;
|
||||
txwi = NULL;
|
||||
while (!rt2x00queue_empty(queue)) {
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
if (rt2800_txdone_entry_check(entry, reg))
|
||||
@ -683,48 +758,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
if (!entry || rt2x00queue_empty(queue))
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
* Obtain the status about this packet.
|
||||
*/
|
||||
txdesc.flags = 0;
|
||||
txwi = rt2800_drv_get_txwi(entry);
|
||||
rt2x00_desc_read(txwi, 0, &word);
|
||||
mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
|
||||
real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
|
||||
|
||||
/*
|
||||
* Ralink has a retry mechanism using a global fallback
|
||||
* table. We setup this fallback table to try the immediate
|
||||
* lower rate for all rates. In the TX_STA_FIFO, the MCS field
|
||||
* always contains the MCS used for the last transmission, be
|
||||
* it successful or not.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
|
||||
/*
|
||||
* Transmission succeeded. The number of retries is
|
||||
* mcs - real_mcs
|
||||
*/
|
||||
__set_bit(TXDONE_SUCCESS, &txdesc.flags);
|
||||
txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
|
||||
} else {
|
||||
/*
|
||||
* Transmission failed. The number of retries is
|
||||
* always 7 in this case (for a total number of 8
|
||||
* frames sent).
|
||||
*/
|
||||
__set_bit(TXDONE_FAILURE, &txdesc.flags);
|
||||
txdesc.retry = rt2x00dev->long_retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* the frame was retried at least once
|
||||
* -> hw used fallback rates
|
||||
*/
|
||||
if (txdesc.retry)
|
||||
__set_bit(TXDONE_FALLBACK, &txdesc.flags);
|
||||
|
||||
rt2x00lib_txdone(entry, &txdesc);
|
||||
rt2800_txdone_entry(entry, reg);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_txdone);
|
||||
@ -1031,8 +1065,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
|
||||
* 1 pairwise key is possible per AID, this means that the AID
|
||||
* equals our hw_key_idx. Make sure the WCID starts _after_ the
|
||||
* last possible shared key entry.
|
||||
*
|
||||
* Since parts of the pairwise key table might be shared with
|
||||
* the beacon frame buffers 6 & 7 we should only write into the
|
||||
* first 222 entries.
|
||||
*/
|
||||
if (crypto->aid > (256 - 32))
|
||||
if (crypto->aid > (222 - 32))
|
||||
return -ENOSPC;
|
||||
|
||||
key->hw_key_idx = 32 + crypto->aid;
|
||||
@ -1159,6 +1197,102 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_config_intf);
|
||||
|
||||
static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_erp *erp)
|
||||
{
|
||||
bool any_sta_nongf = !!(erp->ht_opmode &
|
||||
IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
|
||||
u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION;
|
||||
u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode;
|
||||
u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate;
|
||||
u32 reg;
|
||||
|
||||
/* default protection rate for HT20: OFDM 24M */
|
||||
mm20_rate = gf20_rate = 0x4004;
|
||||
|
||||
/* default protection rate for HT40: duplicate OFDM 24M */
|
||||
mm40_rate = gf40_rate = 0x4084;
|
||||
|
||||
switch (protection) {
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
|
||||
/*
|
||||
* All STAs in this BSS are HT20/40 but there might be
|
||||
* STAs not supporting greenfield mode.
|
||||
* => Disable protection for HT transmissions.
|
||||
*/
|
||||
mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0;
|
||||
|
||||
break;
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
|
||||
/*
|
||||
* All STAs in this BSS are HT20 or HT20/40 but there
|
||||
* might be STAs not supporting greenfield mode.
|
||||
* => Protect all HT40 transmissions.
|
||||
*/
|
||||
mm20_mode = gf20_mode = 0;
|
||||
mm40_mode = gf40_mode = 2;
|
||||
|
||||
break;
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
|
||||
/*
|
||||
* Nonmember protection:
|
||||
* According to 802.11n we _should_ protect all
|
||||
* HT transmissions (but we don't have to).
|
||||
*
|
||||
* But if cts_protection is enabled we _shall_ protect
|
||||
* all HT transmissions using a CCK rate.
|
||||
*
|
||||
* And if any station is non GF we _shall_ protect
|
||||
* GF transmissions.
|
||||
*
|
||||
* We decide to protect everything
|
||||
* -> fall through to mixed mode.
|
||||
*/
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
|
||||
/*
|
||||
* Legacy STAs are present
|
||||
* => Protect all HT transmissions.
|
||||
*/
|
||||
mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2;
|
||||
|
||||
/*
|
||||
* If erp protection is needed we have to protect HT
|
||||
* transmissions with CCK 11M long preamble.
|
||||
*/
|
||||
if (erp->cts_protection) {
|
||||
/* don't duplicate RTS/CTS in CCK mode */
|
||||
mm20_rate = mm40_rate = 0x0003;
|
||||
gf20_rate = gf40_rate = 0x0003;
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
/* check for STAs not supporting greenfield mode */
|
||||
if (any_sta_nongf)
|
||||
gf20_mode = gf40_mode = 2;
|
||||
|
||||
/* Update HT protection config */
|
||||
rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®);
|
||||
rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, mm20_rate);
|
||||
rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode);
|
||||
rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, mm40_rate);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode);
|
||||
rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®);
|
||||
rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, gf20_rate);
|
||||
rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode);
|
||||
rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®);
|
||||
rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, gf40_rate);
|
||||
rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode);
|
||||
rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
|
||||
}
|
||||
|
||||
void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
|
||||
u32 changed)
|
||||
{
|
||||
@ -1203,6 +1337,9 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
|
||||
erp->beacon_int * 16);
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_HT)
|
||||
rt2800_config_ht_opmode(rt2x00dev, erp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_config_erp);
|
||||
|
||||
@ -1907,8 +2044,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL,
|
||||
!rt2x00_is_usb(rt2x00dev));
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
|
||||
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
|
||||
@ -3056,11 +3192,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
* Initialize all hw fields.
|
||||
*/
|
||||
rt2x00dev->hw->flags =
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_PS_NULLFUNC_STACK |
|
||||
IEEE80211_HW_AMPDU_AGGREGATION;
|
||||
/*
|
||||
* Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
|
||||
* unless we are capable of sending the buffered frames out after the
|
||||
* DTIM transmission using rt2x00lib_beacondone. This will send out
|
||||
* multicast and broadcast traffic immediately instead of buffering it
|
||||
* infinitly and thus dropping it after some time.
|
||||
*/
|
||||
if (!rt2x00_is_usb(rt2x00dev))
|
||||
rt2x00dev->hw->flags |=
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
|
||||
|
||||
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
|
||||
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
|
||||
@ -3071,12 +3216,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
* As rt2800 has a global fallback table we cannot specify
|
||||
* more then one tx rate per frame but since the hw will
|
||||
* try several rates (based on the fallback table) we should
|
||||
* still initialize max_rates to the maximum number of rates
|
||||
* initialize max_report_rates to the maximum number of rates
|
||||
* we are going to try. Otherwise mac80211 will truncate our
|
||||
* reported tx rates and the rc algortihm will end up with
|
||||
* incorrect data.
|
||||
*/
|
||||
rt2x00dev->hw->max_rates = 7;
|
||||
rt2x00dev->hw->max_rates = 1;
|
||||
rt2x00dev->hw->max_report_rates = 7;
|
||||
rt2x00dev->hw->max_rate_tries = 1;
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
|
||||
@ -3333,8 +3479,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
/* we don't support RX aggregation yet */
|
||||
ret = -ENOTSUPP;
|
||||
/*
|
||||
* The hw itself takes care of setting up BlockAck mechanisms.
|
||||
* So, we only have to allow mac80211 to nagotiate a BlockAck
|
||||
* agreement. Once that is done, the hw will BlockAck incoming
|
||||
* AMPDUs without further setup.
|
||||
*/
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||
|
@ -153,6 +153,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
|
||||
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
|
||||
|
||||
void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
|
||||
|
@ -241,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
|
||||
{
|
||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
u32 word;
|
||||
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
@ -251,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
|
||||
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
||||
rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
|
||||
rt2x00_desc_write(entry_priv->desc, 1, word);
|
||||
|
||||
/*
|
||||
* Set RX IDX in register to inform hardware that we have
|
||||
* handled this entry and it is available for reuse again.
|
||||
*/
|
||||
rt2800_register_write(rt2x00dev, RX_CRX_IDX,
|
||||
entry->entry_idx);
|
||||
} else {
|
||||
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
||||
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
|
||||
@ -599,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue)
|
||||
static void rt2800pci_fill_rxdone(struct queue_entry *entry,
|
||||
struct rxdone_entry_desc *rxdesc)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||
__le32 *rxd = entry_priv->desc;
|
||||
u32 word;
|
||||
@ -641,12 +648,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
|
||||
* Process the RXWI structure that is at the start of the buffer.
|
||||
*/
|
||||
rt2800_process_rxwi(entry, rxdesc);
|
||||
|
||||
/*
|
||||
* Set RX IDX in register to inform hardware that we have handled
|
||||
* this entry and it is available for reuse again.
|
||||
*/
|
||||
rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -660,6 +661,63 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
|
||||
}
|
||||
|
||||
static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
struct queue_entry *entry;
|
||||
u32 status;
|
||||
u8 qid;
|
||||
|
||||
while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
|
||||
/* Now remove the tx status from the FIFO */
|
||||
if (kfifo_out(&rt2x00dev->txstatus_fifo, &status,
|
||||
sizeof(status)) != sizeof(status)) {
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1;
|
||||
if (qid >= QID_RX) {
|
||||
/*
|
||||
* Unknown queue, this shouldn't happen. Just drop
|
||||
* this tx status.
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status report with "
|
||||
"unexpected pid %u, dropping", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
queue = rt2x00queue_get_queue(rt2x00dev, qid);
|
||||
if (unlikely(queue == NULL)) {
|
||||
/*
|
||||
* The queue is NULL, this shouldn't happen. Stop
|
||||
* processing here and drop the tx status
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status for an unavailable "
|
||||
"queue %u, dropping", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rt2x00queue_empty(queue)) {
|
||||
/*
|
||||
* The queue is empty. Stop processing here
|
||||
* and drop the tx status.
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status for an empty "
|
||||
"queue %u, dropping", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
rt2800_txdone_entry(entry, status);
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800pci_txstatus_tasklet(unsigned long data)
|
||||
{
|
||||
rt2800pci_txdone((struct rt2x00_dev *)data);
|
||||
}
|
||||
|
||||
static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = dev_instance;
|
||||
@ -684,13 +742,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
|
||||
rt2x00pci_rxdone(rt2x00dev);
|
||||
|
||||
/*
|
||||
* 4 - Tx done interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
|
||||
rt2800_txdone(rt2x00dev);
|
||||
|
||||
/*
|
||||
* 5 - Auto wakeup interrupt.
|
||||
* 4 - Auto wakeup interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
|
||||
rt2800pci_wakeup(rt2x00dev);
|
||||
@ -702,10 +754,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 status;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The TX_FIFO_STATUS interrupt needs special care. We should
|
||||
* read TX_STA_FIFO but we should do it immediately as otherwise
|
||||
* the register can overflow and we would lose status reports.
|
||||
*
|
||||
* Hence, read the TX_STA_FIFO register and copy all tx status
|
||||
* reports into a kernel FIFO which is handled in the txstatus
|
||||
* tasklet. We use a tasklet to process the tx status reports
|
||||
* because we can schedule the tasklet multiple times (when the
|
||||
* interrupt fires again during tx status processing).
|
||||
*
|
||||
* Furthermore we don't disable the TX_FIFO_STATUS
|
||||
* interrupt here but leave it enabled so that the TX_STA_FIFO
|
||||
* can also be read while the interrupt thread gets executed.
|
||||
*
|
||||
* Since we have only one producer and one consumer we don't
|
||||
* need to lock the kfifo.
|
||||
*/
|
||||
for (i = 0; i < TX_ENTRIES; i++) {
|
||||
rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
|
||||
|
||||
if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
|
||||
break;
|
||||
|
||||
if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
|
||||
WARNING(rt2x00dev, "TX status FIFO overrun,"
|
||||
" drop tx status report.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (kfifo_in(&rt2x00dev->txstatus_fifo, &status,
|
||||
sizeof(status)) != sizeof(status)) {
|
||||
WARNING(rt2x00dev, "TX status FIFO overrun,"
|
||||
"drop tx status report.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Schedule the tasklet for processing the tx status. */
|
||||
tasklet_schedule(&rt2x00dev->txstatus_tasklet);
|
||||
}
|
||||
|
||||
static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = dev_instance;
|
||||
u32 reg;
|
||||
irqreturn_t ret = IRQ_HANDLED;
|
||||
|
||||
/* Read status and ACK all interrupts */
|
||||
rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®);
|
||||
@ -717,15 +817,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
|
||||
if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* Store irqvalue for use in the interrupt thread. */
|
||||
rt2x00dev->irqvalue[0] = reg;
|
||||
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
|
||||
rt2800pci_txstatus_interrupt(rt2x00dev);
|
||||
|
||||
/* Disable interrupts, will be enabled again in the interrupt thread. */
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
STATE_RADIO_IRQ_OFF_ISR);
|
||||
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) ||
|
||||
rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) ||
|
||||
rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) ||
|
||||
rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) {
|
||||
/*
|
||||
* All other interrupts are handled in the interrupt thread.
|
||||
* Store irqvalue for use in the interrupt thread.
|
||||
*/
|
||||
rt2x00dev->irqvalue[0] = reg;
|
||||
|
||||
/*
|
||||
* Disable interrupts, will be enabled again in the
|
||||
* interrupt thread.
|
||||
*/
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
STATE_RADIO_IRQ_OFF_ISR);
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
/*
|
||||
* Leave the TX_FIFO_STATUS interrupt enabled to not lose any
|
||||
* tx status reports.
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®);
|
||||
rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1);
|
||||
rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
|
||||
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -788,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
|
||||
if (!modparam_nohwcrypt)
|
||||
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
|
||||
@ -837,6 +961,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
|
||||
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
||||
.irq_handler = rt2800pci_interrupt,
|
||||
.irq_handler_thread = rt2800pci_interrupt_thread,
|
||||
.txstatus_tasklet = rt2800pci_txstatus_tasklet,
|
||||
.probe_hw = rt2800pci_probe_hw,
|
||||
.get_firmware_name = rt2800pci_get_firmware_name,
|
||||
.check_firmware = rt2800_check_firmware,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
||||
@ -457,6 +458,7 @@ struct rt2x00lib_erp {
|
||||
short eifs;
|
||||
|
||||
u16 beacon_int;
|
||||
u16 ht_opmode;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -521,6 +523,11 @@ struct rt2x00lib_ops {
|
||||
*/
|
||||
irq_handler_t irq_handler_thread;
|
||||
|
||||
/*
|
||||
* TX status tasklet handler.
|
||||
*/
|
||||
void (*txstatus_tasklet) (unsigned long data);
|
||||
|
||||
/*
|
||||
* Device init handlers.
|
||||
*/
|
||||
@ -651,6 +658,7 @@ enum rt2x00_flags {
|
||||
DRIVER_REQUIRE_DMA,
|
||||
DRIVER_REQUIRE_COPY_IV,
|
||||
DRIVER_REQUIRE_L2PAD,
|
||||
DRIVER_REQUIRE_TXSTATUS_FIFO,
|
||||
|
||||
/*
|
||||
* Driver features
|
||||
@ -884,6 +892,16 @@ struct rt2x00_dev {
|
||||
* and interrupt thread routine.
|
||||
*/
|
||||
u32 irqvalue[2];
|
||||
|
||||
/*
|
||||
* FIFO for storing tx status reports between isr and tasklet.
|
||||
*/
|
||||
struct kfifo txstatus_fifo;
|
||||
|
||||
/*
|
||||
* Tasklet for processing tx status reports (rt2800pci).
|
||||
*/
|
||||
struct tasklet_struct txstatus_tasklet;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -103,6 +103,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||
/* Update global beacon interval time, this is needed for PS support */
|
||||
rt2x00dev->beacon_int = bss_conf->beacon_int;
|
||||
|
||||
if (changed & BSS_CHANGED_HT)
|
||||
erp.ht_opmode = bss_conf->ht_operation_mode;
|
||||
|
||||
rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
|
||||
}
|
||||
|
||||
|
@ -812,6 +812,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
|
||||
rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
|
||||
|
||||
/*
|
||||
* Allocate tx status FIFO for driver use.
|
||||
*/
|
||||
if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) &&
|
||||
rt2x00dev->ops->lib->txstatus_tasklet) {
|
||||
/*
|
||||
* Allocate txstatus fifo and tasklet, we use a size of 512
|
||||
* for the kfifo which is big enough to store 512/4=128 tx
|
||||
* status reports. In the worst case (tx status for all tx
|
||||
* queues gets reported before we've got a chance to handle
|
||||
* them) 24*4=384 tx status reports need to be cached.
|
||||
*/
|
||||
status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
|
||||
GFP_KERNEL);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* tasklet for processing the tx status reports. */
|
||||
tasklet_init(&rt2x00dev->txstatus_tasklet,
|
||||
rt2x00dev->ops->lib->txstatus_tasklet,
|
||||
(unsigned long)rt2x00dev);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Register HW.
|
||||
*/
|
||||
@ -909,10 +933,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
/* Enable the radio */
|
||||
retval = rt2x00lib_enable_radio(rt2x00dev);
|
||||
if (retval) {
|
||||
rt2x00queue_uninitialize(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
|
||||
|
||||
@ -1027,6 +1049,16 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
|
||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
cancel_work_sync(&rt2x00dev->txdone_work);
|
||||
|
||||
/*
|
||||
* Free the tx status fifo.
|
||||
*/
|
||||
kfifo_free(&rt2x00dev->txstatus_fifo);
|
||||
|
||||
/*
|
||||
* Kill the tx status tasklet.
|
||||
*/
|
||||
tasklet_kill(&rt2x00dev->txstatus_tasklet);
|
||||
|
||||
/*
|
||||
* Uninitialize device.
|
||||
*/
|
||||
|
@ -60,9 +60,10 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
|
||||
* when using more then one tx stream (>MCS7).
|
||||
*/
|
||||
if (tx_info->control.sta && txdesc->mcs > 7 &&
|
||||
(tx_info->control.sta->ht_cap.cap &
|
||||
(WLAN_HT_CAP_SM_PS_DYNAMIC <<
|
||||
IEEE80211_HT_CAP_SM_PS_SHIFT)))
|
||||
((tx_info->control.sta->ht_cap.cap &
|
||||
IEEE80211_HT_CAP_SM_PS) >>
|
||||
IEEE80211_HT_CAP_SM_PS_SHIFT) ==
|
||||
WLAN_HT_CAP_SM_PS_DYNAMIC)
|
||||
__set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
|
||||
} else {
|
||||
txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
|
||||
@ -72,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
|
||||
|
||||
|
||||
/*
|
||||
* Convert flags
|
||||
* This frame is eligible for an AMPDU, however, don't aggregate
|
||||
* frames that are intended to probe a specific tx rate.
|
||||
*/
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
|
||||
!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
|
||||
__set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
|
||||
|
||||
/*
|
||||
@ -84,7 +87,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
|
||||
txdesc->rate_mode = RATE_MODE_HT_MIX;
|
||||
if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
|
||||
txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
|
||||
if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
|
||||
/*
|
||||
* Set 40Mhz mode if necessary (for legacy rates this will
|
||||
* duplicate the frame to both channels).
|
||||
*/
|
||||
if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
|
||||
txrate->flags & IEEE80211_TX_RC_DUP_DATA)
|
||||
__set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
|
||||
if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
__set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
|
||||
|
@ -671,7 +671,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
||||
*/
|
||||
if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
|
||||
BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT))
|
||||
BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
|
||||
rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
|
||||
|
@ -2630,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
* As rt61 has a global fallback table we cannot specify
|
||||
* more then one tx rate per frame but since the hw will
|
||||
* try several rates (based on the fallback table) we should
|
||||
* still initialize max_rates to the maximum number of rates
|
||||
* initialize max_report_rates to the maximum number of rates
|
||||
* we are going to try. Otherwise mac80211 will truncate our
|
||||
* reported tx rates and the rc algortihm will end up with
|
||||
* incorrect data.
|
||||
*/
|
||||
rt2x00dev->hw->max_rates = 7;
|
||||
rt2x00dev->hw->max_rates = 1;
|
||||
rt2x00dev->hw->max_report_rates = 7;
|
||||
rt2x00dev->hw->max_rate_tries = 1;
|
||||
|
||||
/*
|
||||
|
@ -2063,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
/*
|
||||
* Initialize all hw fields.
|
||||
*
|
||||
* Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
|
||||
* capable of sending the buffered frames out after the DTIM
|
||||
* transmission using rt2x00lib_beacondone. This will send out
|
||||
* multicast and broadcast traffic immediately instead of buffering it
|
||||
* infinitly and thus dropping it after some time.
|
||||
*/
|
||||
rt2x00dev->hw->flags =
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_PS_NULLFUNC_STACK;
|
||||
@ -2365,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = {
|
||||
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* CEIVA */
|
||||
{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* CNet */
|
||||
|
@ -99,66 +99,19 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl8180_handle_tx(struct ieee80211_hw *dev)
|
||||
static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
struct rtl8180_tx_ring *ring;
|
||||
int prio;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
for (prio = 3; prio >= 0; prio--) {
|
||||
ring = &priv->tx_ring[prio];
|
||||
|
||||
while (skb_queue_len(&ring->queue)) {
|
||||
struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *info;
|
||||
u32 flags = le32_to_cpu(entry->flags);
|
||||
|
||||
if (flags & RTL818X_TX_DESC_FLAG_OWN)
|
||||
break;
|
||||
|
||||
ring->idx = (ring->idx + 1) % ring->entries;
|
||||
skb = __skb_dequeue(&ring->queue);
|
||||
pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
|
||||
(flags & RTL818X_TX_DESC_FLAG_TX_OK))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
||||
info->status.rates[0].count = (flags & 0xFF) + 1;
|
||||
info->status.rates[1].idx = -1;
|
||||
|
||||
ieee80211_tx_status(dev, skb);
|
||||
if (ring->entries - skb_queue_len(&ring->queue) == 2)
|
||||
ieee80211_wake_queue(dev, prio);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
unsigned int count = 0;
|
||||
unsigned int count = 32;
|
||||
u8 signal, agc, sq;
|
||||
|
||||
/* handle pending Tx queue cleanup */
|
||||
rtl8180_handle_tx(dev);
|
||||
|
||||
while (count++ < budget) {
|
||||
while (count--) {
|
||||
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
|
||||
struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
|
||||
u32 flags = le32_to_cpu(entry->flags);
|
||||
|
||||
if (flags & RTL818X_RX_DESC_FLAG_OWN)
|
||||
break;
|
||||
return;
|
||||
|
||||
if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
|
||||
RTL818X_RX_DESC_FLAG_FOF |
|
||||
@ -198,7 +151,7 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
|
||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx(dev, skb);
|
||||
ieee80211_rx_irqsafe(dev, skb);
|
||||
|
||||
skb = new_skb;
|
||||
priv->rx_buf[priv->rx_idx] = skb;
|
||||
@ -215,16 +168,41 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
|
||||
entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
|
||||
priv->rx_idx = (priv->rx_idx + 1) % 32;
|
||||
}
|
||||
}
|
||||
|
||||
if (count < budget) {
|
||||
/* disable polling */
|
||||
ieee80211_napi_complete(dev);
|
||||
static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
|
||||
|
||||
/* enable interrupts */
|
||||
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
|
||||
while (skb_queue_len(&ring->queue)) {
|
||||
struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *info;
|
||||
u32 flags = le32_to_cpu(entry->flags);
|
||||
|
||||
if (flags & RTL818X_TX_DESC_FLAG_OWN)
|
||||
return;
|
||||
|
||||
ring->idx = (ring->idx + 1) % ring->entries;
|
||||
skb = __skb_dequeue(&ring->queue);
|
||||
pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
|
||||
(flags & RTL818X_TX_DESC_FLAG_TX_OK))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
||||
info->status.rates[0].count = (flags & 0xFF) + 1;
|
||||
info->status.rates[1].idx = -1;
|
||||
|
||||
ieee80211_tx_status_irqsafe(dev, skb);
|
||||
if (ring->entries - skb_queue_len(&ring->queue) == 2)
|
||||
ieee80211_wake_queue(dev, prio);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
|
||||
@ -233,17 +211,31 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u16 reg;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
|
||||
if (unlikely(reg == 0xFFFF))
|
||||
if (unlikely(reg == 0xFFFF)) {
|
||||
spin_unlock(&priv->lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
|
||||
|
||||
/* disable interrupts */
|
||||
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
|
||||
if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
|
||||
rtl8180_handle_tx(dev, 3);
|
||||
|
||||
/* enable polling */
|
||||
ieee80211_napi_schedule(dev);
|
||||
if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
|
||||
rtl8180_handle_tx(dev, 2);
|
||||
|
||||
if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
|
||||
rtl8180_handle_tx(dev, 1);
|
||||
|
||||
if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
|
||||
rtl8180_handle_tx(dev, 0);
|
||||
|
||||
if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
|
||||
rtl8180_handle_rx(dev);
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -255,6 +247,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
struct rtl8180_tx_ring *ring;
|
||||
struct rtl8180_tx_desc *entry;
|
||||
unsigned long flags;
|
||||
unsigned int idx, prio;
|
||||
dma_addr_t mapping;
|
||||
u32 tx_flags;
|
||||
@ -301,7 +294,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
plcp_len |= 1 << 15;
|
||||
}
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
|
||||
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
||||
@ -325,7 +318,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
if (ring->entries - skb_queue_len(&ring->queue) < 2)
|
||||
ieee80211_stop_queue(dev, prio);
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
|
||||
|
||||
@ -871,7 +864,6 @@ static const struct ieee80211_ops rtl8180_ops = {
|
||||
.prepare_multicast = rtl8180_prepare_multicast,
|
||||
.configure_filter = rtl8180_configure_filter,
|
||||
.get_tsf = rtl8180_get_tsf,
|
||||
.napi_poll = rtl8180_poll,
|
||||
};
|
||||
|
||||
static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
|
||||
@ -1003,8 +995,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
|
||||
dev->queues = 1;
|
||||
dev->max_signal = 65;
|
||||
|
||||
dev->napi_weight = 64;
|
||||
|
||||
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
|
||||
reg &= RTL818X_TX_CONF_HWVER_MASK;
|
||||
switch (reg) {
|
||||
|
@ -117,10 +117,7 @@ enum {
|
||||
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
|
||||
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
|
||||
|
||||
/*
|
||||
* Enable/disable 802.11a support for WL1273
|
||||
*/
|
||||
#undef WL1271_80211A_ENABLED
|
||||
#define WL1271_CIPHER_SUITE_GEM 0x00147201
|
||||
|
||||
#define WL1271_BUSY_WORD_CNT 1
|
||||
#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
|
||||
@ -133,6 +130,8 @@ enum {
|
||||
|
||||
#define ACX_TX_DESCRIPTORS 32
|
||||
|
||||
#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
|
||||
|
||||
enum wl1271_state {
|
||||
WL1271_STATE_OFF,
|
||||
WL1271_STATE_ON,
|
||||
@ -301,6 +300,7 @@ struct wl1271_rx_mem_pool_addr {
|
||||
struct wl1271_scan {
|
||||
struct cfg80211_scan_request *req;
|
||||
bool *scanned_ch;
|
||||
bool failed;
|
||||
u8 state;
|
||||
u8 ssid[IW_ESSID_MAX_SIZE+1];
|
||||
size_t ssid_len;
|
||||
@ -350,6 +350,7 @@ struct wl1271 {
|
||||
#define WL1271_FLAG_IDLE (10)
|
||||
#define WL1271_FLAG_IDLE_REQUESTED (11)
|
||||
#define WL1271_FLAG_PSPOLL_FAILURE (12)
|
||||
#define WL1271_FLAG_STA_STATE_SENT (13)
|
||||
unsigned long flags;
|
||||
|
||||
struct wl1271_partition_set part;
|
||||
@ -362,6 +363,7 @@ struct wl1271 {
|
||||
u8 *fw;
|
||||
size_t fw_len;
|
||||
struct wl1271_nvs_file *nvs;
|
||||
size_t nvs_len;
|
||||
|
||||
s8 hw_pg_ver;
|
||||
|
||||
@ -408,9 +410,15 @@ struct wl1271 {
|
||||
/* Rx memory pool address */
|
||||
struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
|
||||
|
||||
/* Intermediate buffer, used for packet aggregation */
|
||||
u8 *aggr_buf;
|
||||
|
||||
/* The target interrupt mask */
|
||||
struct work_struct irq_work;
|
||||
|
||||
/* Hardware recovery work */
|
||||
struct work_struct recovery_work;
|
||||
|
||||
/* The mbox event mask */
|
||||
u32 event_mask;
|
||||
|
||||
@ -419,6 +427,7 @@ struct wl1271 {
|
||||
|
||||
/* Are we currently scanning */
|
||||
struct wl1271_scan scan;
|
||||
struct delayed_work scan_complete_work;
|
||||
|
||||
/* Our association ID */
|
||||
u16 aid;
|
||||
@ -475,6 +484,8 @@ struct wl1271 {
|
||||
|
||||
bool sg_enabled;
|
||||
|
||||
bool enable_11a;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
/* Most recently reported noise in dBm */
|
||||
@ -498,14 +509,4 @@ int wl1271_plt_stop(struct wl1271 *wl);
|
||||
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
|
||||
#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
|
||||
|
||||
static inline bool wl1271_11a_enabled(void)
|
||||
{
|
||||
/* FIXME: this could be determined based on the NVS-INI file */
|
||||
#ifdef WL1271_80211A_ENABLED
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -86,40 +86,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
|
||||
{
|
||||
struct acx_revision *rev;
|
||||
int ret;
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "acx fw rev");
|
||||
|
||||
rev = kzalloc(sizeof(*rev), GFP_KERNEL);
|
||||
if (!rev) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("ACX_FW_REV interrogate failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* be careful with the buffer sizes */
|
||||
strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
|
||||
|
||||
/*
|
||||
* if the firmware version string is exactly
|
||||
* sizeof(rev->fw_version) long or fw_len is less than
|
||||
* sizeof(rev->fw_version) it won't be null terminated
|
||||
*/
|
||||
buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
|
||||
|
||||
out:
|
||||
kfree(rev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_tx_power(struct wl1271 *wl, int power)
|
||||
{
|
||||
struct acx_current_tx_power *acx;
|
||||
|
@ -100,35 +100,6 @@ struct acx_error_counter {
|
||||
__le32 seq_num_miss;
|
||||
} __packed;
|
||||
|
||||
struct acx_revision {
|
||||
struct acx_header header;
|
||||
|
||||
/*
|
||||
* The WiLink firmware version, an ASCII string x.x.x.x,
|
||||
* that uniquely identifies the current firmware.
|
||||
* The left most digit is incremented each time a
|
||||
* significant change is made to the firmware, such as
|
||||
* code redesign or new platform support.
|
||||
* The second digit is incremented when major enhancements
|
||||
* are added or major fixes are made.
|
||||
* The third digit is incremented for each GA release.
|
||||
* The fourth digit is incremented for each build.
|
||||
* The first two digits identify a firmware release version,
|
||||
* in other words, a unique set of features.
|
||||
* The first three digits identify a GA release.
|
||||
*/
|
||||
char fw_version[20];
|
||||
|
||||
/*
|
||||
* This 4 byte field specifies the WiLink hardware version.
|
||||
* bits 0 - 15: Reserved.
|
||||
* bits 16 - 23: Version ID - The WiLink version ID
|
||||
* (1 = first spin, 2 = second spin, and so on).
|
||||
* bits 24 - 31: Chip ID - The WiLink chip ID.
|
||||
*/
|
||||
__le32 hw_version;
|
||||
} __packed;
|
||||
|
||||
enum wl1271_psm_mode {
|
||||
/* Active mode */
|
||||
WL1271_PSM_CAM = 0,
|
||||
@ -1060,7 +1031,6 @@ enum {
|
||||
ACX_PEER_HT_CAP = 0x0057,
|
||||
ACX_HT_BSS_OPERATION = 0x0058,
|
||||
ACX_COEX_ACTIVITY = 0x0059,
|
||||
ACX_SET_SMART_REFLEX_DEBUG = 0x005A,
|
||||
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
|
||||
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
|
||||
DOT11_CUR_TX_PWR = 0x100D,
|
||||
@ -1077,7 +1047,6 @@ enum {
|
||||
|
||||
int wl1271_acx_wake_up_conditions(struct wl1271 *wl);
|
||||
int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
|
||||
int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
|
||||
int wl1271_acx_tx_power(struct wl1271 *wl, int power);
|
||||
int wl1271_acx_feature_cfg(struct wl1271 *wl);
|
||||
int wl1271_acx_mem_map(struct wl1271 *wl,
|
||||
|
@ -225,6 +225,28 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
if (wl->nvs == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
|
||||
* configurations) can be removed when those NVS files stop floating
|
||||
* around.
|
||||
*/
|
||||
if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
|
||||
wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
|
||||
if (wl->nvs->general_params.dual_mode_select)
|
||||
wl->enable_11a = true;
|
||||
}
|
||||
|
||||
if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
|
||||
(wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
|
||||
wl->enable_11a)) {
|
||||
wl1271_error("nvs size is not as expected: %zu != %zu",
|
||||
wl->nvs_len, sizeof(struct wl1271_nvs_file));
|
||||
kfree(wl->nvs);
|
||||
wl->nvs = NULL;
|
||||
wl->nvs_len = 0;
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
/* only the first part of the NVS needs to be uploaded */
|
||||
nvs_len = sizeof(wl->nvs->nvs);
|
||||
nvs_ptr = (u8 *)wl->nvs->nvs;
|
||||
@ -251,8 +273,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
burst_len = nvs_ptr[0];
|
||||
dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
|
||||
|
||||
/* FIXME: Due to our new wl1271_translate_reg_addr function,
|
||||
we need to add the REGISTER_BASE to the destination */
|
||||
/*
|
||||
* Due to our new wl1271_translate_reg_addr function,
|
||||
* we need to add the REGISTER_BASE to the destination
|
||||
*/
|
||||
dest_addr += REGISTERS_BASE;
|
||||
|
||||
/* We move our pointer to the data */
|
||||
@ -280,8 +304,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
|
||||
nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
|
||||
|
||||
/* FIXME: The driver sets the partition here, but this is not needed,
|
||||
since it sets to the same one as currently in use */
|
||||
/* Now we must set the partition correctly */
|
||||
wl1271_set_partition(wl, &part_table[PART_WORK]);
|
||||
|
||||
@ -291,9 +313,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
return -ENOMEM;
|
||||
|
||||
/* And finally we upload the NVS tables */
|
||||
/* FIXME: In wl1271, we upload everything at once.
|
||||
No endianness handling needed here?! The ref driver doesn't do
|
||||
anything about it at this point */
|
||||
wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
|
||||
|
||||
kfree(nvs_aligned);
|
||||
@ -491,10 +510,7 @@ int wl1271_boot(struct wl1271 *wl)
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
|
||||
|
||||
pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
|
||||
* WU_COUNTER_PAUSE_VAL instead of
|
||||
* 0x3ff (magic number ). How does
|
||||
* this work?! */
|
||||
pause &= ~(WU_COUNTER_PAUSE_VAL);
|
||||
pause |= WU_COUNTER_PAUSE_VAL;
|
||||
wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
|
||||
|
||||
@ -548,7 +564,6 @@ int wl1271_boot(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* FIXME: Need to check whether this is really what we want */
|
||||
wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
|
||||
WL1271_ACX_ALL_EVENTS_VECTOR);
|
||||
|
||||
|
@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
|
||||
status = le16_to_cpu(cmd->status);
|
||||
if (status != CMD_STATUS_SUCCESS) {
|
||||
wl1271_error("command execute failure %d", status);
|
||||
ieee80211_queue_work(wl->hw, &wl->recovery_work);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
@ -107,6 +108,8 @@ out:
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_general_parms_cmd *gen_parms;
|
||||
struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
|
||||
bool answer = false;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
|
||||
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
|
||||
|
||||
memcpy(&gen_parms->general_params, &wl->nvs->general_params,
|
||||
sizeof(struct wl1271_ini_general_params));
|
||||
memcpy(&gen_parms->general_params, gp, sizeof(*gp));
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
|
||||
if (ret < 0)
|
||||
if (gp->tx_bip_fem_auto_detect)
|
||||
answer = true;
|
||||
|
||||
ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
out:
|
||||
kfree(gen_parms);
|
||||
return ret;
|
||||
}
|
||||
@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
|
||||
struct conf_rf_settings *rf = &wl->conf.rf;
|
||||
int ret;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
|
||||
if (!ext_radio_parms)
|
||||
return -ENOMEM;
|
||||
|
||||
ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
|
||||
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
|
||||
rf->tx_per_channel_power_compensation_2,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_2);
|
||||
memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
|
||||
rf->tx_per_channel_power_compensation_5,
|
||||
CONF_TX_PWR_COMPENSATION_LEN_5);
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
|
||||
ext_radio_parms, sizeof(*ext_radio_parms));
|
||||
|
||||
ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
|
||||
if (ret < 0)
|
||||
wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
|
||||
|
||||
kfree(ext_radio_parms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll the mailbox event field until any of the bits in the mask is set or a
|
||||
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
|
||||
@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
|
||||
timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
|
||||
|
||||
do {
|
||||
if (time_after(jiffies, timeout))
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ieee80211_queue_work(wl->hw, &wl->recovery_work);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
@ -390,18 +439,11 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
|
||||
{
|
||||
struct wl1271_cmd_ps_params *ps_params = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* FIXME: this should be in ps.c */
|
||||
ret = wl1271_acx_wake_up_conditions(wl);
|
||||
if (ret < 0) {
|
||||
wl1271_error("couldn't set wake up conditions");
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd set ps mode");
|
||||
|
||||
ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
|
||||
@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
|
||||
|
||||
ps_params->ps_mode = ps_mode;
|
||||
ps_params->send_null_data = send;
|
||||
ps_params->retries = 5;
|
||||
ps_params->hang_over_period = 1;
|
||||
ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set);
|
||||
ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
|
||||
ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
|
||||
ps_params->null_data_rate = cpu_to_le32(rates);
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
|
||||
sizeof(*ps_params), 0);
|
||||
@ -428,41 +470,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
|
||||
size_t len)
|
||||
{
|
||||
struct cmd_read_write_memory *cmd;
|
||||
int ret = 0;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd read memory");
|
||||
|
||||
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
||||
if (!cmd) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
WARN_ON(len > MAX_READ_SIZE);
|
||||
len = min_t(size_t, len, MAX_READ_SIZE);
|
||||
|
||||
cmd->addr = cpu_to_le32(addr);
|
||||
cmd->size = cpu_to_le32(len);
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
|
||||
sizeof(*cmd));
|
||||
if (ret < 0) {
|
||||
wl1271_error("read memory command failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* the read command got in */
|
||||
memcpy(answer, cmd->value, len);
|
||||
|
||||
out:
|
||||
kfree(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
|
||||
void *buf, size_t buf_len, int index, u32 rates)
|
||||
{
|
||||
@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
|
||||
}
|
||||
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
|
||||
WL1271_RATE_AUTOMATIC);
|
||||
wl->basic_rate);
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
|
||||
skb->data, skb->len,
|
||||
CMD_TEMPL_KLV_IDX_NULL_DATA,
|
||||
WL1271_RATE_AUTOMATIC);
|
||||
wl->basic_rate);
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
|
||||
|
||||
return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
|
||||
sizeof(template), 0,
|
||||
WL1271_RATE_AUTOMATIC);
|
||||
wl->basic_rate);
|
||||
}
|
||||
|
||||
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
|
||||
@ -746,3 +753,31 @@ out_free:
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_set_sta_state(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_cmd_set_sta_state *cmd;
|
||||
int ret = 0;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd set sta state");
|
||||
|
||||
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
||||
if (!cmd) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0);
|
||||
if (ret < 0) {
|
||||
wl1271_error("failed to send set STA state command");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
kfree(cmd);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -33,12 +33,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
|
||||
size_t res_len);
|
||||
int wl1271_cmd_general_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_radio_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
|
||||
int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
|
||||
int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
|
||||
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
|
||||
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
|
||||
size_t len);
|
||||
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
|
||||
@ -55,6 +56,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
|
||||
u8 key_size, const u8 *key, const u8 *addr,
|
||||
u32 tx_seq_32, u16 tx_seq_16);
|
||||
int wl1271_cmd_disconnect(struct wl1271 *wl);
|
||||
int wl1271_cmd_set_sta_state(struct wl1271 *wl);
|
||||
|
||||
enum wl1271_commands {
|
||||
CMD_INTERROGATE = 1, /*use this to read information elements*/
|
||||
@ -160,41 +162,6 @@ enum {
|
||||
MAX_COMMAND_STATUS = 0xff
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CMD_READ_MEMORY
|
||||
*
|
||||
* The host issues this command to read the WiLink device memory/registers.
|
||||
*
|
||||
* Note: The Base Band address has special handling (16 bits registers and
|
||||
* addresses). For more information, see the hardware specification.
|
||||
*/
|
||||
/*
|
||||
* CMD_WRITE_MEMORY
|
||||
*
|
||||
* The host issues this command to write the WiLink device memory/registers.
|
||||
*
|
||||
* The Base Band address has special handling (16 bits registers and
|
||||
* addresses). For more information, see the hardware specification.
|
||||
*/
|
||||
#define MAX_READ_SIZE 256
|
||||
|
||||
struct cmd_read_write_memory {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
/* The address of the memory to read from or write to.*/
|
||||
__le32 addr;
|
||||
|
||||
/* The amount of data in bytes to read from or write to the WiLink
|
||||
* device.*/
|
||||
__le32 size;
|
||||
|
||||
/* The actual value read from or written to the Wilink. The source
|
||||
of this field is the Host in WRITE command or the Wilink in READ
|
||||
command. */
|
||||
u8 value[MAX_READ_SIZE];
|
||||
} __packed;
|
||||
|
||||
#define CMDMBOX_HEADER_LEN 4
|
||||
#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
|
||||
|
||||
@ -313,7 +280,7 @@ enum wl1271_cmd_key_type {
|
||||
KEY_WEP = 1,
|
||||
KEY_TKIP = 2,
|
||||
KEY_AES = 3,
|
||||
KEY_GEM = 4
|
||||
KEY_GEM = 4,
|
||||
};
|
||||
|
||||
/* FIXME: Add description for key-types */
|
||||
@ -358,13 +325,14 @@ enum wl1271_channel_tune_bands {
|
||||
WL1271_CHANNEL_TUNE_BAND_4_9
|
||||
};
|
||||
|
||||
#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
|
||||
#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
|
||||
|
||||
#define TEST_CMD_P2G_CAL 0x02
|
||||
#define TEST_CMD_CHANNEL_TUNE 0x0d
|
||||
#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
|
||||
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
|
||||
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
|
||||
#define TEST_CMD_P2G_CAL 0x02
|
||||
#define TEST_CMD_CHANNEL_TUNE 0x0d
|
||||
#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
|
||||
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
|
||||
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
|
||||
#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
|
||||
|
||||
struct wl1271_general_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
@ -397,6 +365,16 @@ struct wl1271_radio_parms_cmd {
|
||||
u8 padding3[2];
|
||||
} __packed;
|
||||
|
||||
struct wl1271_ext_radio_parms_cmd {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
struct wl1271_cmd_test_header test;
|
||||
|
||||
u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
|
||||
u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
struct wl1271_cmd_cal_channel_tune {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
@ -469,4 +447,13 @@ struct wl1271_cmd_disconnect {
|
||||
u8 padding;
|
||||
} __packed;
|
||||
|
||||
#define WL1271_CMD_STA_STATE_CONNECTED 1
|
||||
|
||||
struct wl1271_cmd_set_sta_state {
|
||||
struct wl1271_cmd_header header;
|
||||
|
||||
u8 state;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
#endif /* __WL1271_CMD_H__ */
|
||||
|
@ -595,7 +595,7 @@ struct conf_tx_ac_category {
|
||||
u16 tx_op_limit;
|
||||
};
|
||||
|
||||
#define CONF_TX_MAX_TID_COUNT 7
|
||||
#define CONF_TX_MAX_TID_COUNT 8
|
||||
|
||||
enum {
|
||||
CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/
|
||||
@ -911,6 +911,22 @@ struct conf_conn_settings {
|
||||
*/
|
||||
u8 psm_entry_retries;
|
||||
|
||||
/*
|
||||
* Specifies the maximum number of times to try transmit the PSM entry
|
||||
* null-func frame for each PSM entry attempt
|
||||
*
|
||||
* Range 0 - 255
|
||||
*/
|
||||
u8 psm_entry_nullfunc_retries;
|
||||
|
||||
/*
|
||||
* Specifies the time to linger in active mode after successfully
|
||||
* transmitting the PSM entry null-func frame.
|
||||
*
|
||||
* Range 0 - 255 TU's
|
||||
*/
|
||||
u8 psm_entry_hangover_period;
|
||||
|
||||
/*
|
||||
*
|
||||
* Specifies the interval of the connection keep-alive null-func
|
||||
@ -1016,6 +1032,64 @@ struct conf_roam_trigger_settings {
|
||||
u8 avg_weight_snr_data;
|
||||
};
|
||||
|
||||
struct conf_scan_settings {
|
||||
/*
|
||||
* The minimum time to wait on each channel for active scans
|
||||
*
|
||||
* Range: 0 - 65536 tu
|
||||
*/
|
||||
u16 min_dwell_time_active;
|
||||
|
||||
/*
|
||||
* The maximum time to wait on each channel for active scans
|
||||
*
|
||||
* Range: 0 - 65536 tu
|
||||
*/
|
||||
u16 max_dwell_time_active;
|
||||
|
||||
/*
|
||||
* The maximum time to wait on each channel for passive scans
|
||||
*
|
||||
* Range: 0 - 65536 tu
|
||||
*/
|
||||
u16 min_dwell_time_passive;
|
||||
|
||||
/*
|
||||
* The maximum time to wait on each channel for passive scans
|
||||
*
|
||||
* Range: 0 - 65536 tu
|
||||
*/
|
||||
u16 max_dwell_time_passive;
|
||||
|
||||
/*
|
||||
* Number of probe requests to transmit on each active scan channel
|
||||
*
|
||||
* Range: u8
|
||||
*/
|
||||
u16 num_probe_reqs;
|
||||
|
||||
};
|
||||
|
||||
/* these are number of channels on the band divided by two, rounded up */
|
||||
#define CONF_TX_PWR_COMPENSATION_LEN_2 7
|
||||
#define CONF_TX_PWR_COMPENSATION_LEN_5 18
|
||||
|
||||
struct conf_rf_settings {
|
||||
/*
|
||||
* Per channel power compensation for 2.4GHz
|
||||
*
|
||||
* Range: s8
|
||||
*/
|
||||
u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
|
||||
|
||||
/*
|
||||
* Per channel power compensation for 5GHz
|
||||
*
|
||||
* Range: s8
|
||||
*/
|
||||
u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
|
||||
};
|
||||
|
||||
struct conf_drv_settings {
|
||||
struct conf_sg_settings sg;
|
||||
struct conf_rx_settings rx;
|
||||
@ -1024,6 +1098,8 @@ struct conf_drv_settings {
|
||||
struct conf_itrim_settings itrim;
|
||||
struct conf_pm_config_settings pm_config;
|
||||
struct conf_roam_trigger_settings roam_trigger;
|
||||
struct conf_scan_settings scan;
|
||||
struct conf_rf_settings rf;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work)
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (unlikely(wl->state == WL1271_STATE_OFF))
|
||||
goto out;
|
||||
|
||||
if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
|
||||
goto out;
|
||||
|
||||
@ -52,7 +55,7 @@ void wl1271_pspoll_work(struct work_struct *work)
|
||||
* delivery failure occurred, and no-one changed state since, so
|
||||
* we should go back to powersave.
|
||||
*/
|
||||
wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true);
|
||||
wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
@ -70,7 +73,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
|
||||
|
||||
/* force active mode receive data from the AP */
|
||||
if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
|
||||
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true);
|
||||
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
|
||||
wl->basic_rate, true);
|
||||
if (ret < 0)
|
||||
return;
|
||||
set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
|
||||
@ -91,6 +95,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
|
||||
bool *beacon_loss)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 total_retries = wl->conf.conn.psm_entry_retries;
|
||||
|
||||
wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
|
||||
|
||||
@ -104,10 +109,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
|
||||
break;
|
||||
}
|
||||
|
||||
if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
|
||||
if (wl->psm_entry_retry < total_retries) {
|
||||
wl->psm_entry_retry++;
|
||||
ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
|
||||
true);
|
||||
wl->basic_rate, true);
|
||||
} else {
|
||||
wl1271_info("No ack to nullfunc from AP.");
|
||||
wl->psm_entry_retry = 0;
|
||||
@ -143,7 +148,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
|
||||
/* make sure the firmware goes to active mode - the frame to
|
||||
be sent next will indicate to the AP, that we are active. */
|
||||
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
|
||||
false);
|
||||
wl->basic_rate, false);
|
||||
break;
|
||||
case EVENT_EXIT_POWER_SAVE_SUCCESS:
|
||||
default:
|
||||
|
@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
|
||||
int wl1271_init_templates_config(struct wl1271 *wl)
|
||||
{
|
||||
int ret, i;
|
||||
size_t size;
|
||||
|
||||
/* send empty templates for fw memory reservation */
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
|
||||
@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (wl1271_11a_enabled()) {
|
||||
size_t size = sizeof(struct wl12xx_probe_req_template);
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
||||
NULL, size, 0,
|
||||
WL1271_RATE_AUTOMATIC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
size = sizeof(struct wl12xx_probe_req_template);
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
|
||||
NULL, size, 0,
|
||||
WL1271_RATE_AUTOMATIC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
|
||||
sizeof(struct wl12xx_null_data_template),
|
||||
@ -223,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_cmd_ext_radio_parms(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Template settings */
|
||||
ret = wl1271_init_templates_config(wl);
|
||||
if (ret < 0)
|
||||
@ -291,8 +294,16 @@ int wl1271_hw_init(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
goto out_free_memmap;
|
||||
|
||||
/* Default TID configuration */
|
||||
/* Default TID/AC configuration */
|
||||
BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
|
||||
for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
|
||||
conf_ac = &wl->conf.tx.ac_conf[i];
|
||||
ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
|
||||
conf_ac->cw_max, conf_ac->aifsn,
|
||||
conf_ac->tx_op_limit);
|
||||
if (ret < 0)
|
||||
goto out_free_memmap;
|
||||
|
||||
conf_tid = &wl->conf.tx.tid_conf[i];
|
||||
ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
|
||||
conf_tid->channel_type,
|
||||
@ -305,16 +316,6 @@ int wl1271_hw_init(struct wl1271 *wl)
|
||||
goto out_free_memmap;
|
||||
}
|
||||
|
||||
/* Default AC configuration */
|
||||
for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
|
||||
conf_ac = &wl->conf.tx.ac_conf[i];
|
||||
ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
|
||||
conf_ac->cw_max, conf_ac->aifsn,
|
||||
conf_ac->tx_op_limit);
|
||||
if (ret < 0)
|
||||
goto out_free_memmap;
|
||||
}
|
||||
|
||||
/* Configure TX rate classes */
|
||||
ret = wl1271_acx_rate_policies(wl);
|
||||
if (ret < 0)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user