Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
10be7eb36b
125 changed files with 3769 additions and 2017 deletions
|
@ -1000,7 +1000,6 @@ CONFIG_TIGON3=y
|
|||
CONFIG_SPIDER_NET=m
|
||||
CONFIG_GELIC_NET=m
|
||||
CONFIG_GELIC_WIRELESS=y
|
||||
# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set
|
||||
# CONFIG_QLA3XXX is not set
|
||||
# CONFIG_ATL1 is not set
|
||||
# CONFIG_ATL1E is not set
|
||||
|
|
|
@ -593,7 +593,6 @@ CONFIG_MII=m
|
|||
CONFIG_NETDEV_1000=y
|
||||
CONFIG_GELIC_NET=y
|
||||
CONFIG_GELIC_WIRELESS=y
|
||||
# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
|
||||
#
|
||||
|
|
|
@ -2368,20 +2368,6 @@ config GELIC_WIRELESS
|
|||
the driver automatically distinguishes the models, you can
|
||||
safely enable this option even if you have a wireless-less model.
|
||||
|
||||
config GELIC_WIRELESS_OLD_PSK_INTERFACE
|
||||
bool "PS3 Wireless private PSK interface (OBSOLETE)"
|
||||
depends on GELIC_WIRELESS
|
||||
select WEXT_PRIV
|
||||
help
|
||||
This option retains the obsolete private interface to pass
|
||||
the PSK from user space programs to the driver. The PSK
|
||||
stands for 'Pre Shared Key' and is used for WPA[2]-PSK
|
||||
(WPA-Personal) environment.
|
||||
If WPA[2]-PSK is used and you need to use old programs that
|
||||
support only this old interface, say Y. Otherwise N.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config FSL_PQ_MDIO
|
||||
tristate "Freescale PQ MDIO"
|
||||
depends on FSL_SOC
|
||||
|
|
|
@ -1389,113 +1389,6 @@ static int gelic_wl_get_mode(struct net_device *netdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
|
||||
/* SIOCIWFIRSTPRIV */
|
||||
static int hex2bin(u8 *str, u8 *bin, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
static unsigned char *hex = "0123456789ABCDEF";
|
||||
unsigned char *p, *q;
|
||||
u8 tmp;
|
||||
|
||||
if (len != WPA_PSK_LEN * 2)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < WPA_PSK_LEN * 2; i += 2) {
|
||||
p = strchr(hex, toupper(str[i]));
|
||||
q = strchr(hex, toupper(str[i + 1]));
|
||||
if (!p || !q) {
|
||||
pr_info("%s: unconvertible PSK digit=%d\n",
|
||||
__func__, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
tmp = ((p - hex) << 4) + (q - hex);
|
||||
*bin++ = tmp;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int gelic_wl_priv_set_psk(struct net_device *net_dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *data, char *extra)
|
||||
{
|
||||
struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
|
||||
unsigned int len;
|
||||
unsigned long irqflag;
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("%s:<- len=%d\n", __func__, data->data.length);
|
||||
len = data->data.length - 1;
|
||||
if (len <= 2)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&wl->lock, irqflag);
|
||||
if (extra[0] == '"' && extra[len - 1] == '"') {
|
||||
pr_debug("%s: passphrase mode\n", __func__);
|
||||
/* pass phrase */
|
||||
if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) {
|
||||
pr_info("%s: passphrase too long\n", __func__);
|
||||
ret = -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
memset(wl->psk, 0, sizeof(wl->psk));
|
||||
wl->psk_len = len - 2;
|
||||
memcpy(wl->psk, &(extra[1]), wl->psk_len);
|
||||
wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
|
||||
} else {
|
||||
ret = hex2bin(extra, wl->psk, len);
|
||||
if (ret)
|
||||
goto out;
|
||||
wl->psk_len = WPA_PSK_LEN;
|
||||
wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
|
||||
}
|
||||
set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
|
||||
out:
|
||||
spin_unlock_irqrestore(&wl->lock, irqflag);
|
||||
pr_debug("%s:->\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gelic_wl_priv_get_psk(struct net_device *net_dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *data, char *extra)
|
||||
{
|
||||
struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
|
||||
char *p;
|
||||
unsigned long irqflag;
|
||||
unsigned int i;
|
||||
|
||||
pr_debug("%s:<-\n", __func__);
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
spin_lock_irqsave(&wl->lock, irqflag);
|
||||
p = extra;
|
||||
if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) {
|
||||
if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) {
|
||||
for (i = 0; i < wl->psk_len; i++) {
|
||||
sprintf(p, "%02xu", wl->psk[i]);
|
||||
p += 2;
|
||||
}
|
||||
*p = '\0';
|
||||
data->data.length = wl->psk_len * 2;
|
||||
} else {
|
||||
*p++ = '"';
|
||||
memcpy(p, wl->psk, wl->psk_len);
|
||||
p += wl->psk_len;
|
||||
*p++ = '"';
|
||||
*p = '\0';
|
||||
data->data.length = wl->psk_len + 2;
|
||||
}
|
||||
} else
|
||||
/* no psk set */
|
||||
data->data.length = 0;
|
||||
spin_unlock_irqrestore(&wl->lock, irqflag);
|
||||
pr_debug("%s:-> %d\n", __func__, data->data.length);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SIOCGIWNICKN */
|
||||
static int gelic_wl_get_nick(struct net_device *net_dev,
|
||||
struct iw_request_info *info,
|
||||
|
@ -1571,8 +1464,10 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
|
|||
init_completion(&wl->scan_done);
|
||||
/*
|
||||
* If we have already a bss list, don't try to get new
|
||||
* unless we are doing an ESSID scan
|
||||
*/
|
||||
if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
|
||||
if ((!essid_len && !always_scan)
|
||||
&& wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
|
||||
pr_debug("%s: already has the list\n", __func__);
|
||||
complete(&wl->scan_done);
|
||||
goto out;
|
||||
|
@ -1673,7 +1568,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
|
|||
}
|
||||
}
|
||||
|
||||
/* put them in the newtork_list */
|
||||
/* put them in the network_list */
|
||||
for (i = 0, scan_info_size = 0, scan_info = buf;
|
||||
scan_info_size < data_len;
|
||||
i++, scan_info_size += be16_to_cpu(scan_info->size),
|
||||
|
@ -2009,7 +1904,7 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
|
|||
/* PSK type */
|
||||
wpa->psk_type = cpu_to_be16(wl->psk_type);
|
||||
#ifdef DEBUG
|
||||
pr_debug("%s: sec=%s psktype=%s\nn", __func__,
|
||||
pr_debug("%s: sec=%s psktype=%s\n", __func__,
|
||||
wpasecstr(wpa->security),
|
||||
(wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
|
||||
"BIN" : "passphrase");
|
||||
|
@ -2019,9 +1914,9 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
|
|||
* the debug log because this dumps your precious
|
||||
* passphrase/key.
|
||||
*/
|
||||
pr_debug("%s: psk=%s\n",
|
||||
pr_debug("%s: psk=%s\n", __func__,
|
||||
(wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
|
||||
(char *)"N/A" : (char *)wpa->psk);
|
||||
"N/A" : wpa->psk);
|
||||
#endif
|
||||
#endif
|
||||
/* issue wpa setup */
|
||||
|
@ -2406,40 +2301,10 @@ static const iw_handler gelic_wl_wext_handler[] =
|
|||
IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
|
||||
static struct iw_priv_args gelic_wl_private_args[] =
|
||||
{
|
||||
{
|
||||
.cmd = GELIC_WL_PRIV_SET_PSK,
|
||||
.set_args = IW_PRIV_TYPE_CHAR |
|
||||
(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
|
||||
.name = "set_psk"
|
||||
},
|
||||
{
|
||||
.cmd = GELIC_WL_PRIV_GET_PSK,
|
||||
.get_args = IW_PRIV_TYPE_CHAR |
|
||||
(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
|
||||
.name = "get_psk"
|
||||
}
|
||||
};
|
||||
|
||||
static const iw_handler gelic_wl_private_handler[] =
|
||||
{
|
||||
gelic_wl_priv_set_psk,
|
||||
gelic_wl_priv_get_psk,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct iw_handler_def gelic_wl_wext_handler_def = {
|
||||
.num_standard = ARRAY_SIZE(gelic_wl_wext_handler),
|
||||
.standard = gelic_wl_wext_handler,
|
||||
.get_wireless_stats = gelic_wl_get_wireless_stats,
|
||||
#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
|
||||
.num_private = ARRAY_SIZE(gelic_wl_private_handler),
|
||||
.num_private_args = ARRAY_SIZE(gelic_wl_private_args),
|
||||
.private = gelic_wl_private_handler,
|
||||
.private_args = gelic_wl_private_args,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct net_device * __devinit gelic_wl_alloc(struct gelic_card *card)
|
||||
|
|
|
@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
|
|||
WepKeyRid wkr;
|
||||
int rc;
|
||||
|
||||
if (keylen == 0) {
|
||||
airo_print_err(ai->dev->name, "%s: key length to set was zero",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
WARN_ON(keylen == 0);
|
||||
|
||||
memset(&wkr, 0, sizeof(wkr));
|
||||
wkr.len = cpu_to_le16(sizeof(wkr));
|
||||
|
@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev,
|
|||
if (dwrq->length > MIN_KEY_SIZE)
|
||||
key.len = MAX_KEY_SIZE;
|
||||
else
|
||||
if (dwrq->length > 0)
|
||||
key.len = MIN_KEY_SIZE;
|
||||
else
|
||||
/* Disable the key */
|
||||
key.len = 0;
|
||||
/* Check if the key is not marked as invalid */
|
||||
if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
|
||||
/* Cleanup */
|
||||
|
@ -6590,14 +6582,24 @@ static int airo_set_encodeext(struct net_device *dev,
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Send the key to the card */
|
||||
if (key.len == 0) {
|
||||
rc = set_wep_tx_idx(local, idx, perm, 1);
|
||||
if (rc < 0) {
|
||||
airo_print_err(local->dev->name,
|
||||
"failed to set WEP transmit index to %d: %d.",
|
||||
idx, rc);
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
|
||||
if (rc < 0) {
|
||||
airo_print_err(local->dev->name, "failed to set WEP key"
|
||||
" at index %d: %d.", idx, rc);
|
||||
airo_print_err(local->dev->name,
|
||||
"failed to set WEP key at index %d: %d.",
|
||||
idx, rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the flags */
|
||||
if(encoding->flags & IW_ENCODE_DISABLED)
|
||||
|
|
|
@ -74,7 +74,6 @@ struct ath_common;
|
|||
|
||||
struct ath_bus_ops {
|
||||
void (*read_cachesize)(struct ath_common *common, int *csz);
|
||||
void (*cleanup)(struct ath_common *common);
|
||||
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
|
||||
void (*bt_coex_prep)(struct ath_common *common);
|
||||
};
|
||||
|
|
|
@ -535,7 +535,7 @@ struct ath5k_txq_info {
|
|||
u32 tqi_cbr_period; /* Constant bit rate period */
|
||||
u32 tqi_cbr_overflow_limit;
|
||||
u32 tqi_burst_time;
|
||||
u32 tqi_ready_time; /* Not used */
|
||||
u32 tqi_ready_time; /* Time queue waits after an event */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -1516,7 +1516,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
|
|||
|
||||
ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
if (sc->opmode == NL80211_IFTYPE_AP ||
|
||||
sc->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||
/*
|
||||
|
@ -1543,10 +1544,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
|
|||
if (ret) {
|
||||
ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
|
||||
"hardware queue!\n", __func__);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
|
||||
/* reconfigure cabq with ready time to 80% of beacon_interval */
|
||||
ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
qi.tqi_ready_time = (sc->bintval * 80) / 100;
|
||||
ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
|
|||
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
|
||||
/* HP Compaq C700 (nitrousnrg@gmail.com) */
|
||||
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
|
||||
/* LiteOn AR5BXB63 (magooz@salug.it) */
|
||||
{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
|
||||
/* IBM-specific AR5212 (all others) */
|
||||
{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
|
||||
/* Dell Vostro A860 (shahar@shahar-or.co.il) */
|
||||
|
|
|
@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
|||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_CAB:
|
||||
/* XXX: use BCN_SENT_GT, if we can figure out how */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
|
||||
AR5K_QCU_MISC_FRSHED_DBA_GT |
|
||||
AR5K_QCU_MISC_CBREXP_DIS |
|
||||
AR5K_QCU_MISC_CBREXP_BCN_DIS);
|
||||
|
||||
ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
|
||||
ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
|
||||
(AR5K_TUNE_SW_BEACON_RESP -
|
||||
AR5K_TUNE_DMA_BEACON_RESP) -
|
||||
AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
|
||||
|
|
|
@ -1374,7 +1374,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
|||
* Set clocks to 32KHz operation and use an
|
||||
* external 32KHz crystal when sleeping if one
|
||||
* exists */
|
||||
if (ah->ah_version == AR5K_AR5212)
|
||||
if (ah->ah_version == AR5K_AR5212 &&
|
||||
ah->ah_op_mode != NL80211_IFTYPE_AP)
|
||||
ath5k_hw_set_sleep_clock(ah, true);
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
|
|||
*csz = L1_CACHE_BYTES >> 2;
|
||||
}
|
||||
|
||||
static void ath_ahb_cleanup(struct ath_common *common)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)common->priv;
|
||||
iounmap(sc->mem);
|
||||
}
|
||||
|
||||
static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)common->priv;
|
||||
|
@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
|||
|
||||
static struct ath_bus_ops ath_ahb_bus_ops = {
|
||||
.read_cachesize = ath_ahb_read_cachesize,
|
||||
.cleanup = ath_ahb_cleanup,
|
||||
|
||||
.eeprom_read = ath_ahb_eeprom_read,
|
||||
};
|
||||
|
||||
|
@ -164,12 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
|
|||
if (hw) {
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
void __iomem *mem = sc->mem;
|
||||
|
||||
ath9k_deinit_device(sc);
|
||||
free_irq(sc->irq, sc);
|
||||
ieee80211_free_hw(sc->hw);
|
||||
ath_bus_cleanup(common);
|
||||
iounmap(mem);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -364,6 +364,7 @@ struct ath_btcoex {
|
|||
int bt_stomp_type; /* Types of BT stomping */
|
||||
u32 btcoex_no_stomp; /* in usec */
|
||||
u32 btcoex_period; /* in usec */
|
||||
u32 btscan_no_stomp; /* in usec */
|
||||
struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
|
||||
};
|
||||
|
||||
|
@ -429,6 +430,7 @@ void ath_deinit_leds(struct ath_softc *sc);
|
|||
#define SC_OP_SCANNING BIT(10)
|
||||
#define SC_OP_TSF_RESET BIT(11)
|
||||
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
|
||||
#define SC_OP_BT_SCAN BIT(13)
|
||||
|
||||
/* Powersave flags */
|
||||
#define PS_WAIT_FOR_BEACON BIT(0)
|
||||
|
@ -478,6 +480,7 @@ struct ath_softc {
|
|||
u8 nbcnvifs;
|
||||
u16 nvifs;
|
||||
bool ps_enabled;
|
||||
bool ps_idle;
|
||||
unsigned long ps_usecount;
|
||||
enum ath9k_int imask;
|
||||
|
||||
|
@ -535,11 +538,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
|||
common->bus_ops->read_cachesize(common, csz);
|
||||
}
|
||||
|
||||
static inline void ath_bus_cleanup(struct ath_common *common)
|
||||
{
|
||||
common->bus_ops->cleanup(common);
|
||||
}
|
||||
|
||||
extern struct ieee80211_ops ath9k_ops;
|
||||
extern int modparam_nohwcrypt;
|
||||
|
||||
|
|
|
@ -25,10 +25,12 @@
|
|||
|
||||
#define ATH_BTCOEX_DEF_BT_PERIOD 45
|
||||
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
|
||||
#define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90
|
||||
#define ATH_BTCOEX_BMISS_THRESH 50
|
||||
|
||||
#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */
|
||||
#define ATH_BT_CNT_THRESHOLD 3
|
||||
#define ATH_BT_CNT_SCAN_THRESHOLD 15
|
||||
|
||||
enum ath_btcoex_scheme {
|
||||
ATH_BTCOEX_CFG_NONE,
|
||||
|
|
|
@ -75,17 +75,24 @@ static const struct file_operations fops_debug = {
|
|||
|
||||
#endif
|
||||
|
||||
#define DMA_BUF_LEN 1024
|
||||
|
||||
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
char buf[1024];
|
||||
char *buf;
|
||||
int retval;
|
||||
unsigned int len = 0;
|
||||
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
|
||||
int i, qcuOffset = 0, dcuOffset = 0;
|
||||
u32 *qcuBase = &val[0], *dcuBase = &val[4];
|
||||
|
||||
buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
REG_WRITE_D(ah, AR_MACMISC,
|
||||
|
@ -93,20 +100,20 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
|||
(AR_MACMISC_MISC_OBS_BUS_1 <<
|
||||
AR_MACMISC_MISC_OBS_BUS_MSB_S)));
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"Raw DMA Debug values:\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
|
||||
if (i % 4 == 0)
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
|
||||
|
||||
val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
|
||||
i, val[i]);
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
|
||||
|
@ -120,7 +127,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
|||
dcuBase++;
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"%2d %2x %1x %2x %2x\n",
|
||||
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
|
||||
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
|
||||
|
@ -128,35 +135,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
|||
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"qcu_stitch state: %2x qcu_fetch state: %2x\n",
|
||||
(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"qcu_complete state: %2x dcu_complete state: %2x\n",
|
||||
(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"dcu_arb state: %2x dcu_fp state: %2x\n",
|
||||
(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
|
||||
(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
|
||||
(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
|
||||
(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n",
|
||||
REG_READ_D(ah, AR_OBS_BUS_1));
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
len += snprintf(buf + len, DMA_BUF_LEN - len,
|
||||
"AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_dma = {
|
||||
|
|
|
@ -230,12 +230,17 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
|
|||
|
||||
if (time_after(jiffies, btcoex->bt_priority_time +
|
||||
msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
|
||||
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
|
||||
sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
|
||||
/* Detect if colocated bt started scanning */
|
||||
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
|
||||
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
|
||||
"BT scan detected");
|
||||
sc->sc_flags |= (SC_OP_BT_SCAN |
|
||||
SC_OP_BT_PRIORITY_DETECTED);
|
||||
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
|
||||
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
|
||||
"BT priority traffic detected");
|
||||
sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
|
||||
} else {
|
||||
sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
|
||||
}
|
||||
|
||||
btcoex->bt_priority_cnt = 0;
|
||||
|
@ -316,12 +321,17 @@ static void ath_btcoex_period_timer(unsigned long data)
|
|||
struct ath_softc *sc = (struct ath_softc *) data;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
u32 timer_period;
|
||||
bool is_btscan;
|
||||
|
||||
ath_detect_bt_priority(sc);
|
||||
|
||||
is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
|
||||
|
||||
spin_lock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
|
||||
ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
btcoex->bt_stomp_type);
|
||||
|
||||
spin_unlock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
|
@ -329,11 +339,12 @@ static void ath_btcoex_period_timer(unsigned long data)
|
|||
if (btcoex->hw_timer_enabled)
|
||||
ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
|
||||
|
||||
timer_period = is_btscan ? btcoex->btscan_no_stomp :
|
||||
btcoex->btcoex_no_stomp;
|
||||
ath9k_gen_timer_start(ah,
|
||||
btcoex->no_stomp_timer,
|
||||
(ath9k_hw_gettsf32(ah) +
|
||||
btcoex->btcoex_no_stomp),
|
||||
btcoex->btcoex_no_stomp * 10);
|
||||
timer_period), timer_period * 10);
|
||||
btcoex->hw_timer_enabled = true;
|
||||
}
|
||||
|
||||
|
@ -350,13 +361,14 @@ static void ath_btcoex_no_stomp_timer(void *arg)
|
|||
struct ath_softc *sc = (struct ath_softc *)arg;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
|
||||
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
|
||||
"no stomp timer running \n");
|
||||
|
||||
spin_lock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
|
||||
ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
|
||||
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
|
||||
ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
|
||||
|
@ -371,6 +383,8 @@ int ath_init_btcoex_timer(struct ath_softc *sc)
|
|||
btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
|
||||
btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
|
||||
btcoex->btcoex_period / 100;
|
||||
btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
|
||||
btcoex->btcoex_period / 100;
|
||||
|
||||
setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
|
||||
(unsigned long) sc);
|
||||
|
@ -405,7 +419,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
|
|||
|
||||
btcoex->bt_priority_cnt = 0;
|
||||
btcoex->bt_priority_time = jiffies;
|
||||
sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
|
||||
sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
|
||||
|
||||
mod_timer(&btcoex->period_timer, jiffies);
|
||||
}
|
||||
|
|
|
@ -334,7 +334,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.ht_enable = 1;
|
||||
ah->config.ofdm_trig_low = 200;
|
||||
ah->config.ofdm_trig_high = 500;
|
||||
ah->config.cck_trig_high = 200;
|
||||
|
@ -346,6 +345,11 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
|
|||
ah->config.spurchans[i][1] = AR_NO_SPUR;
|
||||
}
|
||||
|
||||
if (ah->hw_version.devid != AR2427_DEVID_PCIE)
|
||||
ah->config.ht_enable = 1;
|
||||
else
|
||||
ah->config.ht_enable = 0;
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
|
||||
/*
|
||||
|
@ -542,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid)
|
|||
case AR5416_DEVID_AR9287_PCI:
|
||||
case AR5416_DEVID_AR9287_PCIE:
|
||||
case AR9271_USB:
|
||||
case AR2427_DEVID_PCIE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define AR9280_DEVID_PCI 0x0029
|
||||
#define AR9280_DEVID_PCIE 0x002a
|
||||
#define AR9285_DEVID_PCIE 0x002b
|
||||
#define AR2427_DEVID_PCIE 0x002c
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
|
||||
|
|
|
@ -620,11 +620,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_AMPDU_AGGREGATION |
|
||||
IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_PS_NULLFUNC_STACK |
|
||||
IEEE80211_HW_SPECTRUM_MGMT;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
|
||||
hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
|
||||
|
||||
if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
|
||||
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
|
||||
|
||||
|
@ -640,8 +642,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
hw->max_rates = 4;
|
||||
hw->channel_change_time = 5000;
|
||||
hw->max_listen_interval = 10;
|
||||
/* Hardware supports 10 but we use 4 */
|
||||
hw->max_rate_tries = 4;
|
||||
hw->max_rate_tries = 10;
|
||||
hw->sta_data_size = sizeof(struct ath_node);
|
||||
hw->vif_data_size = sizeof(struct ath_vif);
|
||||
|
||||
|
|
|
@ -143,7 +143,9 @@ void ath9k_ps_restore(struct ath_softc *sc)
|
|||
if (--sc->ps_usecount != 0)
|
||||
goto unlock;
|
||||
|
||||
if (sc->ps_enabled &&
|
||||
if (sc->ps_idle)
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
||||
else if (sc->ps_enabled &&
|
||||
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
|
@ -204,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
|||
r = ath9k_hw_reset(ah, hchan, fastcc);
|
||||
if (r) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to reset channel (%u Mhz) "
|
||||
"Unable to reset channel (%u MHz), "
|
||||
"reset status %d\n",
|
||||
channel->center_freq, r);
|
||||
spin_unlock_bh(&sc->sc_resetlock);
|
||||
|
@ -867,7 +869,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
r = ath9k_hw_reset(ah, ah->curchan, false);
|
||||
if (r) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to reset channel %u (%uMhz) ",
|
||||
"Unable to reset channel (%u MHz), "
|
||||
"reset status %d\n",
|
||||
channel->center_freq, r);
|
||||
}
|
||||
|
@ -922,7 +924,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
r = ath9k_hw_reset(ah, ah->curchan, false);
|
||||
if (r) {
|
||||
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
|
||||
"Unable to reset channel %u (%uMhz) "
|
||||
"Unable to reset channel (%u MHz), "
|
||||
"reset status %d\n",
|
||||
channel->center_freq, r);
|
||||
}
|
||||
|
@ -1528,6 +1530,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|||
spin_unlock_bh(&sc->wiphy_lock);
|
||||
|
||||
if (enable_radio) {
|
||||
sc->ps_idle = false;
|
||||
ath_radio_enable(sc, hw);
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"not-idle: enabling radio\n");
|
||||
|
@ -1624,8 +1627,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|||
}
|
||||
|
||||
skip_chan_change:
|
||||
if (changed & IEEE80211_CONF_CHANGE_POWER)
|
||||
if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
||||
sc->config.txpowlimit = 2 * conf->power_level;
|
||||
ath_update_txpow(sc);
|
||||
}
|
||||
|
||||
spin_lock_bh(&sc->wiphy_lock);
|
||||
disable_radio = ath9k_all_wiphys_idle(sc);
|
||||
|
@ -1633,6 +1638,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|||
|
||||
if (disable_radio) {
|
||||
ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
|
||||
sc->ps_idle = true;
|
||||
ath_radio_disable(sc, hw);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
|||
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
|
||||
{ 0 }
|
||||
|
@ -49,16 +50,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
|
|||
*csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
|
||||
}
|
||||
|
||||
static void ath_pci_cleanup(struct ath_common *common)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
struct pci_dev *pdev = to_pci_dev(sc->dev);
|
||||
|
||||
pci_iounmap(pdev, sc->mem);
|
||||
pci_disable_device(pdev);
|
||||
pci_release_region(pdev, 0);
|
||||
}
|
||||
|
||||
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) common->ah;
|
||||
|
@ -98,7 +89,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
|
|||
|
||||
static const struct ath_bus_ops ath_pci_bus_ops = {
|
||||
.read_cachesize = ath_pci_read_cachesize,
|
||||
.cleanup = ath_pci_cleanup,
|
||||
.eeprom_read = ath_pci_eeprom_read,
|
||||
.bt_coex_prep = ath_pci_bt_coex_prep,
|
||||
};
|
||||
|
@ -245,12 +235,15 @@ static void ath_pci_remove(struct pci_dev *pdev)
|
|||
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
void __iomem *mem = sc->mem;
|
||||
|
||||
ath9k_deinit_device(sc);
|
||||
free_irq(sc->irq, sc);
|
||||
ieee80211_free_hw(sc->hw);
|
||||
ath_bus_cleanup(common);
|
||||
|
||||
pci_iounmap(pdev, mem);
|
||||
pci_disable_device(pdev);
|
||||
pci_release_region(pdev, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -678,13 +678,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
|
|||
* For Multi Rate Retry we use a different number of
|
||||
* retry attempt counts. This ends up looking like this:
|
||||
*
|
||||
* MRR[0] = 2
|
||||
* MRR[1] = 2
|
||||
* MRR[2] = 2
|
||||
* MRR[3] = 4
|
||||
* MRR[0] = 4
|
||||
* MRR[1] = 4
|
||||
* MRR[2] = 4
|
||||
* MRR[3] = 8
|
||||
*
|
||||
*/
|
||||
try_per_rate = sc->hw->max_rate_tries;
|
||||
try_per_rate = 4;
|
||||
|
||||
rate_table = sc->cur_rate_table;
|
||||
rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
|
||||
|
@ -714,7 +714,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
|
|||
for ( ; i < 4; i++) {
|
||||
/* Use twice the number of tries for the last MRR segment. */
|
||||
if (i + 1 == 4)
|
||||
try_per_rate = 4;
|
||||
try_per_rate = 8;
|
||||
|
||||
ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
|
||||
/* All other rates in the series have RTS enabled */
|
||||
|
|
|
@ -429,7 +429,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
|
|||
sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
|
||||
ath_print(common, ATH_DBG_PS,
|
||||
"Going back to sleep after having received "
|
||||
"PS-Poll data (0x%x)\n",
|
||||
"PS-Poll data (0x%lx)\n",
|
||||
sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
|
|
|
@ -1547,9 +1547,9 @@ enum {
|
|||
|
||||
#define AR_BT_COEX_WEIGHT 0x8174
|
||||
#define AR_BT_COEX_WGHT 0xff55
|
||||
#define AR_STOMP_ALL_WLAN_WGHT 0xffcc
|
||||
#define AR_STOMP_LOW_WLAN_WGHT 0xaaa8
|
||||
#define AR_STOMP_NONE_WLAN_WGHT 0xaa00
|
||||
#define AR_STOMP_ALL_WLAN_WGHT 0xfcfc
|
||||
#define AR_STOMP_LOW_WLAN_WGHT 0xa8a8
|
||||
#define AR_STOMP_NONE_WLAN_WGHT 0x0000
|
||||
#define AR_BTCOEX_BT_WGHT 0x0000ffff
|
||||
#define AR_BTCOEX_BT_WGHT_S 0
|
||||
#define AR_BTCOEX_WL_WGHT 0xffff0000
|
||||
|
|
|
@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
|
|||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
ctsrate |= rate->hw_value_short;
|
||||
|
||||
/*
|
||||
* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
|
||||
* Check the first rate in the series to decide whether RTS/CTS
|
||||
* or CTS-to-self has to be used.
|
||||
*/
|
||||
if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
|
||||
flags = ATH9K_TXDESC_CTSENA;
|
||||
else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
|
||||
flags = ATH9K_TXDESC_RTSENA;
|
||||
|
||||
/* FIXME: Handle aggregation protection */
|
||||
if (sc->config.ath_aggr_prot &&
|
||||
(!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
|
||||
flags = ATH9K_TXDESC_RTSENA;
|
||||
}
|
||||
|
||||
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
|
||||
if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
|
||||
flags &= ~(ATH9K_TXDESC_RTSENA);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
bool is_40, is_sgi, is_sp;
|
||||
int phy;
|
||||
|
@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
|
|||
series[i].Tries = rates[i].count;
|
||||
series[i].ChSel = common->tx_chainmask;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
|
||||
if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
|
||||
(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
flags |= ATH9K_TXDESC_RTSENA;
|
||||
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
flags |= ATH9K_TXDESC_CTSENA;
|
||||
}
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_2040;
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
|
@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
|
|||
phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
|
||||
}
|
||||
|
||||
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
|
||||
if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
|
||||
flags &= ~ATH9K_TXDESC_RTSENA;
|
||||
|
||||
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
|
||||
if (flags & ATH9K_TXDESC_RTSENA)
|
||||
flags &= ~ATH9K_TXDESC_CTSENA;
|
||||
|
||||
/* set dur_update_en for l-sig computation except for PS-Poll frames */
|
||||
ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
|
||||
bf->bf_lastbf->bf_desc,
|
||||
|
@ -1862,7 +1857,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
|||
sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
|
||||
ath_print(common, ATH_DBG_PS,
|
||||
"Going back to sleep after having "
|
||||
"received TX status (0x%x)\n",
|
||||
"received TX status (0x%lx)\n",
|
||||
sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
|
|
|
@ -65,11 +65,11 @@ enum ATH_DEBUG {
|
|||
#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
|
||||
|
||||
#ifdef CONFIG_ATH_DEBUG
|
||||
void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...);
|
||||
void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 3, 4)));
|
||||
#else
|
||||
static inline void ath_print(struct ath_common *common,
|
||||
int dbg_mask,
|
||||
const char *fmt, ...)
|
||||
static inline void __attribute__ ((format (printf, 3, 4)))
|
||||
ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH_DEBUG */
|
||||
|
|
|
@ -844,7 +844,9 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
|
|||
}
|
||||
|
||||
static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
|
||||
struct ieee80211_key_conf *keyconf, const u8 *addr,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key_conf *keyconf,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 iv32, u16 *phase1key)
|
||||
{
|
||||
struct b43_wl *wl = hw_to_b43_wl(hw);
|
||||
|
@ -854,19 +856,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
|
|||
if (B43_WARN_ON(!modparam_hwtkip))
|
||||
return;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
/* This is only called from the RX path through mac80211, where
|
||||
* our mutex is already locked. */
|
||||
B43_WARN_ON(!mutex_is_locked(&wl->mutex));
|
||||
dev = wl->current_dev;
|
||||
if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
|
||||
goto out_unlock;
|
||||
B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
|
||||
|
||||
keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
|
||||
|
||||
rx_tkip_phase1_write(dev, index, iv32, phase1key);
|
||||
keymac_write(dev, index, addr);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&wl->mutex);
|
||||
/* only pairwise TKIP keys are supported right now */
|
||||
if (WARN_ON(!sta))
|
||||
return;
|
||||
keymac_write(dev, index, sta->addr);
|
||||
}
|
||||
|
||||
static void do_key_write(struct b43_wldev *dev,
|
||||
|
@ -3571,6 +3573,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
|
|||
dev = wl->current_dev;
|
||||
phy = &dev->phy;
|
||||
|
||||
if (conf_is_ht(conf))
|
||||
phy->is_40mhz =
|
||||
(conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
|
||||
else
|
||||
phy->is_40mhz = false;
|
||||
|
||||
b43_mac_suspend(dev);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
|
||||
|
|
|
@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
|
|||
{
|
||||
b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
|
||||
struct b43_c32 b43_cordic(int theta)
|
||||
{
|
||||
u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
|
||||
58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
|
||||
229, 115, 57, 29, };
|
||||
u8 i;
|
||||
s32 tmp;
|
||||
s8 signx = 1;
|
||||
u32 angle = 0;
|
||||
struct b43_c32 ret = { .i = 39797, .q = 0, };
|
||||
|
||||
while (theta > (180 << 16))
|
||||
theta -= (360 << 16);
|
||||
while (theta < -(180 << 16))
|
||||
theta += (360 << 16);
|
||||
|
||||
if (theta > (90 << 16)) {
|
||||
theta -= (180 << 16);
|
||||
signx = -1;
|
||||
} else if (theta < -(90 << 16)) {
|
||||
theta += (180 << 16);
|
||||
signx = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 17; i++) {
|
||||
if (theta > angle) {
|
||||
tmp = ret.i - (ret.q >> i);
|
||||
ret.q += ret.i >> i;
|
||||
ret.i = tmp;
|
||||
angle += arctg[i];
|
||||
} else {
|
||||
tmp = ret.i + (ret.q >> i);
|
||||
ret.q -= ret.i >> i;
|
||||
ret.i = tmp;
|
||||
angle -= arctg[i];
|
||||
}
|
||||
}
|
||||
|
||||
ret.i *= signx;
|
||||
ret.q *= signx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
|
||||
struct b43_wldev;
|
||||
|
||||
/* Complex number using 2 32-bit signed integers */
|
||||
struct b43_c32 { s32 i, q; };
|
||||
|
||||
#define CORDIC_CONVERT(value) (((value) >= 0) ? \
|
||||
((((value) >> 15) + 1) >> 1) : \
|
||||
-((((-(value)) >> 15) + 1) >> 1))
|
||||
|
||||
/* PHY register routing bits */
|
||||
#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
|
||||
|
@ -212,6 +218,9 @@ struct b43_phy {
|
|||
bool supports_2ghz;
|
||||
bool supports_5ghz;
|
||||
|
||||
/* HT info */
|
||||
bool is_40mhz;
|
||||
|
||||
/* GMODE bit enabled? */
|
||||
bool gmode;
|
||||
|
||||
|
@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
|
|||
*/
|
||||
void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
|
||||
|
||||
struct b43_c32 b43_cordic(int theta);
|
||||
|
||||
#endif /* LINUX_B43_PHY_COMMON_H_ */
|
||||
|
|
|
@ -1767,47 +1767,6 @@ static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Complex number using 2 32-bit signed integers */
|
||||
typedef struct {s32 i, q;} lpphy_c32;
|
||||
|
||||
static lpphy_c32 lpphy_cordic(int theta)
|
||||
{
|
||||
u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
|
||||
58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
|
||||
229, 115, 57, 29, };
|
||||
int i, tmp, signx = 1, angle = 0;
|
||||
lpphy_c32 ret = { .i = 39797, .q = 0, };
|
||||
|
||||
theta = clamp_t(int, theta, -180, 180);
|
||||
|
||||
if (theta > 90) {
|
||||
theta -= 180;
|
||||
signx = -1;
|
||||
} else if (theta < -90) {
|
||||
theta += 180;
|
||||
signx = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 17; i++) {
|
||||
if (theta > angle) {
|
||||
tmp = ret.i - (ret.q >> i);
|
||||
ret.q += ret.i >> i;
|
||||
ret.i = tmp;
|
||||
angle += arctg[i];
|
||||
} else {
|
||||
tmp = ret.i + (ret.q >> i);
|
||||
ret.q -= ret.i >> i;
|
||||
ret.i = tmp;
|
||||
angle -= arctg[i];
|
||||
}
|
||||
}
|
||||
|
||||
ret.i *= signx;
|
||||
ret.q *= signx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
|
||||
u16 wait)
|
||||
{
|
||||
|
@ -1825,8 +1784,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
|
|||
{
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
u16 buf[64];
|
||||
int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
|
||||
lpphy_c32 sample;
|
||||
int i, samples = 0, angle = 0;
|
||||
int rotation = (((36 * freq) / 20) << 16) / 100;
|
||||
struct b43_c32 sample;
|
||||
|
||||
lpphy->tx_tone_freq = freq;
|
||||
|
||||
|
@ -1842,10 +1802,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
|
|||
}
|
||||
|
||||
for (i = 0; i < samples; i++) {
|
||||
sample = lpphy_cordic(angle);
|
||||
sample = b43_cordic(angle);
|
||||
angle += rotation;
|
||||
buf[i] = ((sample.i * max) & 0xFF) << 8;
|
||||
buf[i] |= (sample.q * max) & 0xFF;
|
||||
buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
|
||||
buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
|
||||
}
|
||||
|
||||
b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -973,6 +973,12 @@ struct b43_phy_n {
|
|||
bool hang_avoid;
|
||||
bool mute;
|
||||
u16 papd_epsilon_offset[2];
|
||||
s32 preamble_override;
|
||||
u32 bb_mult_save;
|
||||
|
||||
bool gain_boost;
|
||||
bool elna_gain_config;
|
||||
bool band5g_pwrgain;
|
||||
|
||||
u8 mphase_cal_phase_id;
|
||||
u16 mphase_txcal_cmdidx;
|
||||
|
@ -985,6 +991,7 @@ struct b43_phy_n {
|
|||
bool txiqlocal_coeffsvalid;
|
||||
struct b43_phy_n_txpwrindex txpwrindex[2];
|
||||
|
||||
u8 txrx_chain;
|
||||
u16 tx_rx_cal_phy_saveregs[11];
|
||||
u16 tx_rx_cal_radio_saveregs[22];
|
||||
|
||||
|
|
|
@ -2883,6 +2883,67 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
|
|||
0x9084, 0x9267, 0x9056, 0x9234
|
||||
};
|
||||
|
||||
const s16 tbl_tx_filter_coef_rev4[7][15] = {
|
||||
{ -377, 137, -407, 208, -1527,
|
||||
956, 93, 186, 93, 230,
|
||||
-44, 230, 20, -191, 201 },
|
||||
{ -77, 20, -98, 49, -93,
|
||||
60, 56, 111, 56, 26,
|
||||
-5, 26, 34, -32, 34 },
|
||||
{ -360, 164, -376, 164, -1533,
|
||||
576, 308, -314, 308, 121,
|
||||
-73, 121, 91, 124, 91 },
|
||||
{ -295, 200, -363, 142, -1391,
|
||||
826, 151, 301, 151, 151,
|
||||
301, 151, 602, -752, 602 },
|
||||
{ -92, 58, -96, 49, -104,
|
||||
44, 17, 35, 17, 12,
|
||||
25, 12, 13, 27, 13 },
|
||||
{ -375, 136, -399, 209, -1479,
|
||||
949, 130, 260, 130, 230,
|
||||
-44, 230, 201, -191, 201 },
|
||||
{ 0xed9, 0xc8, 0xe95, 0x8e, 0xa91,
|
||||
0x33a, 0x97, 0x12d, 0x97, 0x97,
|
||||
0x12d, 0x97, 0x25a, 0xd10, 0x25a }
|
||||
};
|
||||
|
||||
/* addr0, addr1, bmask, shift */
|
||||
const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = {
|
||||
{ 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */
|
||||
{ 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */
|
||||
{ 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */
|
||||
{ 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */
|
||||
{ 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */
|
||||
{ 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */
|
||||
{ 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */
|
||||
{ 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */
|
||||
{ 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */
|
||||
{ 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */
|
||||
{ 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */
|
||||
{ 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */
|
||||
{ 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */
|
||||
{ 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */
|
||||
};
|
||||
|
||||
/* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */
|
||||
const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
|
||||
{ 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */
|
||||
{ 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
|
||||
{ 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
|
||||
{ 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
|
||||
{ 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
|
||||
{ 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
|
||||
{ 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
|
||||
{ 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
|
||||
{ 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
|
||||
{ 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
|
||||
{ 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
|
||||
{ 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
|
||||
{ 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */
|
||||
{ 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */
|
||||
{ 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
|
||||
};
|
||||
|
||||
static inline void assert_ntab_array_sizes(void)
|
||||
{
|
||||
#undef check
|
||||
|
@ -2919,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void)
|
|||
#undef check
|
||||
}
|
||||
|
||||
u32 b43_ntab_read(struct b43_wldev *dev, u32 offset)
|
||||
{
|
||||
u32 type, value;
|
||||
|
||||
type = offset & B43_NTAB_TYPEMASK;
|
||||
offset &= ~B43_NTAB_TYPEMASK;
|
||||
B43_WARN_ON(offset > 0xFFFF);
|
||||
|
||||
switch (type) {
|
||||
case B43_NTAB_8BIT:
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
|
||||
break;
|
||||
case B43_NTAB_16BIT:
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
break;
|
||||
case B43_NTAB_32BIT:
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
|
||||
value <<= 16;
|
||||
value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
value = 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
unsigned int nr_elements, void *_data)
|
||||
{
|
||||
u32 type;
|
||||
u8 *data = _data;
|
||||
unsigned int i;
|
||||
|
||||
type = offset & B43_NTAB_TYPEMASK;
|
||||
offset &= ~B43_NTAB_TYPEMASK;
|
||||
B43_WARN_ON(offset > 0xFFFF);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
|
||||
for (i = 0; i < nr_elements; i++) {
|
||||
switch (type) {
|
||||
case B43_NTAB_8BIT:
|
||||
*data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
|
||||
data++;
|
||||
break;
|
||||
case B43_NTAB_16BIT:
|
||||
*((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
data += 2;
|
||||
break;
|
||||
case B43_NTAB_32BIT:
|
||||
*((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
|
||||
*((u32 *)data) <<= 16;
|
||||
*((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
data += 4;
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
|
||||
{
|
||||
u32 type;
|
||||
|
@ -2952,6 +3079,46 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
|
|||
assert_ntab_array_sizes();
|
||||
}
|
||||
|
||||
void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
|
||||
unsigned int nr_elements, const void *_data)
|
||||
{
|
||||
u32 type, value;
|
||||
const u8 *data = _data;
|
||||
unsigned int i;
|
||||
|
||||
type = offset & B43_NTAB_TYPEMASK;
|
||||
offset &= ~B43_NTAB_TYPEMASK;
|
||||
B43_WARN_ON(offset > 0xFFFF);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
|
||||
for (i = 0; i < nr_elements; i++) {
|
||||
switch (type) {
|
||||
case B43_NTAB_8BIT:
|
||||
value = *data;
|
||||
data++;
|
||||
B43_WARN_ON(value & ~0xFF);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
|
||||
break;
|
||||
case B43_NTAB_16BIT:
|
||||
value = *((u16 *)data);
|
||||
data += 2;
|
||||
B43_WARN_ON(value & ~0xFFFF);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
|
||||
break;
|
||||
case B43_NTAB_32BIT:
|
||||
value = *((u32 *)data);
|
||||
data += 4;
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
|
||||
value & 0xFFFF);
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ntab_upload(dev, offset, data) do { \
|
||||
unsigned int i; \
|
||||
for (i = 0; i < (offset##_SIZE); i++) \
|
||||
|
|
|
@ -51,6 +51,22 @@ struct nphy_txiqcal_ladder {
|
|||
u8 g_env;
|
||||
};
|
||||
|
||||
struct nphy_rf_control_override_rev2 {
|
||||
u8 addr0;
|
||||
u8 addr1;
|
||||
u16 bmask;
|
||||
u8 shift;
|
||||
};
|
||||
|
||||
struct nphy_rf_control_override_rev3 {
|
||||
u16 val_mask;
|
||||
u8 val_shift;
|
||||
u8 en_addr0;
|
||||
u8 val_addr0;
|
||||
u8 en_addr1;
|
||||
u8 val_addr1;
|
||||
};
|
||||
|
||||
/* Upload the default register value table.
|
||||
* If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
|
||||
* table is uploaded. If "ignore_uploadflag" is true, we upload any value
|
||||
|
@ -142,7 +158,12 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
|
|||
#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10
|
||||
#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12
|
||||
|
||||
u32 b43_ntab_read(struct b43_wldev *dev, u32 offset);
|
||||
void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
unsigned int nr_elements, void *_data);
|
||||
void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
|
||||
void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
|
||||
unsigned int nr_elements, const void *_data);
|
||||
|
||||
void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
|
||||
void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
|
||||
|
@ -172,5 +193,11 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
|
|||
extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
|
||||
extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
|
||||
extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
|
||||
extern const s16 tbl_tx_filter_coef_rev4[7][15];
|
||||
|
||||
extern const struct nphy_rf_control_override_rev2
|
||||
tbl_rf_control_override_rev2[];
|
||||
extern const struct nphy_rf_control_override_rev3
|
||||
tbl_rf_control_override_rev3[];
|
||||
|
||||
#endif /* B43_TABLES_NPHY_H_ */
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
config IWLWIFI
|
||||
tristate "Intel Wireless Wifi"
|
||||
depends on PCI && MAC80211 && EXPERIMENTAL
|
||||
depends on PCI && MAC80211
|
||||
select FW_LOADER
|
||||
|
||||
config IWLWIFI_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwlagn driver"
|
||||
depends on IWLWIFI
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwlagn driver.
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
bool "Enable full debugging output in iwlagn and iwl3945 drivers"
|
||||
depends on IWLWIFI
|
||||
|
@ -120,9 +114,3 @@ config IWL3945
|
|||
inserted in and removed from the running kernel whenever you want),
|
||||
say M here and read <file:Documentation/kbuild/modules.txt>. The
|
||||
module will be called iwl3945.
|
||||
|
||||
config IWL3945_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwl3945 driver"
|
||||
depends on IWL3945
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwl3945 driver.
|
||||
|
|
|
@ -3,7 +3,6 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
|
|||
iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
|
||||
iwlcore-objs += iwl-scan.o iwl-led.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
|
||||
|
||||
CFLAGS_iwl-devtrace.o := -I$(src)
|
||||
|
@ -20,3 +19,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
|
|||
# 3945
|
||||
obj-$(CONFIG_IWL3945) += iwl3945.o
|
||||
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
|
|||
~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
|
||||
}
|
||||
|
||||
static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
|
||||
.min_nrg_cck = 95,
|
||||
.max_nrg_cck = 0, /* not used, set to 0 */
|
||||
.auto_corr_min_ofdm = 90,
|
||||
.auto_corr_min_ofdm_mrc = 170,
|
||||
.auto_corr_min_ofdm_x1 = 120,
|
||||
.auto_corr_min_ofdm_mrc_x1 = 240,
|
||||
|
||||
.auto_corr_max_ofdm = 120,
|
||||
.auto_corr_max_ofdm_mrc = 210,
|
||||
.auto_corr_max_ofdm_x1 = 155,
|
||||
.auto_corr_max_ofdm_mrc_x1 = 290,
|
||||
|
||||
.auto_corr_min_cck = 125,
|
||||
.auto_corr_max_cck = 200,
|
||||
.auto_corr_min_cck_mrc = 170,
|
||||
.auto_corr_max_cck_mrc = 400,
|
||||
.nrg_th_cck = 95,
|
||||
.nrg_th_ofdm = 95,
|
||||
|
||||
.barker_corr_th_min = 190,
|
||||
.barker_corr_th_min_mrc = 390,
|
||||
.nrg_th_cca = 62,
|
||||
};
|
||||
|
||||
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 <= IWL50_NUM_QUEUES)
|
||||
priv->cfg->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->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 *
|
||||
sizeof(struct iwl5000_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
|
||||
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
|
||||
priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
|
||||
|
||||
priv->hw_params.max_bsm_size = 0;
|
||||
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
|
||||
BIT(IEEE80211_BAND_5GHZ);
|
||||
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
|
||||
|
||||
priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
|
||||
priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
|
||||
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
|
||||
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
|
||||
|
||||
if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
|
||||
priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
|
||||
|
||||
/* Set initial sensitivity parameters */
|
||||
/* Set initial calibration set */
|
||||
priv->hw_params.sens = &iwl1000_sensitivity;
|
||||
priv->hw_params.calib_init_cfg =
|
||||
BIT(IWL_CALIB_XTAL) |
|
||||
BIT(IWL_CALIB_LO) |
|
||||
BIT(IWL_CALIB_TX_IQ) |
|
||||
BIT(IWL_CALIB_TX_IQ_PERD) |
|
||||
BIT(IWL_CALIB_BASE_BAND);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct iwl_lib_ops iwl1000_lib = {
|
||||
.set_hw_params = iwl5000_hw_set_hw_params,
|
||||
.set_hw_params = iwl1000_hw_set_hw_params,
|
||||
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
|
||||
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
|
||||
.txq_set_sched = iwl5000_txq_set_sched,
|
||||
|
@ -106,6 +176,7 @@ static struct iwl_lib_ops iwl1000_lib = {
|
|||
.dump_nic_event_log = iwl_dump_nic_event_log,
|
||||
.dump_nic_error_log = iwl_dump_nic_error_log,
|
||||
.dump_csr = iwl_dump_csr,
|
||||
.dump_fh = iwl_dump_fh,
|
||||
.init_alive_start = iwl5000_init_alive_start,
|
||||
.alive_notify = iwl5000_alive_notify,
|
||||
.send_tx_power = iwl5000_send_tx_power,
|
||||
|
@ -139,6 +210,7 @@ static struct iwl_lib_ops iwl1000_lib = {
|
|||
.temperature = iwl5000_temperature,
|
||||
.set_ct_kill = iwl1000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl1000_ops = {
|
||||
|
@ -174,6 +246,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
|
|||
.use_rts_for_ht = 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_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1000_bg_cfg = {
|
||||
|
@ -200,6 +273,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
|
|||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -1951,11 +1951,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
|
|||
}
|
||||
|
||||
/* Add the broadcast address so we can send broadcast frames */
|
||||
if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
|
||||
IWL_INVALID_STATION) {
|
||||
IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
|
||||
return -EIO;
|
||||
}
|
||||
priv->cfg->ops->lib->add_bcast_station(priv);
|
||||
|
||||
/* If we have set the ASSOC_MSK and we are in BSS mode then
|
||||
* add the IWL_AP_ID to the station rate table */
|
||||
|
@ -2796,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib = {
|
|||
.post_associate = iwl3945_post_associate,
|
||||
.isr = iwl_isr_legacy,
|
||||
.config_ap = iwl3945_config_ap,
|
||||
.add_bcast_station = iwl3945_add_bcast_station,
|
||||
};
|
||||
|
||||
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
|
||||
|
@ -2830,6 +2827,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
|
|||
.ht_greenfield_support = false,
|
||||
.led_compensation = 64,
|
||||
.broken_powersave = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
static struct iwl_cfg iwl3945_abg_cfg = {
|
||||
|
@ -2847,6 +2845,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
|
|||
.ht_greenfield_support = false,
|
||||
.led_compensation = 64,
|
||||
.broken_powersave = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -2206,6 +2206,7 @@ static struct iwl_lib_ops iwl4965_lib = {
|
|||
.temperature = iwl4965_temperature_calib,
|
||||
.set_ct_kill = iwl4965_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl4965_ops = {
|
||||
|
@ -2239,6 +2240,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
|
|||
.broken_powersave = true,
|
||||
.led_compensation = 61,
|
||||
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
/* Module firmware */
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -263,8 +263,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
|
|||
|
||||
.auto_corr_max_ofdm = 120,
|
||||
.auto_corr_max_ofdm_mrc = 210,
|
||||
.auto_corr_max_ofdm_x1 = 155,
|
||||
.auto_corr_max_ofdm_mrc_x1 = 290,
|
||||
.auto_corr_max_ofdm_x1 = 120,
|
||||
.auto_corr_max_ofdm_mrc_x1 = 240,
|
||||
|
||||
.auto_corr_min_cck = 125,
|
||||
.auto_corr_max_cck = 200,
|
||||
|
@ -412,12 +412,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
|
|||
/*
|
||||
* ucode
|
||||
*/
|
||||
static int iwl5000_load_section(struct iwl_priv *priv,
|
||||
struct fw_desc *image,
|
||||
u32 dst_addr)
|
||||
static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
|
||||
struct fw_desc *image, u32 dst_addr)
|
||||
{
|
||||
dma_addr_t phy_addr = image->p_addr;
|
||||
u32 byte_cnt = image->len;
|
||||
int ret;
|
||||
|
||||
priv->ucode_write_complete = 0;
|
||||
|
||||
iwl_write_direct32(priv,
|
||||
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
|
||||
|
@ -447,6 +449,20 @@ static int iwl5000_load_section(struct iwl_priv *priv,
|
|||
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
|
||||
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
|
||||
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
priv->ucode_write_complete, 5 * HZ);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
IWL_ERR(priv, "Could not load the %s uCode section due "
|
||||
"to interrupt\n", name);
|
||||
return ret;
|
||||
}
|
||||
if (!ret) {
|
||||
IWL_ERR(priv, "Could not load the %s uCode section\n",
|
||||
name);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -456,48 +472,13 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = iwl5000_load_section(priv, inst_image,
|
||||
ret = iwl5000_load_section(priv, "INST", inst_image,
|
||||
IWL50_RTC_INST_LOWER_BOUND);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
|
||||
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
priv->ucode_write_complete, 5 * HZ);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
IWL_ERR(priv, "Could not load the INST uCode section due "
|
||||
"to interrupt\n");
|
||||
return ret;
|
||||
}
|
||||
if (!ret) {
|
||||
IWL_ERR(priv, "Could not load the INST uCode section\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
priv->ucode_write_complete = 0;
|
||||
|
||||
ret = iwl5000_load_section(
|
||||
priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
|
||||
|
||||
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
priv->ucode_write_complete, 5 * HZ);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
IWL_ERR(priv, "Could not load the INST uCode section due "
|
||||
"to interrupt\n");
|
||||
return ret;
|
||||
} else if (!ret) {
|
||||
IWL_ERR(priv, "Could not load the DATA uCode section\n");
|
||||
return -ETIMEDOUT;
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
priv->ucode_write_complete = 0;
|
||||
|
||||
return ret;
|
||||
return iwl5000_load_section(priv, "DATA", data_image,
|
||||
IWL50_RTC_DATA_LOWER_BOUND);
|
||||
}
|
||||
|
||||
int iwl5000_load_ucode(struct iwl_priv *priv)
|
||||
|
@ -1467,6 +1448,7 @@ struct iwl_lib_ops iwl5000_lib = {
|
|||
.dump_nic_event_log = iwl_dump_nic_event_log,
|
||||
.dump_nic_error_log = iwl_dump_nic_error_log,
|
||||
.dump_csr = iwl_dump_csr,
|
||||
.dump_fh = iwl_dump_fh,
|
||||
.load_ucode = iwl5000_load_ucode,
|
||||
.init_alive_start = iwl5000_init_alive_start,
|
||||
.alive_notify = iwl5000_alive_notify,
|
||||
|
@ -1502,6 +1484,7 @@ struct iwl_lib_ops iwl5000_lib = {
|
|||
.temperature = iwl5000_temperature,
|
||||
.set_ct_kill = iwl5000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl5150_lib = {
|
||||
|
@ -1555,6 +1538,7 @@ static struct iwl_lib_ops iwl5150_lib = {
|
|||
.temperature = iwl5150_temperature,
|
||||
.set_ct_kill = iwl5150_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl5000_ops = {
|
||||
|
@ -1602,6 +1586,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
|
|||
.led_compensation = 51,
|
||||
.use_rts_for_ht = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_bgn_cfg = {
|
||||
|
@ -1626,6 +1611,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
|
|||
.led_compensation = 51,
|
||||
.use_rts_for_ht = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_abg_cfg = {
|
||||
|
@ -1648,6 +1634,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
|
|||
.use_bsm = false,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_agn_cfg = {
|
||||
|
@ -1672,6 +1659,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
|
|||
.led_compensation = 51,
|
||||
.use_rts_for_ht = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5350_agn_cfg = {
|
||||
|
@ -1696,6 +1684,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
|||
.led_compensation = 51,
|
||||
.use_rts_for_ht = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5150_agn_cfg = {
|
||||
|
@ -1720,6 +1709,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
|
|||
.led_compensation = 51,
|
||||
.use_rts_for_ht = true, /* use rts/cts protection */
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5150_abg_cfg = {
|
||||
|
@ -1742,6 +1732,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
|
|||
.use_bsm = false,
|
||||
.led_compensation = 51,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -108,7 +108,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
|
|||
|
||||
.auto_corr_max_ofdm = 145,
|
||||
.auto_corr_max_ofdm_mrc = 232,
|
||||
.auto_corr_max_ofdm_x1 = 145,
|
||||
.auto_corr_max_ofdm_x1 = 110,
|
||||
.auto_corr_max_ofdm_mrc_x1 = 232,
|
||||
|
||||
.auto_corr_min_cck = 125,
|
||||
|
@ -158,11 +158,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
/* Set initial sensitivity parameters */
|
||||
/* Set initial calibration set */
|
||||
priv->hw_params.sens = &iwl6000_sensitivity;
|
||||
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
|
||||
case CSR_HW_REV_TYPE_6x50:
|
||||
priv->hw_params.calib_init_cfg =
|
||||
BIT(IWL_CALIB_XTAL) |
|
||||
BIT(IWL_CALIB_DC) |
|
||||
BIT(IWL_CALIB_LO) |
|
||||
BIT(IWL_CALIB_TX_IQ) |
|
||||
BIT(IWL_CALIB_BASE_BAND);
|
||||
|
||||
break;
|
||||
default:
|
||||
priv->hw_params.calib_init_cfg =
|
||||
BIT(IWL_CALIB_XTAL) |
|
||||
BIT(IWL_CALIB_LO) |
|
||||
BIT(IWL_CALIB_TX_IQ) |
|
||||
BIT(IWL_CALIB_BASE_BAND);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,6 +230,7 @@ static struct iwl_lib_ops iwl6000_lib = {
|
|||
.dump_nic_event_log = iwl_dump_nic_event_log,
|
||||
.dump_nic_error_log = iwl_dump_nic_error_log,
|
||||
.dump_csr = iwl_dump_csr,
|
||||
.dump_fh = iwl_dump_fh,
|
||||
.init_alive_start = iwl5000_init_alive_start,
|
||||
.alive_notify = iwl5000_alive_notify,
|
||||
.send_tx_power = iwl5000_send_tx_power,
|
||||
|
@ -251,6 +266,7 @@ static struct iwl_lib_ops iwl6000_lib = {
|
|||
.temperature = iwl5000_temperature,
|
||||
.set_ct_kill = iwl6000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6000_ops = {
|
||||
|
@ -307,6 +323,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2abg_cfg = {
|
||||
|
@ -336,6 +353,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
|
@ -365,6 +383,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
|
@ -395,6 +414,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
|
@ -424,6 +444,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
|
@ -454,6 +475,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
|||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
.support_ct_kill_exit = true,
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -191,7 +191,7 @@ enum {
|
|||
IWL_RATE_2M_MASK)
|
||||
|
||||
#define IWL_CCK_RATES_MASK \
|
||||
(IWL_BASIC_RATES_MASK | \
|
||||
(IWL_CCK_BASIC_RATES_MASK | \
|
||||
IWL_RATE_5M_MASK | \
|
||||
IWL_RATE_11M_MASK)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -73,13 +73,7 @@
|
|||
#define VD
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
|
||||
#define VS "s"
|
||||
#else
|
||||
#define VS
|
||||
#endif
|
||||
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD VS
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD
|
||||
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
|
@ -203,7 +197,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
|
|||
priv->start_calib = 0;
|
||||
|
||||
/* Add the broadcast address so we can send broadcast frames */
|
||||
iwl_add_bcast_station(priv);
|
||||
priv->cfg->ops->lib->add_bcast_station(priv);
|
||||
|
||||
|
||||
/* If we have set the ASSOC_MSK and we are in BSS mode then
|
||||
* add the IWL_AP_ID to the station rate table */
|
||||
|
@ -704,7 +699,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
|
|||
spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
|
||||
}
|
||||
|
||||
void iwl_continuous_event_trace(struct iwl_priv *priv)
|
||||
static void iwl_continuous_event_trace(struct iwl_priv *priv)
|
||||
{
|
||||
u32 capacity; /* event log capacity in # entries */
|
||||
u32 base; /* SRAM byte address of event log header */
|
||||
|
@ -888,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
|||
priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
|
||||
priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
|
||||
priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
|
||||
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
|
||||
iwl_rx_spectrum_measure_notif;
|
||||
priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
|
||||
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
|
||||
iwl_rx_pm_debug_statistics_notif;
|
||||
|
@ -901,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
|||
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
|
||||
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
|
||||
|
||||
iwl_setup_spectrum_handlers(priv);
|
||||
iwl_setup_rx_scan_handlers(priv);
|
||||
|
||||
/* status change handler */
|
||||
|
@ -1761,7 +1757,7 @@ static const char *desc_lookup_text[] = {
|
|||
"DEBUG_1",
|
||||
"DEBUG_2",
|
||||
"DEBUG_3",
|
||||
"UNKNOWN"
|
||||
"ADVANCED SYSASSERT"
|
||||
};
|
||||
|
||||
static const char *desc_lookup(int i)
|
||||
|
@ -1965,7 +1961,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
|||
IWL_ERR(priv,
|
||||
"Invalid event log pointer 0x%08X for %s uCode\n",
|
||||
base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
|
||||
return pos;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* event log header */
|
||||
|
@ -2013,7 +2009,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
|||
bufsz = size * 48;
|
||||
*buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!*buf)
|
||||
return pos;
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
|
||||
/*
|
||||
|
@ -2443,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
static void iwl_bg_up(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
__iwl_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl_bg_restart(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
|
||||
|
@ -2471,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data)
|
|||
ieee80211_restart_hw(priv->hw);
|
||||
} else {
|
||||
iwl_down(priv);
|
||||
queue_work(priv->workqueue, &priv->up);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
__iwl_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2607,7 +2597,7 @@ void iwl_post_associate(struct iwl_priv *priv)
|
|||
* Not a mac80211 entry point function, but it fits in with all the
|
||||
* other mac80211 functions grouped here.
|
||||
*/
|
||||
static int iwl_setup_mac(struct iwl_priv *priv)
|
||||
static int iwl_mac_setup_register(struct iwl_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
struct ieee80211_hw *hw = priv->hw;
|
||||
|
@ -2839,14 +2829,18 @@ void iwl_config_ap(struct iwl_priv *priv)
|
|||
}
|
||||
|
||||
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
|
||||
struct ieee80211_key_conf *keyconf, const u8 *addr,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key_conf *keyconf,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 iv32, u16 *phase1key)
|
||||
{
|
||||
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
|
||||
iwl_update_tkip_key(priv, keyconf,
|
||||
sta ? sta->addr : iwl_bcast_addr,
|
||||
iv32, phase1key);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
@ -3007,6 +3001,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
|
|||
break;
|
||||
case STA_NOTIFY_AWAKE:
|
||||
WARN_ON(!sta_priv->client);
|
||||
if (!sta_priv->asleep)
|
||||
break;
|
||||
sta_priv->asleep = false;
|
||||
sta_id = iwl_find_station(priv, sta->addr);
|
||||
if (sta_id != IWL_INVALID_STATION)
|
||||
|
@ -3283,7 +3279,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
|||
|
||||
init_waitqueue_head(&priv->wait_command_queue);
|
||||
|
||||
INIT_WORK(&priv->up, iwl_bg_up);
|
||||
INIT_WORK(&priv->restart, iwl_bg_restart);
|
||||
INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
|
||||
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
|
||||
|
@ -3368,6 +3363,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
|
|||
|
||||
priv->iw_mode = NL80211_IFTYPE_STATION;
|
||||
priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
|
||||
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
|
||||
|
||||
/* Choose which receivers/antennas to use */
|
||||
if (priv->cfg->ops->hcmd->set_rxon_chain)
|
||||
|
@ -3619,9 +3615,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
iwl_setup_deferred_work(priv);
|
||||
iwl_setup_rx_handlers(priv);
|
||||
|
||||
/**********************************
|
||||
* 8. Setup and register mac80211
|
||||
**********************************/
|
||||
/*********************************************
|
||||
* 8. Enable interrupts and read RFKILL state
|
||||
*********************************************/
|
||||
|
||||
/* enable interrupts if needed: hw bug w/a */
|
||||
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
|
||||
|
@ -3632,14 +3628,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
iwl_enable_interrupts(priv);
|
||||
|
||||
err = iwl_setup_mac(priv);
|
||||
if (err)
|
||||
goto out_remove_sysfs;
|
||||
|
||||
err = iwl_dbgfs_register(priv, DRV_NAME);
|
||||
if (err)
|
||||
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
|
@ -3651,6 +3639,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
iwl_power_initialize(priv);
|
||||
iwl_tt_initialize(priv);
|
||||
|
||||
/**************************************************
|
||||
* 9. Setup and register with mac80211 and debugfs
|
||||
**************************************************/
|
||||
err = iwl_mac_setup_register(priv);
|
||||
if (err)
|
||||
goto out_remove_sysfs;
|
||||
|
||||
err = iwl_dbgfs_register(priv, DRV_NAME);
|
||||
if (err)
|
||||
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
|
||||
|
||||
return 0;
|
||||
|
||||
out_remove_sysfs:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -2247,10 +2247,22 @@ struct iwl_link_quality_cmd {
|
|||
__le32 reserved2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* BT configuration enable flags:
|
||||
* bit 0 - 1: BT channel announcement enabled
|
||||
* 0: disable
|
||||
* bit 1 - 1: priority of BT device enabled
|
||||
* 0: disable
|
||||
* bit 2 - 1: BT 2 wire support enabled
|
||||
* 0: disable
|
||||
*/
|
||||
#define BT_COEX_DISABLE (0x0)
|
||||
#define BT_COEX_MODE_2W (0x1)
|
||||
#define BT_COEX_MODE_3W (0x2)
|
||||
#define BT_COEX_MODE_4W (0x3)
|
||||
#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
|
||||
#define BT_ENABLE_PRIORITY BIT(1)
|
||||
#define BT_ENABLE_2_WIRE BIT(2)
|
||||
|
||||
#define BT_COEX_DISABLE (0x0)
|
||||
#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
|
||||
|
||||
#define BT_LEAD_TIME_MIN (0x0)
|
||||
#define BT_LEAD_TIME_DEF (0x1E)
|
||||
|
@ -3095,7 +3107,12 @@ struct statistics_general {
|
|||
__le32 ttl_timestamp;
|
||||
struct statistics_div div;
|
||||
__le32 rx_enable_counter;
|
||||
__le32 reserved1;
|
||||
/*
|
||||
* num_of_sos_states:
|
||||
* count the number of times we have to re-tune
|
||||
* in order to get out of bad PHY status
|
||||
*/
|
||||
__le32 num_of_sos_states;
|
||||
__le32 reserved2;
|
||||
__le32 reserved3;
|
||||
} __attribute__ ((packed));
|
||||
|
@ -3160,13 +3177,30 @@ struct iwl_notif_statistics {
|
|||
|
||||
/*
|
||||
* MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
|
||||
*
|
||||
* uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
|
||||
* in regardless of how many missed beacons, which mean when driver receive the
|
||||
* notification, inside the command, it can find all the beacons information
|
||||
* which include number of total missed beacons, number of consecutive missed
|
||||
* beacons, number of beacons received and number of beacons expected to
|
||||
* receive.
|
||||
*
|
||||
* If uCode detected consecutive_missed_beacons > 5, it will reset the radio
|
||||
* in order to bring the radio/PHY back to working state; which has no relation
|
||||
* to when driver will perform sensitivity calibration.
|
||||
*
|
||||
* Driver should set it own missed_beacon_threshold to decide when to perform
|
||||
* sensitivity calibration based on number of consecutive missed beacons in
|
||||
* order to improve overall performance, especially in noisy environment.
|
||||
*
|
||||
*/
|
||||
/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
|
||||
* then this notification will be sent. */
|
||||
#define CONSECUTIVE_MISSED_BCONS_TH 20
|
||||
|
||||
#define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
|
||||
#define IWL_MISSED_BEACON_THRESHOLD_DEF (5)
|
||||
#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF
|
||||
|
||||
struct iwl_missed_beacon_notif {
|
||||
__le32 consequtive_missed_beacons;
|
||||
__le32 consecutive_missed_beacons;
|
||||
__le32 total_missed_becons;
|
||||
__le32 num_expected_beacons;
|
||||
__le32 num_recvd_beacons;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -47,6 +47,26 @@ MODULE_VERSION(IWLWIFI_VERSION);
|
|||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* set bt_coex_active to true, uCode will do kill/defer
|
||||
* every time the priority line is asserted (BT is sending signals on the
|
||||
* priority line in the PCIx).
|
||||
* set bt_coex_active to false, uCode will ignore the BT activity and
|
||||
* perform the normal operation
|
||||
*
|
||||
* User might experience transmit issue on some platform due to WiFi/BT
|
||||
* co-exist problem. The possible behaviors are:
|
||||
* Able to scan and finding all the available AP
|
||||
* Not able to associate with any AP
|
||||
* On those platforms, WiFi communication can be restored by set
|
||||
* "bt_coex_active" module parameter to "false"
|
||||
*
|
||||
* default: bt_coex_active = true (BT_COEX_ENABLE)
|
||||
*/
|
||||
static bool bt_coex_active = true;
|
||||
module_param(bt_coex_active, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
|
||||
|
||||
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
|
||||
{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
|
||||
0, COEX_UNASSOC_IDLE_FLAGS},
|
||||
|
@ -257,8 +277,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
|
|||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->cfg->ops->lib->apm_ops.init(priv);
|
||||
|
||||
/* Set interrupt coalescing timer to 512 usecs */
|
||||
iwl_write8(priv, CSR_INT_COALESCING, 512 / 32);
|
||||
/* Set interrupt coalescing calibration timer to default (512 usecs) */
|
||||
iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
|
@ -1353,6 +1373,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
|
|||
priv->cfg->ops->lib->dump_nic_error_log(priv);
|
||||
if (priv->cfg->ops->lib->dump_csr)
|
||||
priv->cfg->ops->lib->dump_csr(priv);
|
||||
if (priv->cfg->ops->lib->dump_fh)
|
||||
priv->cfg->ops->lib->dump_fh(priv, NULL, false);
|
||||
priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
|
||||
|
@ -1803,6 +1825,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
|
|||
if (val == 0xffffffff)
|
||||
val = 0;
|
||||
|
||||
/*
|
||||
* this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
|
||||
* (bit 15 before shifting it to 31) to clear when using interrupt
|
||||
* coalescing. fortunately, bits 18 and 19 stay set when this happens
|
||||
* so we use them to decide on the real state of the Rx bit.
|
||||
* In order words, bit 15 is set if bit 18 or bit 19 are set.
|
||||
*/
|
||||
if (val & 0xC0000)
|
||||
val |= 0x8000;
|
||||
|
||||
inta = (0xff & val) | ((0xff00 & val) << 16);
|
||||
IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
|
||||
inta, inta_mask, val);
|
||||
|
@ -1965,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
|
|||
int iwl_send_bt_config(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_bt_cmd bt_cmd = {
|
||||
.flags = BT_COEX_MODE_4W,
|
||||
.lead_time = BT_LEAD_TIME_DEF,
|
||||
.max_kill = BT_MAX_KILL_DEF,
|
||||
.kill_ack_mask = 0,
|
||||
.kill_cts_mask = 0,
|
||||
};
|
||||
|
||||
if (!bt_coex_active)
|
||||
bt_cmd.flags = BT_COEX_DISABLE;
|
||||
else
|
||||
bt_cmd.flags = BT_COEX_ENABLE;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "BT coex %s\n",
|
||||
(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
|
||||
|
||||
return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
|
||||
sizeof(struct iwl_bt_cmd), &bt_cmd);
|
||||
}
|
||||
|
@ -2592,23 +2631,21 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
|
|||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (priv->vif) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
|
||||
return -EOPNOTSUPP;
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->vif = vif;
|
||||
priv->iw_mode = vif->type;
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (vif->addr) {
|
||||
IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
|
||||
memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
|
||||
|
@ -2618,10 +2655,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
|
|||
/* we are not ready, will run again when ready */
|
||||
set_bit(STATUS_MODE_PENDING, &priv->status);
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_mac_add_interface);
|
||||
|
||||
|
@ -3268,6 +3306,93 @@ void iwl_dump_csr(struct iwl_priv *priv)
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_dump_csr);
|
||||
|
||||
const static char *get_fh_string(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_WPTR);
|
||||
IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
|
||||
IWL_CMD(FH_TSSR_TX_STATUS_REG);
|
||||
IWL_CMD(FH_TSSR_TX_ERROR_REG);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
int pos = 0;
|
||||
size_t bufsz = 0;
|
||||
#endif
|
||||
u32 fh_tbl[] = {
|
||||
FH_RSCSR_CHNL0_STTS_WPTR_REG,
|
||||
FH_RSCSR_CHNL0_RBDCB_BASE_REG,
|
||||
FH_RSCSR_CHNL0_WPTR,
|
||||
FH_MEM_RCSR_CHNL0_CONFIG_REG,
|
||||
FH_MEM_RSSR_SHARED_CTRL_REG,
|
||||
FH_MEM_RSSR_RX_STATUS_REG,
|
||||
FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
|
||||
FH_TSSR_TX_STATUS_REG,
|
||||
FH_TSSR_TX_ERROR_REG
|
||||
};
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (display) {
|
||||
bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
|
||||
*buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!*buf)
|
||||
return -ENOMEM;
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
"FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
" %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(priv, fh_tbl[i]));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
IWL_ERR(priv, "FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
IWL_ERR(priv, " %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(priv, fh_tbl[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_dump_fh);
|
||||
|
||||
void iwl_force_rf_reset(struct iwl_priv *priv)
|
||||
{
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (!iwl_is_associated(priv)) {
|
||||
IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* There is no easy and better way to force reset the radio,
|
||||
* the only known method is switching channel which will force to
|
||||
* reset and tune the radio.
|
||||
* Use internal short scan (single channel) operation to should
|
||||
* achieve this objective.
|
||||
* Driver should reset the radio when number of consecutive missed
|
||||
* beacon, or any other uCode error condition detected.
|
||||
*/
|
||||
IWL_DEBUG_INFO(priv, "perform radio reset.\n");
|
||||
iwl_internal_short_hw_scan(priv);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_force_rf_reset);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -71,7 +71,7 @@ struct iwl_cmd;
|
|||
|
||||
|
||||
#define IWLWIFI_VERSION "in-tree:"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
|
||||
|
@ -171,6 +171,7 @@ struct iwl_lib_ops {
|
|||
bool full_log, char **buf, bool display);
|
||||
void (*dump_nic_error_log)(struct iwl_priv *priv);
|
||||
void (*dump_csr)(struct iwl_priv *priv);
|
||||
int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
|
||||
int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
|
||||
/* power management */
|
||||
struct iwl_apm_ops apm_ops;
|
||||
|
@ -187,6 +188,8 @@ struct iwl_lib_ops {
|
|||
|
||||
/* temperature */
|
||||
struct iwl_temp_ops temp_ops;
|
||||
/* station management */
|
||||
void (*add_bcast_station)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_led_ops {
|
||||
|
@ -231,6 +234,8 @@ struct iwl_mod_params {
|
|||
* @adv_thermal_throttle: support advance thermal throttle
|
||||
* @support_ct_kill_exit: support ct kill exit condition
|
||||
* @support_wimax_coexist: support wimax/wifi co-exist
|
||||
* @plcp_delta_threshold: plcp error rate threshold used to trigger
|
||||
* radio tuning when there is a high receiving plcp error rate
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt API version. The
|
||||
* driver specifies which APIs it supports (with @ucode_api_max being the
|
||||
|
@ -287,6 +292,7 @@ struct iwl_cfg {
|
|||
bool adv_thermal_throttle;
|
||||
bool support_ct_kill_exit;
|
||||
const bool support_wimax_coexist;
|
||||
u8 plcp_delta_threshold;
|
||||
};
|
||||
|
||||
/***************************
|
||||
|
@ -423,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
|
|||
/* Handlers */
|
||||
void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwl_rx_statistics(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwl_reply_statistics(struct iwl_priv *priv,
|
||||
|
@ -493,6 +501,8 @@ void iwl_init_scan_params(struct iwl_priv *priv);
|
|||
int iwl_scan_cancel(struct iwl_priv *priv);
|
||||
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
|
||||
int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
|
||||
int iwl_internal_short_hw_scan(struct iwl_priv *priv);
|
||||
void iwl_force_rf_reset(struct iwl_priv *priv);
|
||||
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
|
||||
const u8 *ie, int ie_len, int left);
|
||||
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
|
||||
|
@ -523,14 +533,6 @@ int iwl_send_calib_results(struct iwl_priv *priv);
|
|||
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
|
||||
void iwl_calib_free_results(struct iwl_priv *priv);
|
||||
|
||||
/*******************************************************************************
|
||||
* Spectrum Measureemtns in iwl-spectrum.c
|
||||
******************************************************************************/
|
||||
#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
|
||||
void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
|
||||
#else
|
||||
static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
|
||||
#endif
|
||||
/*****************************************************
|
||||
* S e n d i n g H o s t C o m m a n d s *
|
||||
*****************************************************/
|
||||
|
@ -582,6 +584,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv);
|
|||
int iwl_dump_nic_event_log(struct iwl_priv *priv,
|
||||
bool full_log, char **buf, bool display);
|
||||
void iwl_dump_csr(struct iwl_priv *priv);
|
||||
int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv);
|
||||
#else
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project.
|
||||
*
|
||||
|
@ -67,59 +67,6 @@ do { \
|
|||
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct iwl_debugfs {
|
||||
const char *name;
|
||||
struct dentry *dir_drv;
|
||||
struct dentry *dir_data;
|
||||
struct dentry *dir_debug;
|
||||
struct dentry *dir_rf;
|
||||
struct dir_data_files {
|
||||
struct dentry *file_sram;
|
||||
struct dentry *file_nvm;
|
||||
struct dentry *file_stations;
|
||||
struct dentry *file_log_event;
|
||||
struct dentry *file_channels;
|
||||
struct dentry *file_status;
|
||||
struct dentry *file_interrupt;
|
||||
struct dentry *file_qos;
|
||||
struct dentry *file_thermal_throttling;
|
||||
struct dentry *file_led;
|
||||
struct dentry *file_disable_ht40;
|
||||
struct dentry *file_sleep_level_override;
|
||||
struct dentry *file_current_sleep_command;
|
||||
} dbgfs_data_files;
|
||||
struct dir_rf_files {
|
||||
struct dentry *file_disable_sensitivity;
|
||||
struct dentry *file_disable_chain_noise;
|
||||
struct dentry *file_disable_tx_power;
|
||||
} dbgfs_rf_files;
|
||||
struct dir_debug_files {
|
||||
struct dentry *file_rx_statistics;
|
||||
struct dentry *file_tx_statistics;
|
||||
struct dentry *file_traffic_log;
|
||||
struct dentry *file_rx_queue;
|
||||
struct dentry *file_tx_queue;
|
||||
struct dentry *file_ucode_rx_stats;
|
||||
struct dentry *file_ucode_tx_stats;
|
||||
struct dentry *file_ucode_general_stats;
|
||||
struct dentry *file_sensitivity;
|
||||
struct dentry *file_chain_noise;
|
||||
struct dentry *file_tx_power;
|
||||
struct dentry *file_power_save_status;
|
||||
struct dentry *file_clear_ucode_statistics;
|
||||
struct dentry *file_clear_traffic_statistics;
|
||||
struct dentry *file_csr;
|
||||
struct dentry *file_ucode_tracing;
|
||||
} dbgfs_debug_files;
|
||||
u32 sram_offset;
|
||||
u32 sram_len;
|
||||
};
|
||||
|
||||
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
|
||||
void iwl_dbgfs_unregister(struct iwl_priv *priv);
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define IWL_DEBUG(__priv, level, fmt, args...)
|
||||
#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
|
||||
|
@ -128,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
|
|||
{}
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
|
||||
|
||||
#ifndef CONFIG_IWLWIFI_DEBUGFS
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
|
||||
void iwl_dbgfs_unregister(struct iwl_priv *priv);
|
||||
#else
|
||||
static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
{
|
||||
return 0;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -1011,6 +1011,30 @@ struct iwl_event_log {
|
|||
int wraps_more_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* host interrupt timeout value
|
||||
* used with setting interrupt coalescing timer
|
||||
* the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
|
||||
*
|
||||
* default interrupt coalescing timer is 64 x 32 = 2048 usecs
|
||||
* default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
|
||||
*/
|
||||
#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
|
||||
#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
|
||||
|
||||
/*
|
||||
* This is the threshold value of plcp error rate per 100mSecs. It is
|
||||
* used to set and check for the validity of plcp_delta.
|
||||
*/
|
||||
#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)
|
||||
#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
|
||||
#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
|
||||
#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
|
||||
|
||||
struct iwl_priv {
|
||||
|
||||
/* ieee device used by generic ieee processing code */
|
||||
|
@ -1031,13 +1055,16 @@ struct iwl_priv {
|
|||
|
||||
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
|
||||
|
||||
#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
|
||||
/* spectrum measurement report caching */
|
||||
struct iwl_spectrum_notification measure_report;
|
||||
u8 measurement_status;
|
||||
#endif
|
||||
|
||||
/* ucode beacon time */
|
||||
u32 ucode_beacon_time;
|
||||
int missed_beacon_threshold;
|
||||
|
||||
/* storing the jiffies when the plcp error rate is received */
|
||||
unsigned long plcp_jiffies;
|
||||
|
||||
/* we allocate array of iwl4965_channel_info for NIC's valid channels.
|
||||
* Access via channel # using indirect index array */
|
||||
|
@ -1056,14 +1083,15 @@ struct iwl_priv {
|
|||
struct iwl_calib_result calib_results[IWL_CALIB_MAX];
|
||||
|
||||
/* Scan related variables */
|
||||
unsigned long last_scan_jiffies;
|
||||
unsigned long next_scan_jiffies;
|
||||
unsigned long scan_start;
|
||||
unsigned long scan_pass_start;
|
||||
unsigned long scan_start_tsf;
|
||||
unsigned long last_internal_scan_jiffies;
|
||||
void *scan;
|
||||
int scan_bands;
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
bool is_internal_short_scan;
|
||||
u8 scan_tx_ant[IEEE80211_NUM_BANDS];
|
||||
u8 mgmt_tx_ant;
|
||||
|
||||
|
@ -1162,6 +1190,8 @@ struct iwl_priv {
|
|||
struct iwl_notif_statistics statistics;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
struct iwl_notif_statistics accum_statistics;
|
||||
struct iwl_notif_statistics delta_statistics;
|
||||
struct iwl_notif_statistics max_delta;
|
||||
#endif
|
||||
|
||||
/* context information */
|
||||
|
@ -1234,15 +1264,10 @@ struct iwl_priv {
|
|||
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
struct work_struct up;
|
||||
struct work_struct restart;
|
||||
struct work_struct calibrated_work;
|
||||
struct work_struct scan_completed;
|
||||
struct work_struct rx_replenish;
|
||||
struct work_struct abort_scan;
|
||||
struct work_struct update_link_led;
|
||||
struct work_struct auth_work;
|
||||
struct work_struct report_work;
|
||||
struct work_struct request_scan;
|
||||
struct work_struct beacon_update;
|
||||
struct work_struct tt_work;
|
||||
|
@ -1278,7 +1303,8 @@ struct iwl_priv {
|
|||
u16 rx_traffic_idx;
|
||||
u8 *tx_traffic;
|
||||
u8 *rx_traffic;
|
||||
struct iwl_debugfs *dbgfs;
|
||||
struct dentry *debugfs_dir;
|
||||
u32 dbgfs_sram_offset, dbgfs_sram_len;
|
||||
#endif /* CONFIG_IWLWIFI_DEBUGFS */
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -379,6 +379,25 @@
|
|||
|
||||
#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010)
|
||||
|
||||
/**
|
||||
* Bit fields for TSSR(Tx Shared Status & Control) error status register:
|
||||
* 31: Indicates an address error when accessed to internal memory
|
||||
* uCode/driver must write "1" in order to clear this flag
|
||||
* 30: Indicates that Host did not send the expected number of dwords to FH
|
||||
* uCode/driver must write "1" in order to clear this flag
|
||||
* 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA
|
||||
* command was received from the scheduler while the TRB was already full
|
||||
* with previous command
|
||||
* uCode/driver must write "1" in order to clear this flag
|
||||
* 7-0: Each status bit indicates a channel's TxCredit error. When an error
|
||||
* bit is set, it indicates that the FH has received a full indication
|
||||
* from the RTC TxFIFO and the current value of the TxCredit counter was
|
||||
* not equal to zero. This mean that the credit mechanism was not
|
||||
* synchronized to the TxFIFO status
|
||||
* uCode/driver must write "1" in order to clear this flag
|
||||
*/
|
||||
#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
|
||||
|
||||
#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
|
||||
#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -303,13 +303,12 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
|
|||
sizeof(struct iwl_powertable_cmd), cmd);
|
||||
}
|
||||
|
||||
|
||||
/* priv->mutex must be held */
|
||||
int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
||||
{
|
||||
int ret = 0;
|
||||
struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
|
||||
bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) &&
|
||||
(priv->hw->conf.flags & IEEE80211_CONF_PS);
|
||||
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
|
||||
bool update_chains;
|
||||
struct iwl_powertable_cmd cmd;
|
||||
int dtimper;
|
||||
|
@ -319,7 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
|||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
|
||||
|
||||
if (priv->vif)
|
||||
dtimper = priv->vif->bss_conf.dtim_period;
|
||||
dtimper = priv->hw->conf.ps_dtim_period;
|
||||
else
|
||||
dtimper = 1;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -473,8 +473,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
|||
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
|
||||
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
|
||||
|
||||
/* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */
|
||||
iwl_write8(priv, CSR_INT_COALESCING, 0x40);
|
||||
/* Set interrupt coalescing timer to default (2048 usecs) */
|
||||
iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
|||
struct iwl_missed_beacon_notif *missed_beacon;
|
||||
|
||||
missed_beacon = &pkt->u.missed_beacon;
|
||||
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
|
||||
if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
|
||||
priv->missed_beacon_threshold) {
|
||||
IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
|
||||
le32_to_cpu(missed_beacon->consequtive_missed_beacons),
|
||||
le32_to_cpu(missed_beacon->consecutive_missed_beacons),
|
||||
le32_to_cpu(missed_beacon->total_missed_becons),
|
||||
le32_to_cpu(missed_beacon->num_recvd_beacons),
|
||||
le32_to_cpu(missed_beacon->num_expected_beacons));
|
||||
|
@ -511,6 +512,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
|
||||
|
||||
void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||
|
||||
if (!report->state) {
|
||||
IWL_DEBUG_11H(priv,
|
||||
"Spectrum Measure Notification: Start\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&priv->measure_report, report, sizeof(*report));
|
||||
priv->measurement_status |= MEASUREMENT_READY;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
|
||||
|
||||
|
||||
|
||||
/* Calculate noise level, based on measurements during network silence just
|
||||
* before arriving beacon. This measurement can be done only if we know
|
||||
|
@ -564,15 +583,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
|
|||
int i;
|
||||
__le32 *prev_stats;
|
||||
u32 *accum_stats;
|
||||
u32 *delta, *max_delta;
|
||||
|
||||
prev_stats = (__le32 *)&priv->statistics;
|
||||
accum_stats = (u32 *)&priv->accum_statistics;
|
||||
delta = (u32 *)&priv->delta_statistics;
|
||||
max_delta = (u32 *)&priv->max_delta;
|
||||
|
||||
for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
|
||||
i += sizeof(__le32), stats++, prev_stats++, accum_stats++)
|
||||
if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats))
|
||||
*accum_stats += (le32_to_cpu(*stats) -
|
||||
i += sizeof(__le32), stats++, prev_stats++, delta++,
|
||||
max_delta++, accum_stats++) {
|
||||
if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
|
||||
*delta = (le32_to_cpu(*stats) -
|
||||
le32_to_cpu(*prev_stats));
|
||||
*accum_stats += *delta;
|
||||
if (*delta > *max_delta)
|
||||
*max_delta = *delta;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset accumulative statistics for "no-counter" type statistics */
|
||||
priv->accum_statistics.general.temperature =
|
||||
|
@ -592,11 +620,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
|
|||
|
||||
#define REG_RECALIB_PERIOD (60)
|
||||
|
||||
#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
|
||||
void iwl_rx_statistics(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
int change;
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
int combined_plcp_delta;
|
||||
unsigned int plcp_msec;
|
||||
unsigned long plcp_received_jiffies;
|
||||
|
||||
IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
|
||||
(int)sizeof(priv->statistics),
|
||||
|
@ -611,6 +643,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
|
|||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
|
||||
#endif
|
||||
/*
|
||||
* check for plcp_err and trigger radio reset if it exceeds
|
||||
* the plcp error threshold plcp_delta.
|
||||
*/
|
||||
plcp_received_jiffies = jiffies;
|
||||
plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
|
||||
(long) priv->plcp_jiffies);
|
||||
priv->plcp_jiffies = plcp_received_jiffies;
|
||||
/*
|
||||
* check to make sure plcp_msec is not 0 to prevent division
|
||||
* by zero.
|
||||
*/
|
||||
if (plcp_msec) {
|
||||
combined_plcp_delta =
|
||||
(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
|
||||
le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
|
||||
(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
|
||||
le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
|
||||
|
||||
if ((combined_plcp_delta > 0) &&
|
||||
((combined_plcp_delta * 100) / plcp_msec) >
|
||||
priv->cfg->plcp_delta_threshold) {
|
||||
/*
|
||||
* if plcp_err exceed the threshold, the following
|
||||
* data is printed in csv format:
|
||||
* Text: plcp_err exceeded %d,
|
||||
* Received ofdm.plcp_err,
|
||||
* Current ofdm.plcp_err,
|
||||
* Received ofdm_ht.plcp_err,
|
||||
* Current ofdm_ht.plcp_err,
|
||||
* combined_plcp_delta,
|
||||
* plcp_msec
|
||||
*/
|
||||
IWL_DEBUG_RADIO(priv, PLCP_MSG,
|
||||
priv->cfg->plcp_delta_threshold,
|
||||
le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
|
||||
le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
|
||||
le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
|
||||
le32_to_cpu(
|
||||
priv->statistics.rx.ofdm_ht.plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
|
||||
/*
|
||||
* Reset the RF radio due to the high plcp
|
||||
* error rate
|
||||
*/
|
||||
iwl_force_rf_reset(priv);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
|
||||
|
||||
set_bit(STATUS_STATISTICS, &priv->status);
|
||||
|
@ -638,11 +720,13 @@ void iwl_reply_statistics(struct iwl_priv *priv,
|
|||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
|
||||
if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
|
||||
memset(&priv->statistics, 0,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
memset(&priv->accum_statistics, 0,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
memset(&priv->delta_statistics, 0,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
memset(&priv->max_delta, 0,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
#endif
|
||||
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -192,18 +192,16 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
|
|||
IWL_DEBUG_SCAN(priv, "Scan ch.res: "
|
||||
"%d [802.11%s] "
|
||||
"(TSF: 0x%08X:%08X) - %d "
|
||||
"elapsed=%lu usec (%dms since last)\n",
|
||||
"elapsed=%lu usec\n",
|
||||
notif->channel,
|
||||
notif->band ? "bg" : "a",
|
||||
le32_to_cpu(notif->tsf_high),
|
||||
le32_to_cpu(notif->tsf_low),
|
||||
le32_to_cpu(notif->statistics[0]),
|
||||
le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
|
||||
jiffies_to_msecs(elapsed_jiffies
|
||||
(priv->last_scan_jiffies, jiffies)));
|
||||
le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
|
||||
#endif
|
||||
|
||||
priv->last_scan_jiffies = jiffies;
|
||||
if (!priv->is_internal_short_scan)
|
||||
priv->next_scan_jiffies = 0;
|
||||
}
|
||||
|
||||
|
@ -250,8 +248,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
|
|||
goto reschedule;
|
||||
}
|
||||
|
||||
priv->last_scan_jiffies = jiffies;
|
||||
if (!priv->is_internal_short_scan)
|
||||
priv->next_scan_jiffies = 0;
|
||||
else
|
||||
priv->last_internal_scan_jiffies = jiffies;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Setting scan to off\n");
|
||||
|
||||
clear_bit(STATUS_SCANNING, &priv->status);
|
||||
|
@ -314,6 +315,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_get_passive_dwell_time);
|
||||
|
||||
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int i, added = 0;
|
||||
u16 channel = 0;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband) {
|
||||
IWL_ERR(priv, "invalid band\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
/* only scan single channel, good enough to reset the RF */
|
||||
/* pick the first valid not in-use channel */
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 14; i < priv->channel_count; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel = priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 14; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel =
|
||||
priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel) {
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
added++;
|
||||
} else
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
u8 is_active, u8 n_probes,
|
||||
|
@ -421,6 +488,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
|
|||
|
||||
IWL_DEBUG_INFO(priv, "Starting scan...\n");
|
||||
set_bit(STATUS_SCANNING, &priv->status);
|
||||
priv->is_internal_short_scan = false;
|
||||
priv->scan_start = jiffies;
|
||||
priv->scan_pass_start = priv->scan_start;
|
||||
|
||||
|
@ -461,15 +529,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* if we just finished scan ask for delay */
|
||||
if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
|
||||
time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
|
||||
IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
ret = 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
priv->scan_bands = 0;
|
||||
for (i = 0; i < req->n_channels; i++)
|
||||
priv->scan_bands |= BIT(req->channels[i]->band);
|
||||
|
@ -488,6 +547,54 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_mac_hw_scan);
|
||||
|
||||
/*
|
||||
* internal short scan, this function should only been called while associated.
|
||||
* It will reset and tune the radio to prevent possible RF related problem
|
||||
*/
|
||||
#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1)
|
||||
|
||||
int iwl_internal_short_hw_scan(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
ret = -EIO;
|
||||
IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
|
||||
goto out;
|
||||
}
|
||||
if (test_bit(STATUS_SCANNING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
if (priv->last_internal_scan_jiffies &&
|
||||
time_after(priv->last_internal_scan_jiffies +
|
||||
IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) {
|
||||
IWL_DEBUG_SCAN(priv, "internal scan rejected\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
priv->scan_bands = 0;
|
||||
if (priv->band == IEEE80211_BAND_5GHZ)
|
||||
priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
|
||||
else
|
||||
priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
|
||||
set_bit(STATUS_SCANNING, &priv->status);
|
||||
priv->is_internal_short_scan = true;
|
||||
queue_work(priv->workqueue, &priv->request_scan);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_internal_short_hw_scan);
|
||||
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
|
||||
|
||||
void iwl_bg_scan_check(struct work_struct *data)
|
||||
|
@ -551,6 +658,7 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
|
|||
if (WARN_ON(left < ie_len))
|
||||
return len;
|
||||
|
||||
if (ies)
|
||||
memcpy(pos, ies, ie_len);
|
||||
len += ie_len;
|
||||
left -= ie_len;
|
||||
|
@ -654,7 +762,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
|
|||
unsigned long flags;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
interval = priv->beacon_int;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -672,7 +779,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
|
|||
scan_suspend_time, interval);
|
||||
}
|
||||
|
||||
if (priv->scan_request->n_ssids) {
|
||||
if (priv->is_internal_short_scan) {
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
} else if (priv->scan_request->n_ssids) {
|
||||
int i, p = 0;
|
||||
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
|
||||
for (i = 0; i < priv->scan_request->n_ssids; i++) {
|
||||
|
@ -753,24 +862,38 @@ static void iwl_bg_request_scan(struct work_struct *data)
|
|||
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
|
||||
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
|
||||
scan->rx_chain = cpu_to_le16(rx_chain);
|
||||
if (!priv->is_internal_short_scan) {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
priv->scan_request->ie,
|
||||
priv->scan_request->ie_len,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
} else {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
NULL, 0,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
|
||||
}
|
||||
scan->tx_cmd.len = cpu_to_le16(cmd_len);
|
||||
|
||||
if (iwl_is_monitor_mode(priv))
|
||||
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
|
||||
|
||||
scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
|
||||
RXON_FILTER_BCON_AWARE_MSK);
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
scan->channel_count =
|
||||
iwl_get_channels_for_scan(priv, band, is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
|
||||
|
||||
iwl_get_single_channel_for_scan(priv, band,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
} else {
|
||||
scan->channel_count =
|
||||
iwl_get_channels_for_scan(priv, band,
|
||||
is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
}
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
goto done;
|
||||
|
@ -831,7 +954,12 @@ void iwl_bg_scan_completed(struct work_struct *work)
|
|||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
if (!priv->is_internal_short_scan)
|
||||
ieee80211_scan_completed(priv->hw, false);
|
||||
else {
|
||||
priv->is_internal_short_scan = false;
|
||||
IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/wireless.h>
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-spectrum.h"
|
||||
|
||||
#define BEACON_TIME_MASK_LOW 0x00FFFFFF
|
||||
#define BEACON_TIME_MASK_HIGH 0xFF000000
|
||||
#define TIME_UNIT 1024
|
||||
|
||||
/*
|
||||
* extended beacon time format
|
||||
* time in usec will be changed into a 32-bit value in 8:24 format
|
||||
* the high 1 byte is the beacon counts
|
||||
* the lower 3 bytes is the time in usec within one beacon interval
|
||||
*/
|
||||
|
||||
/* TOOD: was used in sysfs debug interface need to add to mac */
|
||||
#if 0
|
||||
static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
|
||||
{
|
||||
u32 quot;
|
||||
u32 rem;
|
||||
u32 interval = beacon_interval * 1024;
|
||||
|
||||
if (!interval || !usec)
|
||||
return 0;
|
||||
|
||||
quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
|
||||
rem = (usec % interval) & BEACON_TIME_MASK_LOW;
|
||||
|
||||
return (quot << 24) + rem;
|
||||
}
|
||||
|
||||
/* base is usually what we get from ucode with each received frame,
|
||||
* the same as HW timer counter counting down
|
||||
*/
|
||||
|
||||
static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
|
||||
{
|
||||
u32 base_low = base & BEACON_TIME_MASK_LOW;
|
||||
u32 addon_low = addon & BEACON_TIME_MASK_LOW;
|
||||
u32 interval = beacon_interval * TIME_UNIT;
|
||||
u32 res = (base & BEACON_TIME_MASK_HIGH) +
|
||||
(addon & BEACON_TIME_MASK_HIGH);
|
||||
|
||||
if (base_low > addon_low)
|
||||
res += base_low - addon_low;
|
||||
else if (base_low < addon_low) {
|
||||
res += interval + base_low - addon_low;
|
||||
res += (1 << 24);
|
||||
} else
|
||||
res += (1 << 24);
|
||||
|
||||
return cpu_to_le32(res);
|
||||
}
|
||||
static int iwl_get_measurement(struct iwl_priv *priv,
|
||||
struct ieee80211_measurement_params *params,
|
||||
u8 type)
|
||||
{
|
||||
struct iwl4965_spectrum_cmd spectrum;
|
||||
struct iwl_rx_packet *res;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
|
||||
.data = (void *)&spectrum,
|
||||
.meta.flags = CMD_WANT_SKB,
|
||||
};
|
||||
u32 add_time = le64_to_cpu(params->start_time);
|
||||
int rc;
|
||||
int spectrum_resp_status;
|
||||
int duration = le16_to_cpu(params->duration);
|
||||
|
||||
if (iwl_is_associated(priv))
|
||||
add_time =
|
||||
iwl_usecs_to_beacons(
|
||||
le64_to_cpu(params->start_time) - priv->last_tsf,
|
||||
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
||||
|
||||
memset(&spectrum, 0, sizeof(spectrum));
|
||||
|
||||
spectrum.channel_count = cpu_to_le16(1);
|
||||
spectrum.flags =
|
||||
RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
|
||||
spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
|
||||
cmd.len = sizeof(spectrum);
|
||||
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
|
||||
|
||||
if (iwl_is_associated(priv))
|
||||
spectrum.start_time =
|
||||
iwl_add_beacon_time(priv->last_beacon_time,
|
||||
add_time,
|
||||
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
||||
else
|
||||
spectrum.start_time = 0;
|
||||
|
||||
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
|
||||
spectrum.channels[0].channel = params->channel;
|
||||
spectrum.channels[0].type = type;
|
||||
if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
|
||||
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
|
||||
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
|
||||
|
||||
rc = iwl_send_cmd_sync(priv, &cmd);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
|
||||
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||
IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
|
||||
switch (spectrum_resp_status) {
|
||||
case 0: /* Command will be handled */
|
||||
if (res->u.spectrum.id != 0xff) {
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Replaced existing measurement: %d\n",
|
||||
res->u.spectrum.id);
|
||||
priv->measurement_status &= ~MEASUREMENT_READY;
|
||||
}
|
||||
priv->measurement_status |= MEASUREMENT_ACTIVE;
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
case 1: /* Command will not be handled */
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_kfree_skb_any(cmd.meta.u.skb);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||
|
||||
if (!report->state) {
|
||||
IWL_DEBUG_11H(priv,
|
||||
"Spectrum Measure Notification: Start\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&priv->measure_report, report, sizeof(*report));
|
||||
priv->measurement_status |= MEASUREMENT_READY;
|
||||
}
|
||||
|
||||
void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
|
||||
{
|
||||
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
|
||||
iwl_rx_spectrum_measure_notif;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ieee80211 subsystem header files.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -80,19 +80,90 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_get_ra_sta_id);
|
||||
|
||||
/* priv->sta_lock must be held */
|
||||
static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
|
||||
{
|
||||
|
||||
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
|
||||
IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
|
||||
sta_id, priv->stations[sta_id].sta.sta.addr);
|
||||
|
||||
if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
|
||||
IWL_DEBUG_ASSOC(priv,
|
||||
"STA id %u addr %pM already present in uCode (according to driver)\n",
|
||||
sta_id, priv->stations[sta_id].sta.sta.addr);
|
||||
} else {
|
||||
priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
|
||||
IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
|
||||
sta_id, priv->stations[sta_id].sta.sta.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_process_add_sta_resp(struct iwl_priv *priv,
|
||||
struct iwl_addsta_cmd *addsta,
|
||||
struct iwl_rx_packet *pkt,
|
||||
bool sync)
|
||||
{
|
||||
u8 sta_id = addsta->sta.sta_id;
|
||||
unsigned long flags;
|
||||
|
||||
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||
IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
|
||||
pkt->hdr.flags);
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
|
||||
sta_id);
|
||||
|
||||
spin_lock_irqsave(&priv->sta_lock, flags);
|
||||
|
||||
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
|
||||
IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
|
||||
switch (pkt->u.add_sta.status) {
|
||||
case ADD_STA_SUCCESS_MSK:
|
||||
IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
|
||||
iwl_sta_ucode_activate(priv, sta_id);
|
||||
break;
|
||||
case ADD_STA_NO_ROOM_IN_TABLE:
|
||||
IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
|
||||
sta_id);
|
||||
break;
|
||||
case ADD_STA_NO_BLOCK_ACK_RESOURCE:
|
||||
IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
|
||||
sta_id);
|
||||
break;
|
||||
case ADD_STA_MODIFY_NON_EXIST_STA:
|
||||
IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
|
||||
sta_id);
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
|
||||
pkt->u.add_sta.status);
|
||||
break;
|
||||
}
|
||||
|
||||
priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
|
||||
IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
|
||||
priv->stations[sta_id].sta.sta.addr);
|
||||
IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
|
||||
priv->stations[sta_id].sta.mode ==
|
||||
STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
|
||||
sta_id, priv->stations[sta_id].sta.sta.addr);
|
||||
|
||||
/*
|
||||
* XXX: The MAC address in the command buffer is often changed from
|
||||
* the original sent to the device. That is, the MAC address
|
||||
* written to the command buffer often is not the same MAC adress
|
||||
* read from the command buffer when the command returns. This
|
||||
* issue has not yet been resolved and this debugging is left to
|
||||
* observe the problem.
|
||||
*/
|
||||
IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
|
||||
priv->stations[sta_id].sta.mode ==
|
||||
STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
|
||||
addsta->sta.addr);
|
||||
|
||||
/*
|
||||
* Determine if we wanted to modify or add a station,
|
||||
* if adding a station succeeded we have some more initialization
|
||||
* to do when using station notification. TODO
|
||||
*/
|
||||
|
||||
spin_unlock_irqrestore(&priv->sta_lock, flags);
|
||||
}
|
||||
|
@ -103,23 +174,9 @@ static void iwl_add_sta_callback(struct iwl_priv *priv,
|
|||
{
|
||||
struct iwl_addsta_cmd *addsta =
|
||||
(struct iwl_addsta_cmd *)cmd->cmd.payload;
|
||||
u8 sta_id = addsta->sta.sta_id;
|
||||
|
||||
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||
IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
|
||||
pkt->hdr.flags);
|
||||
return;
|
||||
}
|
||||
iwl_process_add_sta_resp(priv, addsta, pkt, false);
|
||||
|
||||
switch (pkt->u.add_sta.status) {
|
||||
case ADD_STA_SUCCESS_MSK:
|
||||
iwl_sta_ucode_activate(priv, sta_id);
|
||||
/* fall through */
|
||||
default:
|
||||
IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
|
||||
pkt->u.add_sta.status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_send_add_sta(struct iwl_priv *priv,
|
||||
|
@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
|
|||
if (ret || (flags & CMD_ASYNC))
|
||||
return ret;
|
||||
|
||||
pkt = (struct iwl_rx_packet *)cmd.reply_page;
|
||||
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||
IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
|
||||
pkt->hdr.flags);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
switch (pkt->u.add_sta.status) {
|
||||
case ADD_STA_SUCCESS_MSK:
|
||||
iwl_sta_ucode_activate(priv, sta->sta.sta_id);
|
||||
IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
|
||||
break;
|
||||
default:
|
||||
ret = -EIO;
|
||||
IWL_WARN(priv, "REPLY_ADD_STA failed\n");
|
||||
break;
|
||||
}
|
||||
pkt = (struct iwl_rx_packet *)cmd.reply_page;
|
||||
iwl_process_add_sta_resp(priv, sta, pkt, true);
|
||||
}
|
||||
iwl_free_pages(priv, cmd.reply_page);
|
||||
|
||||
|
@ -1003,15 +1045,10 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
|
|||
struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
|
||||
u8 sta_id;
|
||||
|
||||
/* Add station to device's station table */
|
||||
|
||||
/*
|
||||
* XXX: This check is definitely not correct, if we're an AP
|
||||
* it'll always be false which is not what we want, but
|
||||
* it doesn't look like iwlagn is prepared to be an HT
|
||||
* AP anyway.
|
||||
* Set HT capabilities. It is ok to set this struct even if not using
|
||||
* HT config: the priv->current_ht_config.is_ht flag will just be false
|
||||
*/
|
||||
if (priv->current_ht_config.is_ht) {
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(priv->vif, addr);
|
||||
if (sta) {
|
||||
|
@ -1019,8 +1056,8 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
|
|||
cur_ht_config = &ht_config;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* Add station to device's station table */
|
||||
sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
|
||||
|
||||
/* Set up default rate scaling table in device's station table */
|
||||
|
@ -1085,6 +1122,7 @@ static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
|
|||
*/
|
||||
void iwl_add_bcast_station(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
|
||||
iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
|
||||
|
||||
/* Set up default rate scaling table in device's station table */
|
||||
|
@ -1092,6 +1130,16 @@ void iwl_add_bcast_station(struct iwl_priv *priv)
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_add_bcast_station);
|
||||
|
||||
/**
|
||||
* iwl3945_add_bcast_station - add broadcast station into station table.
|
||||
*/
|
||||
void iwl3945_add_bcast_station(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
|
||||
iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(iwl3945_add_bcast_station);
|
||||
|
||||
/**
|
||||
* iwl_get_sta_id - Find station's index within station table
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
|
|||
|
||||
int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
|
||||
void iwl_add_bcast_station(struct iwl_priv *priv);
|
||||
void iwl3945_add_bcast_station(struct iwl_priv *priv);
|
||||
int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
|
||||
void iwl_clear_stations_table(struct iwl_priv *priv);
|
||||
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -56,6 +56,7 @@
|
|||
#include "iwl-helpers.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-spectrum.h"
|
||||
|
||||
/*
|
||||
* module name, copyright, version, etc.
|
||||
|
@ -70,14 +71,13 @@
|
|||
#define VD
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
|
||||
#define VS "s"
|
||||
#else
|
||||
#define VS
|
||||
#endif
|
||||
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD VS
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
|
||||
/*
|
||||
* add "s" to indicate spectrum measurement included.
|
||||
* we add it here to be consistent with previous releases in which
|
||||
* this was configurable.
|
||||
*/
|
||||
#define DRV_VERSION IWLWIFI_VERSION VD "s"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
|
@ -689,10 +689,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
|
||||
|
||||
#include "iwl-spectrum.h"
|
||||
|
||||
#define BEACON_TIME_MASK_LOW 0x00FFFFFF
|
||||
#define BEACON_TIME_MASK_HIGH 0xFF000000
|
||||
#define TIME_UNIT 1024
|
||||
|
@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
|
|||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
|
@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
|
|||
priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
|
||||
priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
|
||||
priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
|
||||
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
|
||||
iwl_rx_spectrum_measure_notif;
|
||||
priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
|
||||
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
|
||||
iwl_rx_pm_debug_statistics_notif;
|
||||
|
@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
|
|||
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
|
||||
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
|
||||
|
||||
iwl_setup_spectrum_handlers(priv);
|
||||
iwl_setup_rx_scan_handlers(priv);
|
||||
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
|
||||
|
||||
|
@ -1644,7 +1640,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
|||
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
|
||||
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
|
||||
IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
|
||||
return pos;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* event log header */
|
||||
|
@ -1693,7 +1689,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
|||
bufsz = size * 48;
|
||||
*buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!*buf)
|
||||
return pos;
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
|
||||
/* if uCode has wrapped back to top of log,
|
||||
|
@ -3037,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
|||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl3945_bg_up(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
__iwl3945_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl3945_bg_restart(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
|
||||
|
@ -3065,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
|
|||
ieee80211_restart_hw(priv->hw);
|
||||
} else {
|
||||
iwl3945_down(priv);
|
||||
queue_work(priv->workqueue, &priv->up);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
__iwl3945_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3569,8 +3559,6 @@ static ssize_t store_filter_flags(struct device *d,
|
|||
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
|
||||
store_filter_flags);
|
||||
|
||||
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
|
||||
|
||||
static ssize_t show_measurement(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -3640,7 +3628,6 @@ static ssize_t store_measurement(struct device *d,
|
|||
|
||||
static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
|
||||
show_measurement, store_measurement);
|
||||
#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
|
||||
|
||||
static ssize_t store_retry_rate(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
|
@ -3789,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
|
|||
|
||||
init_waitqueue_head(&priv->wait_command_queue);
|
||||
|
||||
INIT_WORK(&priv->up, iwl3945_bg_up);
|
||||
INIT_WORK(&priv->restart, iwl3945_bg_restart);
|
||||
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
|
||||
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
|
||||
|
@ -3823,9 +3809,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
|
|||
&dev_attr_dump_errors.attr,
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_filter_flags.attr,
|
||||
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
|
||||
&dev_attr_measurement.attr,
|
||||
#endif
|
||||
&dev_attr_retry_rate.attr,
|
||||
&dev_attr_statistics.attr,
|
||||
&dev_attr_status.attr,
|
||||
|
@ -3881,6 +3865,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
|
|||
priv->band = IEEE80211_BAND_2GHZ;
|
||||
|
||||
priv->iw_mode = NL80211_IFTYPE_STATION;
|
||||
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
|
||||
|
||||
iwl_reset_qos(priv);
|
||||
|
||||
|
|
|
@ -1160,11 +1160,11 @@ int lbs_adhoc_stop(struct lbs_private *priv)
|
|||
static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
|
||||
struct bss_descriptor *match_bss)
|
||||
{
|
||||
if (!secinfo->wep_enabled && !secinfo->WPAenabled
|
||||
&& !secinfo->WPA2enabled
|
||||
&& match_bss->wpa_ie[0] != WLAN_EID_GENERIC
|
||||
&& match_bss->rsn_ie[0] != WLAN_EID_RSN
|
||||
&& !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
if (!secinfo->wep_enabled &&
|
||||
!secinfo->WPAenabled && !secinfo->WPA2enabled &&
|
||||
match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
|
||||
match_bss->rsn_ie[0] != WLAN_EID_RSN &&
|
||||
!(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -1173,9 +1173,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
|
|||
static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
|
||||
struct bss_descriptor *match_bss)
|
||||
{
|
||||
if (secinfo->wep_enabled && !secinfo->WPAenabled
|
||||
&& !secinfo->WPA2enabled
|
||||
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
if (secinfo->wep_enabled &&
|
||||
!secinfo->WPAenabled && !secinfo->WPA2enabled &&
|
||||
(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -1184,8 +1184,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
|
|||
static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
|
||||
struct bss_descriptor *match_bss)
|
||||
{
|
||||
if (!secinfo->wep_enabled && secinfo->WPAenabled
|
||||
&& (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
|
||||
if (!secinfo->wep_enabled && secinfo->WPAenabled &&
|
||||
(match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
|
||||
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
|
||||
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
|
||||
)
|
||||
|
@ -1210,11 +1210,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
|
|||
static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
|
||||
struct bss_descriptor *match_bss)
|
||||
{
|
||||
if (!secinfo->wep_enabled && !secinfo->WPAenabled
|
||||
&& !secinfo->WPA2enabled
|
||||
&& (match_bss->wpa_ie[0] != WLAN_EID_GENERIC)
|
||||
&& (match_bss->rsn_ie[0] != WLAN_EID_RSN)
|
||||
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
if (!secinfo->wep_enabled &&
|
||||
!secinfo->WPAenabled && !secinfo->WPA2enabled &&
|
||||
(match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
|
||||
(match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
|
||||
(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -1525,8 +1525,8 @@ static int assoc_helper_associate(struct lbs_private *priv,
|
|||
/* If we're given and 'any' BSSID, try associating based on SSID */
|
||||
|
||||
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
|
||||
if (compare_ether_addr(bssid_any, assoc_req->bssid)
|
||||
&& compare_ether_addr(bssid_off, assoc_req->bssid)) {
|
||||
if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
|
||||
compare_ether_addr(bssid_off, assoc_req->bssid)) {
|
||||
ret = assoc_helper_bssid(priv, assoc_req);
|
||||
done = 1;
|
||||
}
|
||||
|
@ -1612,11 +1612,9 @@ static int assoc_helper_channel(struct lbs_private *priv,
|
|||
goto restore_mesh;
|
||||
}
|
||||
|
||||
if ( assoc_req->secinfo.wep_enabled
|
||||
&& (assoc_req->wep_keys[0].len
|
||||
|| assoc_req->wep_keys[1].len
|
||||
|| assoc_req->wep_keys[2].len
|
||||
|| assoc_req->wep_keys[3].len)) {
|
||||
if (assoc_req->secinfo.wep_enabled &&
|
||||
(assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
|
||||
assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
|
||||
/* Make sure WEP keys are re-sent to firmware */
|
||||
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
|
||||
}
|
||||
|
@ -1983,14 +1981,14 @@ void lbs_association_worker(struct work_struct *work)
|
|||
assoc_req->secinfo.auth_mode);
|
||||
|
||||
/* If 'any' SSID was specified, find an SSID to associate with */
|
||||
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
|
||||
&& !assoc_req->ssid_len)
|
||||
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
|
||||
!assoc_req->ssid_len)
|
||||
find_any_ssid = 1;
|
||||
|
||||
/* But don't use 'any' SSID if there's a valid locked BSSID to use */
|
||||
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
|
||||
if (compare_ether_addr(assoc_req->bssid, bssid_any)
|
||||
&& compare_ether_addr(assoc_req->bssid, bssid_off))
|
||||
if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
|
||||
compare_ether_addr(assoc_req->bssid, bssid_off))
|
||||
find_any_ssid = 0;
|
||||
}
|
||||
|
||||
|
@ -2052,13 +2050,6 @@ void lbs_association_worker(struct work_struct *work)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
|
||||
|| test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
|
||||
ret = assoc_helper_wep_keys(priv, assoc_req);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
|
||||
ret = assoc_helper_secinfo(priv, assoc_req);
|
||||
if (ret)
|
||||
|
@ -2071,18 +2062,31 @@ void lbs_association_worker(struct work_struct *work)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)
|
||||
|| test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
|
||||
/*
|
||||
* v10 FW wants WPA keys to be set/cleared before WEP key operations,
|
||||
* otherwise it will fail to correctly associate to WEP networks.
|
||||
* Other firmware versions don't appear to care.
|
||||
*/
|
||||
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) ||
|
||||
test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
|
||||
ret = assoc_helper_wpa_keys(priv, assoc_req);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) ||
|
||||
test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
|
||||
ret = assoc_helper_wep_keys(priv, assoc_req);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* SSID/BSSID should be the _last_ config option set, because they
|
||||
* trigger the association attempt.
|
||||
*/
|
||||
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)
|
||||
|| test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
|
||||
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
|
||||
test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
|
||||
int success = 1;
|
||||
|
||||
ret = assoc_helper_associate(priv, assoc_req);
|
||||
|
|
|
@ -281,6 +281,8 @@ struct mac80211_hwsim_data {
|
|||
struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
|
||||
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
|
||||
|
||||
struct mac_address addresses[2];
|
||||
|
||||
struct ieee80211_channel *channel;
|
||||
unsigned long beacon_int; /* in jiffies unit */
|
||||
unsigned int rx_filter;
|
||||
|
@ -1154,7 +1156,11 @@ static int __init init_mac80211_hwsim(void)
|
|||
SET_IEEE80211_DEV(hw, data->dev);
|
||||
addr[3] = i >> 8;
|
||||
addr[4] = i;
|
||||
SET_IEEE80211_PERM_ADDR(hw, addr);
|
||||
memcpy(data->addresses[0].addr, addr, ETH_ALEN);
|
||||
memcpy(data->addresses[1].addr, addr, ETH_ALEN);
|
||||
data->addresses[1].addr[0] |= 0x40;
|
||||
hw->wiphy->n_addresses = 2;
|
||||
hw->wiphy->addresses = data->addresses;
|
||||
|
||||
hw->channel_change_time = 1;
|
||||
hw->queues = 4;
|
||||
|
|
|
@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
|
|||
struct mwl8k_priv *priv =
|
||||
container_of(work, struct mwl8k_priv, finalize_join_worker);
|
||||
struct sk_buff *skb = priv->beacon_skb;
|
||||
struct mwl8k_vif *mwl8k_vif;
|
||||
struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
|
||||
const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
|
||||
mgmt->u.beacon.variable, len);
|
||||
int dtim_period = 1;
|
||||
|
||||
mwl8k_vif = mwl8k_first_vif(priv);
|
||||
if (mwl8k_vif != NULL)
|
||||
mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
|
||||
mwl8k_vif->vif->bss_conf.dtim_period);
|
||||
if (tim && tim[1] >= 2)
|
||||
dtim_period = tim[3];
|
||||
|
||||
mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
priv->beacon_skb = NULL;
|
||||
|
|
|
@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
|
|||
skb_tail_pointer(skb),
|
||||
priv->common.rx_mtu + 32,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
if (pci_dma_mapping_error(priv->pdev, mapping)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_err(&priv->pdev->dev,
|
||||
"RX DMA Mapping error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
desc->host_addr = cpu_to_le32(mapping);
|
||||
desc->device_addr = 0; // FIXME: necessary?
|
||||
desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
|
||||
|
@ -226,14 +234,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
|
|||
p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
|
||||
}
|
||||
|
||||
/* caller must hold priv->lock */
|
||||
static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
|
||||
int ring_index, struct p54p_desc *ring, u32 ring_limit,
|
||||
void **tx_buf)
|
||||
struct sk_buff **tx_buf)
|
||||
{
|
||||
struct p54p_priv *priv = dev->priv;
|
||||
struct p54p_ring_control *ring_control = priv->ring_control;
|
||||
struct p54p_desc *desc;
|
||||
struct sk_buff *skb;
|
||||
u32 idx, i;
|
||||
|
||||
i = (*index) % ring_limit;
|
||||
|
@ -242,9 +250,8 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
|
|||
|
||||
while (i != idx) {
|
||||
desc = &ring[i];
|
||||
if (tx_buf[i])
|
||||
if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i]))
|
||||
p54_free_skb(dev, tx_buf[i]);
|
||||
|
||||
skb = tx_buf[i];
|
||||
tx_buf[i] = NULL;
|
||||
|
||||
pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
|
||||
|
@ -255,17 +262,28 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
|
|||
desc->len = 0;
|
||||
desc->flags = 0;
|
||||
|
||||
if (skb && FREE_AFTER_TX(skb))
|
||||
p54_free_skb(dev, skb);
|
||||
|
||||
i++;
|
||||
i %= ring_limit;
|
||||
}
|
||||
}
|
||||
|
||||
static void p54p_rx_tasklet(unsigned long dev_id)
|
||||
static void p54p_tasklet(unsigned long dev_id)
|
||||
{
|
||||
struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
|
||||
struct p54p_priv *priv = dev->priv;
|
||||
struct p54p_ring_control *ring_control = priv->ring_control;
|
||||
|
||||
p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
|
||||
ARRAY_SIZE(ring_control->tx_mgmt),
|
||||
priv->tx_buf_mgmt);
|
||||
|
||||
p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
|
||||
ARRAY_SIZE(ring_control->tx_data),
|
||||
priv->tx_buf_data);
|
||||
|
||||
p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
|
||||
ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
|
||||
|
||||
|
@ -280,59 +298,49 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
struct ieee80211_hw *dev = dev_id;
|
||||
struct p54p_priv *priv = dev->priv;
|
||||
struct p54p_ring_control *ring_control = priv->ring_control;
|
||||
__le32 reg;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
reg = P54P_READ(int_ident);
|
||||
if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
|
||||
spin_unlock(&priv->lock);
|
||||
return IRQ_HANDLED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
P54P_WRITE(int_ack, reg);
|
||||
|
||||
reg &= P54P_READ(int_enable);
|
||||
|
||||
if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) {
|
||||
p54p_check_tx_ring(dev, &priv->tx_idx_mgmt,
|
||||
3, ring_control->tx_mgmt,
|
||||
ARRAY_SIZE(ring_control->tx_mgmt),
|
||||
priv->tx_buf_mgmt);
|
||||
|
||||
p54p_check_tx_ring(dev, &priv->tx_idx_data,
|
||||
1, ring_control->tx_data,
|
||||
ARRAY_SIZE(ring_control->tx_data),
|
||||
priv->tx_buf_data);
|
||||
|
||||
tasklet_schedule(&priv->rx_tasklet);
|
||||
|
||||
} else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
|
||||
if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
|
||||
tasklet_schedule(&priv->tasklet);
|
||||
else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
|
||||
complete(&priv->boot_comp);
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
out:
|
||||
return reg ? IRQ_HANDLED : IRQ_NONE;
|
||||
}
|
||||
|
||||
static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct p54p_priv *priv = dev->priv;
|
||||
struct p54p_ring_control *ring_control = priv->ring_control;
|
||||
unsigned long flags;
|
||||
struct p54p_desc *desc;
|
||||
dma_addr_t mapping;
|
||||
u32 device_idx, idx, i;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
device_idx = le32_to_cpu(ring_control->device_idx[1]);
|
||||
idx = le32_to_cpu(ring_control->host_idx[1]);
|
||||
i = idx % ARRAY_SIZE(ring_control->tx_data);
|
||||
|
||||
priv->tx_buf_data[i] = skb;
|
||||
mapping = pci_map_single(priv->pdev, skb->data, skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (pci_dma_mapping_error(priv->pdev, mapping)) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
p54_free_skb(dev, skb);
|
||||
dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
|
||||
return ;
|
||||
}
|
||||
priv->tx_buf_data[i] = skb;
|
||||
|
||||
desc = &ring_control->tx_data[i];
|
||||
desc->host_addr = cpu_to_le32(mapping);
|
||||
desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
|
||||
|
@ -354,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev)
|
|||
unsigned int i;
|
||||
struct p54p_desc *desc;
|
||||
|
||||
tasklet_kill(&priv->rx_tasklet);
|
||||
|
||||
P54P_WRITE(int_enable, cpu_to_le32(0));
|
||||
P54P_READ(int_enable);
|
||||
udelay(10);
|
||||
|
||||
free_irq(priv->pdev->irq, dev);
|
||||
|
||||
tasklet_kill(&priv->tasklet);
|
||||
|
||||
P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
|
||||
|
@ -545,7 +553,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
|
|||
priv->common.tx = p54p_tx;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
|
||||
tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
|
||||
|
||||
err = request_firmware(&priv->firmware, "isl3886pci",
|
||||
&priv->pdev->dev);
|
||||
|
|
|
@ -92,7 +92,7 @@ struct p54p_priv {
|
|||
struct p54_common common;
|
||||
struct pci_dev *pdev;
|
||||
struct p54p_csr __iomem *map;
|
||||
struct tasklet_struct rx_tasklet;
|
||||
struct tasklet_struct tasklet;
|
||||
const struct firmware *firmware;
|
||||
spinlock_t lock;
|
||||
struct p54p_ring_control *ring_control;
|
||||
|
@ -101,8 +101,8 @@ struct p54p_priv {
|
|||
u32 rx_idx_mgmt, tx_idx_mgmt;
|
||||
struct sk_buff *rx_buf_data[8];
|
||||
struct sk_buff *rx_buf_mgmt[4];
|
||||
void *tx_buf_data[32];
|
||||
void *tx_buf_mgmt[4];
|
||||
struct sk_buff *tx_buf_data[32];
|
||||
struct sk_buff *tx_buf_mgmt[4];
|
||||
struct completion boot_comp;
|
||||
};
|
||||
|
||||
|
|
|
@ -761,6 +761,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
|
|||
rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
|
||||
}
|
||||
|
||||
static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
|
||||
return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
|
||||
(u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops rtl8180_ops = {
|
||||
.tx = rtl8180_tx,
|
||||
.start = rtl8180_start,
|
||||
|
@ -771,6 +779,7 @@ static const struct ieee80211_ops rtl8180_ops = {
|
|||
.bss_info_changed = rtl8180_bss_info_changed,
|
||||
.prepare_multicast = rtl8180_prepare_multicast,
|
||||
.configure_filter = rtl8180_configure_filter,
|
||||
.get_tsf = rtl8180_get_tsf,
|
||||
};
|
||||
|
||||
static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
|
||||
|
|
|
@ -1265,6 +1265,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
|
||||
return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
|
||||
(u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops rtl8187_ops = {
|
||||
.tx = rtl8187_tx,
|
||||
.start = rtl8187_start,
|
||||
|
@ -1276,7 +1284,8 @@ static const struct ieee80211_ops rtl8187_ops = {
|
|||
.prepare_multicast = rtl8187_prepare_multicast,
|
||||
.configure_filter = rtl8187_configure_filter,
|
||||
.conf_tx = rtl8187_conf_tx,
|
||||
.rfkill_poll = rtl8187_rfkill_poll
|
||||
.rfkill_poll = rtl8187_rfkill_poll,
|
||||
.get_tsf = rtl8187_get_tsf,
|
||||
};
|
||||
|
||||
static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
|
||||
|
|
|
@ -341,9 +341,6 @@ struct wl1251 {
|
|||
/* Are we currently scanning */
|
||||
bool scanning;
|
||||
|
||||
/* Our association ID */
|
||||
u16 aid;
|
||||
|
||||
/* Default key (for WEP) */
|
||||
u32 default_key;
|
||||
|
||||
|
|
|
@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
|
|||
|
||||
wl->psm_requested = true;
|
||||
|
||||
wl->dtim_period = conf->ps_dtim_period;
|
||||
|
||||
ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
|
||||
wl->dtim_period);
|
||||
|
||||
/*
|
||||
* We enter PSM only if we're already associated.
|
||||
* If we're not, we'll enter it when joining an SSID,
|
||||
* through the bss_info_changed() hook.
|
||||
* mac80211 enables PSM only if we're already associated.
|
||||
*/
|
||||
ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
|
||||
if (ret < 0)
|
||||
|
@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
|
|||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changed)
|
||||
{
|
||||
enum wl1251_cmd_ps_mode mode;
|
||||
struct wl1251 *wl = hw->priv;
|
||||
struct sk_buff *beacon, *skb;
|
||||
int ret;
|
||||
|
@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
if (bss_conf->assoc) {
|
||||
wl->beacon_int = bss_conf->beacon_int;
|
||||
wl->dtim_period = bss_conf->dtim_period;
|
||||
|
||||
ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
|
||||
wl->dtim_period);
|
||||
wl->aid = bss_conf->aid;
|
||||
|
||||
skb = ieee80211_pspoll_get(wl->hw, wl->vif);
|
||||
if (!skb)
|
||||
|
@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
|
||||
ret = wl1251_acx_aid(wl, wl->aid);
|
||||
ret = wl1251_acx_aid(wl, bss_conf->aid);
|
||||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
|
||||
/* If we want to go in PSM but we're not there yet */
|
||||
if (wl->psm_requested && !wl->psm) {
|
||||
mode = STATION_POWER_SAVE_MODE;
|
||||
ret = wl1251_ps_set_mode(wl, mode);
|
||||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
}
|
||||
} else {
|
||||
/* use defaults when not associated */
|
||||
wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
|
||||
|
|
|
@ -138,6 +138,8 @@
|
|||
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK 0x03
|
||||
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT 5
|
||||
|
||||
#define IEEE80211_HT_CTL_LEN 4
|
||||
|
||||
struct ieee80211_hdr {
|
||||
__le16 frame_control;
|
||||
__le16 duration_id;
|
||||
|
|
|
@ -1195,6 +1195,10 @@ enum wiphy_flags {
|
|||
WIPHY_FLAG_4ADDR_STATION = BIT(6),
|
||||
};
|
||||
|
||||
struct mac_address {
|
||||
u8 addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wiphy - wireless hardware description
|
||||
* @idx: the wiphy index assigned to this item
|
||||
|
@ -1213,12 +1217,28 @@ enum wiphy_flags {
|
|||
* -1 = fragmentation disabled, only odd values >= 256 used
|
||||
* @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled
|
||||
* @net: the network namespace this wiphy currently lives in
|
||||
* @perm_addr: permanent MAC address of this device
|
||||
* @addr_mask: If the device supports multiple MAC addresses by masking,
|
||||
* set this to a mask with variable bits set to 1, e.g. if the last
|
||||
* four bits are variable then set it to 00:...:00:0f. The actual
|
||||
* variable bits shall be determined by the interfaces added, with
|
||||
* interfaces not matching the mask being rejected to be brought up.
|
||||
* @n_addresses: number of addresses in @addresses.
|
||||
* @addresses: If the device has more than one address, set this pointer
|
||||
* to a list of addresses (6 bytes each). The first one will be used
|
||||
* by default for perm_addr. In this case, the mask should be set to
|
||||
* all-zeroes. In this case it is assumed that the device can handle
|
||||
* the same number of arbitrary MAC addresses.
|
||||
*/
|
||||
struct wiphy {
|
||||
/* assign these fields before you register the wiphy */
|
||||
|
||||
/* permanent MAC address */
|
||||
/* permanent MAC address(es) */
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
u8 addr_mask[ETH_ALEN];
|
||||
|
||||
u16 n_addresses;
|
||||
struct mac_address *addresses;
|
||||
|
||||
/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
|
||||
u16 interface_modes;
|
||||
|
@ -1638,6 +1658,22 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
|
|||
*/
|
||||
unsigned int cfg80211_classify8021d(struct sk_buff *skb);
|
||||
|
||||
/**
|
||||
* cfg80211_find_ie - find information element in data
|
||||
*
|
||||
* @eid: element ID
|
||||
* @ies: data consisting of IEs
|
||||
* @len: length of data
|
||||
*
|
||||
* This function will return %NULL if the element ID could
|
||||
* not be found or if the element is invalid (claims to be
|
||||
* longer than the given data), or a pointer to the first byte
|
||||
* of the requested element, that is the byte containing the
|
||||
* element ID. There are no checks on the element length
|
||||
* other than having to fit into the given data.
|
||||
*/
|
||||
const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);
|
||||
|
||||
/*
|
||||
* Regulatory helper functions for wiphys
|
||||
*/
|
||||
|
|
|
@ -186,7 +186,8 @@ enum ieee80211_bss_change {
|
|||
* @use_short_slot: use short slot time (only relevant for ERP);
|
||||
* if the hardware cannot handle this it must set the
|
||||
* IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
|
||||
* @dtim_period: num of beacons before the next DTIM, for PSM
|
||||
* @dtim_period: num of beacons before the next DTIM, for beaconing,
|
||||
* not valid in station mode (cf. hw conf ps_dtim_period)
|
||||
* @timestamp: beacon timestamp
|
||||
* @beacon_int: beacon interval
|
||||
* @assoc_capability: capabilities taken from assoc resp
|
||||
|
@ -271,6 +272,11 @@ struct ieee80211_bss_conf {
|
|||
* transmit function after the current frame, this can be used
|
||||
* by drivers to kick the DMA queue only if unset or when the
|
||||
* queue gets full.
|
||||
* @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted
|
||||
* after TX status because the destination was asleep, it must not
|
||||
* be modified again (no seqno assignment, crypto, etc.)
|
||||
* @IEEE80211_TX_INTFL_HAS_RADIOTAP: This frame was injected and still
|
||||
* has a radiotap header at skb->data.
|
||||
*/
|
||||
enum mac80211_tx_control_flags {
|
||||
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
|
||||
|
@ -291,6 +297,8 @@ enum mac80211_tx_control_flags {
|
|||
IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
|
||||
IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17),
|
||||
IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
|
||||
IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
|
||||
IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -644,6 +652,9 @@ enum ieee80211_smps_mode {
|
|||
* value will be only achievable between DTIM frames, the hardware
|
||||
* needs to check for the multicast traffic bit in DTIM beacons.
|
||||
* This variable is valid only when the CONF_PS flag is set.
|
||||
* @ps_dtim_period: The DTIM period of the AP we're connected to, for use
|
||||
* in power saving. Power saving will not be enabled until a beacon
|
||||
* has been received and the DTIM period is known.
|
||||
* @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
|
||||
* powersave documentation below. This variable is valid only when
|
||||
* the CONF_PS flag is set.
|
||||
|
@ -670,6 +681,7 @@ struct ieee80211_conf {
|
|||
int max_sleep_period;
|
||||
|
||||
u16 listen_interval;
|
||||
u8 ps_dtim_period;
|
||||
|
||||
u8 long_frame_max_tx_count, short_frame_max_tx_count;
|
||||
|
||||
|
@ -1485,7 +1497,7 @@ enum ieee80211_ampdu_mlme_action {
|
|||
* @update_tkip_key: See the section "Hardware crypto acceleration"
|
||||
* This callback will be called in the context of Rx. Called for drivers
|
||||
* which set IEEE80211_KEY_FLAG_TKIP_REQ_RX_P1_KEY.
|
||||
* The callback can sleep.
|
||||
* The callback must be atomic.
|
||||
*
|
||||
* @hw_scan: Ask the hardware to service the scan request, no need to start
|
||||
* the scan state machine in stack. The scan must honour the channel
|
||||
|
@ -1610,7 +1622,9 @@ struct ieee80211_ops {
|
|||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
void (*update_tkip_key)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_key_conf *conf, const u8 *address,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key_conf *conf,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 iv32, u16 *phase1key);
|
||||
int (*hw_scan)(struct ieee80211_hw *hw,
|
||||
struct cfg80211_scan_request *req);
|
||||
|
|
|
@ -39,6 +39,7 @@ enum environment_cap {
|
|||
* 00 - World regulatory domain
|
||||
* 99 - built by driver but a specific alpha2 cannot be determined
|
||||
* 98 - result of an intersection between two regulatory domains
|
||||
* 97 - regulatory domain has not yet been configured
|
||||
* @intersect: indicates whether the wireless core should intersect
|
||||
* the requested regulatory domain with the presently set regulatory
|
||||
* domain.
|
||||
|
|
|
@ -120,36 +120,38 @@ STA_OPS(last_seq_ctrl);
|
|||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[30 + STA_TID_NUM * 70], *p = buf;
|
||||
char buf[64 + STA_TID_NUM * 40], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
|
||||
spin_lock_bh(&sta->lock);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "next dialog_token is %#02x\n",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
|
||||
sta->ampdu_mlme.dialog_token_allocator + 1);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p,
|
||||
"TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
|
||||
for (i = 0; i < STA_TID_NUM; i++) {
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "TID %02d:", i);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, " RX=%x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
sta->ampdu_mlme.tid_state_rx[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_state_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
sta->ampdu_mlme.tid_state_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->ssn : 0);
|
||||
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, " TX=%x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
sta->ampdu_mlme.tid_state_tx[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
sta->ampdu_mlme.tid_tx[i]->ssn : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/pending=%03d",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\n");
|
||||
}
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
|
@ -165,7 +167,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
|
|||
if (_cond) \
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \
|
||||
} while (0)
|
||||
char buf[1024], *p = buf;
|
||||
char buf[512], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap;
|
||||
|
|
|
@ -137,16 +137,20 @@ static inline int drv_set_key(struct ieee80211_local *local,
|
|||
}
|
||||
|
||||
static inline void drv_update_tkip_key(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_key_conf *conf,
|
||||
const u8 *address, u32 iv32,
|
||||
struct sta_info *sta, u32 iv32,
|
||||
u16 *phase1key)
|
||||
{
|
||||
might_sleep();
|
||||
struct ieee80211_sta *ista = NULL;
|
||||
|
||||
if (sta)
|
||||
ista = &sta->sta;
|
||||
|
||||
if (local->ops->update_tkip_key)
|
||||
local->ops->update_tkip_key(&local->hw, conf, address,
|
||||
iv32, phase1key);
|
||||
trace_drv_update_tkip_key(local, conf, address, iv32);
|
||||
local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
|
||||
ista, iv32, phase1key);
|
||||
trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
|
||||
}
|
||||
|
||||
static inline int drv_hw_scan(struct ieee80211_local *local,
|
||||
|
|
|
@ -331,26 +331,29 @@ TRACE_EVENT(drv_set_key,
|
|||
|
||||
TRACE_EVENT(drv_update_tkip_key,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_key_conf *conf,
|
||||
const u8 *address, u32 iv32),
|
||||
struct ieee80211_sta *sta, u32 iv32),
|
||||
|
||||
TP_ARGS(local, conf, address, iv32),
|
||||
TP_ARGS(local, sdata, conf, sta, iv32),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
__array(u8, addr, 6)
|
||||
VIF_ENTRY
|
||||
STA_ENTRY
|
||||
__field(u32, iv32)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
memcpy(__entry->addr, address, 6);
|
||||
VIF_ASSIGN;
|
||||
STA_ASSIGN;
|
||||
__entry->iv32 = iv32;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT " addr:%pM iv32:%#x",
|
||||
LOCAL_PR_ARG, __entry->addr, __entry->iv32
|
||||
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " iv32:%#x",
|
||||
LOCAL_PR_ARG,VIF_PR_ARG,STA_PR_ARG, __entry->iv32
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -293,12 +293,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* check if we need to merge IBSS */
|
||||
|
||||
/* merge only on beacons (???) */
|
||||
if (!beacon)
|
||||
goto put_bss;
|
||||
|
||||
/* we use a fixed BSSID */
|
||||
if (sdata->u.ibss.bssid)
|
||||
if (sdata->u.ibss.fixed_bssid)
|
||||
goto put_bss;
|
||||
|
||||
/* not an IBSS */
|
||||
|
@ -454,6 +450,9 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
return active;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called with state == IEEE80211_IBSS_MLME_JOINED
|
||||
*/
|
||||
|
||||
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
|
@ -519,6 +518,10 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
capability, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called with state == IEEE80211_IBSS_MLME_SEARCH
|
||||
*/
|
||||
|
||||
static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
@ -575,18 +578,14 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
|
||||
|
||||
/* Selected IBSS not found in current scan results - try to scan */
|
||||
if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
|
||||
!ieee80211_sta_active_ibss(sdata)) {
|
||||
mod_timer(&ifibss->timer,
|
||||
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
|
||||
} else if (time_after(jiffies, ifibss->last_scan_completed +
|
||||
if (time_after(jiffies, ifibss->last_scan_completed +
|
||||
IEEE80211_SCAN_INTERVAL)) {
|
||||
printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
|
||||
"join\n", sdata->name);
|
||||
|
||||
ieee80211_request_internal_scan(sdata, ifibss->ssid,
|
||||
ifibss->ssid_len);
|
||||
} else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
|
||||
} else {
|
||||
int interval = IEEE80211_SCAN_INTERVAL;
|
||||
|
||||
if (time_after(jiffies, ifibss->ibss_join_req +
|
||||
|
@ -604,7 +603,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
interval = IEEE80211_SCAN_INTERVAL_SLOW;
|
||||
}
|
||||
|
||||
ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
|
||||
mod_timer(&ifibss->timer,
|
||||
round_jiffies(jiffies + interval));
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue