Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts: drivers/net/wireless/ath/ath9k/init.c
This commit is contained in:
commit
3e11210d46
35 changed files with 197 additions and 205 deletions
|
@ -3323,7 +3323,6 @@ F: drivers/net/wimax/i2400m/
|
||||||
F: include/linux/wimax/i2400m.h
|
F: include/linux/wimax/i2400m.h
|
||||||
|
|
||||||
INTEL WIRELESS WIFI LINK (iwlwifi)
|
INTEL WIRELESS WIFI LINK (iwlwifi)
|
||||||
M: Reinette Chatre <reinette.chatre@intel.com>
|
|
||||||
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||||
M: Intel Linux Wireless <ilw@linux.intel.com>
|
M: Intel Linux Wireless <ilw@linux.intel.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
|
|
|
@ -47,33 +47,16 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
|
||||||
#define USB_REQ_DFU_DNLOAD 1
|
#define USB_REQ_DFU_DNLOAD 1
|
||||||
#define BULK_SIZE 4096
|
#define BULK_SIZE 4096
|
||||||
|
|
||||||
struct ath3k_data {
|
static int ath3k_load_firmware(struct usb_device *udev,
|
||||||
struct usb_device *udev;
|
const struct firmware *firmware)
|
||||||
u8 *fw_data;
|
|
||||||
u32 fw_size;
|
|
||||||
u32 fw_sent;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ath3k_load_firmware(struct ath3k_data *data,
|
|
||||||
unsigned char *firmware,
|
|
||||||
int count)
|
|
||||||
{
|
{
|
||||||
u8 *send_buf;
|
u8 *send_buf;
|
||||||
int err, pipe, len, size, sent = 0;
|
int err, pipe, len, size, sent = 0;
|
||||||
|
int count = firmware->size;
|
||||||
|
|
||||||
BT_DBG("ath3k %p udev %p", data, data->udev);
|
BT_DBG("udev %p", udev);
|
||||||
|
|
||||||
pipe = usb_sndctrlpipe(data->udev, 0);
|
pipe = usb_sndctrlpipe(udev, 0);
|
||||||
|
|
||||||
if ((usb_control_msg(data->udev, pipe,
|
|
||||||
USB_REQ_DFU_DNLOAD,
|
|
||||||
USB_TYPE_VENDOR, 0, 0,
|
|
||||||
firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
|
|
||||||
BT_ERR("Can't change to loading configuration err");
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
sent += 20;
|
|
||||||
count -= 20;
|
|
||||||
|
|
||||||
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
|
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
|
||||||
if (!send_buf) {
|
if (!send_buf) {
|
||||||
|
@ -81,12 +64,23 @@ static int ath3k_load_firmware(struct ath3k_data *data,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(send_buf, firmware->data, 20);
|
||||||
|
if ((err = usb_control_msg(udev, pipe,
|
||||||
|
USB_REQ_DFU_DNLOAD,
|
||||||
|
USB_TYPE_VENDOR, 0, 0,
|
||||||
|
send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
|
||||||
|
BT_ERR("Can't change to loading configuration err");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
sent += 20;
|
||||||
|
count -= 20;
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
size = min_t(uint, count, BULK_SIZE);
|
size = min_t(uint, count, BULK_SIZE);
|
||||||
pipe = usb_sndbulkpipe(data->udev, 0x02);
|
pipe = usb_sndbulkpipe(udev, 0x02);
|
||||||
memcpy(send_buf, firmware + sent, size);
|
memcpy(send_buf, firmware->data + sent, size);
|
||||||
|
|
||||||
err = usb_bulk_msg(data->udev, pipe, send_buf, size,
|
err = usb_bulk_msg(udev, pipe, send_buf, size,
|
||||||
&len, 3000);
|
&len, 3000);
|
||||||
|
|
||||||
if (err || (len != size)) {
|
if (err || (len != size)) {
|
||||||
|
@ -112,57 +106,28 @@ static int ath3k_probe(struct usb_interface *intf,
|
||||||
{
|
{
|
||||||
const struct firmware *firmware;
|
const struct firmware *firmware;
|
||||||
struct usb_device *udev = interface_to_usbdev(intf);
|
struct usb_device *udev = interface_to_usbdev(intf);
|
||||||
struct ath3k_data *data;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
BT_DBG("intf %p id %p", intf, id);
|
BT_DBG("intf %p id %p", intf, id);
|
||||||
|
|
||||||
if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
|
if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
|
||||||
if (!data)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
data->udev = udev;
|
|
||||||
|
|
||||||
if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
|
if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
|
||||||
kfree(data);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = max_t(uint, firmware->size, 4096);
|
if (ath3k_load_firmware(udev, firmware)) {
|
||||||
data->fw_data = kmalloc(size, GFP_KERNEL);
|
|
||||||
if (!data->fw_data) {
|
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
kfree(data);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data->fw_data, firmware->data, firmware->size);
|
|
||||||
data->fw_size = firmware->size;
|
|
||||||
data->fw_sent = 0;
|
|
||||||
release_firmware(firmware);
|
|
||||||
|
|
||||||
usb_set_intfdata(intf, data);
|
|
||||||
if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
|
|
||||||
usb_set_intfdata(intf, NULL);
|
|
||||||
kfree(data->fw_data);
|
|
||||||
kfree(data);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
release_firmware(firmware);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath3k_disconnect(struct usb_interface *intf)
|
static void ath3k_disconnect(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct ath3k_data *data = usb_get_intfdata(intf);
|
|
||||||
|
|
||||||
BT_DBG("ath3k_disconnect intf %p", intf);
|
BT_DBG("ath3k_disconnect intf %p", intf);
|
||||||
|
|
||||||
kfree(data->fw_data);
|
|
||||||
kfree(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_driver ath3k_driver = {
|
static struct usb_driver ath3k_driver = {
|
||||||
|
|
|
@ -2280,6 +2280,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
|
||||||
int i;
|
int i;
|
||||||
bool needreset = false;
|
bool needreset = false;
|
||||||
|
|
||||||
|
mutex_lock(&sc->lock);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
|
for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
|
||||||
if (sc->txqs[i].setup) {
|
if (sc->txqs[i].setup) {
|
||||||
txq = &sc->txqs[i];
|
txq = &sc->txqs[i];
|
||||||
|
@ -2307,6 +2309,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
|
||||||
ath5k_reset(sc, NULL, true);
|
ath5k_reset(sc, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&sc->lock);
|
||||||
|
|
||||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
||||||
msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
|
msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
|
||||||
}
|
}
|
||||||
|
|
|
@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah)
|
||||||
for (i = 0; i < qmax; i++) {
|
for (i = 0; i < qmax; i++) {
|
||||||
err = ath5k_hw_stop_tx_dma(ah, i);
|
err = ath5k_hw_stop_tx_dma(ah, i);
|
||||||
/* -EINVAL -> queue inactive */
|
/* -EINVAL -> queue inactive */
|
||||||
if (err != -EINVAL)
|
if (err && err != -EINVAL)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
|
||||||
if (!ah->ah_bwmode) {
|
if (!ah->ah_bwmode) {
|
||||||
dur = ieee80211_generic_frame_duration(sc->hw,
|
dur = ieee80211_generic_frame_duration(sc->hw,
|
||||||
NULL, len, rate);
|
NULL, len, rate);
|
||||||
return dur;
|
return le16_to_cpu(dur);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitrate = rate->bitrate;
|
bitrate = rate->bitrate;
|
||||||
|
@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
|
||||||
* what rate we should choose to TX ACKs. */
|
* what rate we should choose to TX ACKs. */
|
||||||
tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
|
tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
|
||||||
|
|
||||||
tx_time = le16_to_cpu(tx_time);
|
|
||||||
|
|
||||||
ath5k_hw_reg_write(ah, tx_time, reg);
|
ath5k_hw_reg_write(ah, tx_time, reg);
|
||||||
|
|
||||||
if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
|
if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
|
||||||
|
|
|
@ -679,10 +679,6 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
|
||||||
|
|
||||||
/* Do NF cal only at longer intervals */
|
/* Do NF cal only at longer intervals */
|
||||||
if (longcal || nfcal_pending) {
|
if (longcal || nfcal_pending) {
|
||||||
/* Do periodic PAOffset Cal */
|
|
||||||
ar9002_hw_pa_cal(ah, false);
|
|
||||||
ar9002_hw_olc_temp_compensation(ah);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the value from the previous NF cal and update
|
* Get the value from the previous NF cal and update
|
||||||
* history buffer.
|
* history buffer.
|
||||||
|
@ -697,8 +693,12 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
|
||||||
ath9k_hw_loadnf(ah, ah->curchan);
|
ath9k_hw_loadnf(ah, ah->curchan);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longcal)
|
if (longcal) {
|
||||||
ath9k_hw_start_nfcal(ah, false);
|
ath9k_hw_start_nfcal(ah, false);
|
||||||
|
/* Do periodic PAOffset Cal */
|
||||||
|
ar9002_hw_pa_cal(ah, false);
|
||||||
|
ar9002_hw_olc_temp_compensation(ah);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iscaldone;
|
return iscaldone;
|
||||||
|
|
|
@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WAR for ASPM system hang */
|
/* WAR for ASPM system hang */
|
||||||
if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
|
if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
|
||||||
val |= (AR_WA_BIT6 | AR_WA_BIT7);
|
val |= (AR_WA_BIT6 | AR_WA_BIT7);
|
||||||
}
|
|
||||||
|
|
||||||
if (AR_SREV_9285E_20(ah))
|
if (AR_SREV_9285E_20(ah))
|
||||||
val |= AR_WA_BIT23;
|
val |= AR_WA_BIT23;
|
||||||
|
|
|
@ -1842,7 +1842,7 @@ static const u32 ar9300_2p2_soc_preamble[][2] = {
|
||||||
|
|
||||||
static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
|
static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
|
||||||
/* Addr allmodes */
|
/* Addr allmodes */
|
||||||
{0x00004040, 0x08212e5e},
|
{0x00004040, 0x0821265e},
|
||||||
{0x00004040, 0x0008003b},
|
{0x00004040, 0x0008003b},
|
||||||
{0x00004044, 0x00000000},
|
{0x00004044, 0x00000000},
|
||||||
};
|
};
|
||||||
|
|
|
@ -146,8 +146,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||||
/* Sleep Setting */
|
/* Sleep Setting */
|
||||||
|
|
||||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||||
ar9300PciePhy_clkreq_enable_L1_2p2,
|
ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
|
||||||
ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
|
ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
|
||||||
2);
|
2);
|
||||||
|
|
||||||
/* Fast clock modal settings */
|
/* Fast clock modal settings */
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct tx_frame_hdr {
|
||||||
u8 node_idx;
|
u8 node_idx;
|
||||||
u8 vif_idx;
|
u8 vif_idx;
|
||||||
u8 tidno;
|
u8 tidno;
|
||||||
u32 flags; /* ATH9K_HTC_TX_* */
|
__be32 flags; /* ATH9K_HTC_TX_* */
|
||||||
u8 key_type;
|
u8 key_type;
|
||||||
u8 keyix;
|
u8 keyix;
|
||||||
u8 reserved[26];
|
u8 reserved[26];
|
||||||
|
|
|
@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
|
||||||
{
|
{
|
||||||
ath9k_htc_exit_debug(priv->ah);
|
ath9k_htc_exit_debug(priv->ah);
|
||||||
ath9k_hw_deinit(priv->ah);
|
ath9k_hw_deinit(priv->ah);
|
||||||
tasklet_kill(&priv->swba_tasklet);
|
|
||||||
tasklet_kill(&priv->rx_tasklet);
|
|
||||||
tasklet_kill(&priv->tx_tasklet);
|
|
||||||
kfree(priv->ah);
|
kfree(priv->ah);
|
||||||
priv->ah = NULL;
|
priv->ah = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1026,12 +1026,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u8 cmd_rsp;
|
u8 cmd_rsp;
|
||||||
|
|
||||||
/* Cancel all the running timers/work .. */
|
|
||||||
cancel_work_sync(&priv->fatal_work);
|
|
||||||
cancel_work_sync(&priv->ps_work);
|
|
||||||
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
|
|
||||||
ath9k_led_stop_brightness(priv);
|
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
|
|
||||||
if (priv->op_flags & OP_INVALID) {
|
if (priv->op_flags & OP_INVALID) {
|
||||||
|
@ -1045,8 +1039,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||||
WMI_CMD(WMI_DISABLE_INTR_CMDID);
|
WMI_CMD(WMI_DISABLE_INTR_CMDID);
|
||||||
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
|
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
|
||||||
WMI_CMD(WMI_STOP_RECV_CMDID);
|
WMI_CMD(WMI_STOP_RECV_CMDID);
|
||||||
|
|
||||||
|
tasklet_kill(&priv->swba_tasklet);
|
||||||
|
tasklet_kill(&priv->rx_tasklet);
|
||||||
|
tasklet_kill(&priv->tx_tasklet);
|
||||||
|
|
||||||
skb_queue_purge(&priv->tx_queue);
|
skb_queue_purge(&priv->tx_queue);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
|
|
||||||
|
/* Cancel all the running timers/work .. */
|
||||||
|
cancel_work_sync(&priv->fatal_work);
|
||||||
|
cancel_work_sync(&priv->ps_work);
|
||||||
|
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
|
||||||
|
ath9k_led_stop_brightness(priv);
|
||||||
|
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
|
|
||||||
/* Remove monitor interface here */
|
/* Remove monitor interface here */
|
||||||
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
|
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
|
||||||
if (ath9k_htc_remove_monitor_interface(priv))
|
if (ath9k_htc_remove_monitor_interface(priv))
|
||||||
|
|
|
@ -113,6 +113,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
|
||||||
|
|
||||||
if (ieee80211_is_data(fc)) {
|
if (ieee80211_is_data(fc)) {
|
||||||
struct tx_frame_hdr tx_hdr;
|
struct tx_frame_hdr tx_hdr;
|
||||||
|
u32 flags = 0;
|
||||||
u8 *qc;
|
u8 *qc;
|
||||||
|
|
||||||
memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
|
memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
|
||||||
|
@ -136,13 +137,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
|
||||||
/* Check for RTS protection */
|
/* Check for RTS protection */
|
||||||
if (priv->hw->wiphy->rts_threshold != (u32) -1)
|
if (priv->hw->wiphy->rts_threshold != (u32) -1)
|
||||||
if (skb->len > priv->hw->wiphy->rts_threshold)
|
if (skb->len > priv->hw->wiphy->rts_threshold)
|
||||||
tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
|
flags |= ATH9K_HTC_TX_RTSCTS;
|
||||||
|
|
||||||
/* CTS-to-self */
|
/* CTS-to-self */
|
||||||
if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
|
if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
|
||||||
(priv->op_flags & OP_PROTECT_ENABLE))
|
(priv->op_flags & OP_PROTECT_ENABLE))
|
||||||
tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
|
flags |= ATH9K_HTC_TX_CTSONLY;
|
||||||
|
|
||||||
|
tx_hdr.flags = cpu_to_be32(flags);
|
||||||
tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
|
tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
|
||||||
if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
|
if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
|
||||||
tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
|
tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
|
||||||
|
|
|
@ -369,6 +369,9 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
|
||||||
else
|
else
|
||||||
ah->config.ht_enable = 0;
|
ah->config.ht_enable = 0;
|
||||||
|
|
||||||
|
/* PAPRD needs some more work to be enabled */
|
||||||
|
ah->config.paprd_disable = 1;
|
||||||
|
|
||||||
ah->config.rx_intr_mitigation = true;
|
ah->config.rx_intr_mitigation = true;
|
||||||
ah->config.pcieSerDesWrite = true;
|
ah->config.pcieSerDesWrite = true;
|
||||||
|
|
||||||
|
@ -1971,7 +1974,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||||
pCap->rx_status_len = sizeof(struct ar9003_rxs);
|
pCap->rx_status_len = sizeof(struct ar9003_rxs);
|
||||||
pCap->tx_desc_len = sizeof(struct ar9003_txc);
|
pCap->tx_desc_len = sizeof(struct ar9003_txc);
|
||||||
pCap->txs_len = sizeof(struct ar9003_txs);
|
pCap->txs_len = sizeof(struct ar9003_txs);
|
||||||
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
|
if (!ah->config.paprd_disable &&
|
||||||
|
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
|
||||||
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
|
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
|
||||||
} else {
|
} else {
|
||||||
pCap->tx_desc_len = sizeof(struct ath_desc);
|
pCap->tx_desc_len = sizeof(struct ath_desc);
|
||||||
|
|
|
@ -228,6 +228,7 @@ struct ath9k_ops_config {
|
||||||
u32 pcie_waen;
|
u32 pcie_waen;
|
||||||
u8 analog_shiftreg;
|
u8 analog_shiftreg;
|
||||||
u8 ht_enable;
|
u8 ht_enable;
|
||||||
|
u8 paprd_disable;
|
||||||
u32 ofdm_trig_low;
|
u32 ofdm_trig_low;
|
||||||
u32 ofdm_trig_high;
|
u32 ofdm_trig_high;
|
||||||
u32 cck_trig_high;
|
u32 cck_trig_high;
|
||||||
|
|
|
@ -600,8 +600,6 @@ err_btcoex:
|
||||||
err_queues:
|
err_queues:
|
||||||
ath9k_hw_deinit(ah);
|
ath9k_hw_deinit(ah);
|
||||||
err_hw:
|
err_hw:
|
||||||
tasklet_kill(&sc->intr_tq);
|
|
||||||
tasklet_kill(&sc->bcon_tasklet);
|
|
||||||
|
|
||||||
kfree(ah);
|
kfree(ah);
|
||||||
sc->sc_ah = NULL;
|
sc->sc_ah = NULL;
|
||||||
|
@ -805,9 +803,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
|
||||||
|
|
||||||
ath9k_hw_deinit(sc->sc_ah);
|
ath9k_hw_deinit(sc->sc_ah);
|
||||||
|
|
||||||
tasklet_kill(&sc->intr_tq);
|
|
||||||
tasklet_kill(&sc->bcon_tasklet);
|
|
||||||
|
|
||||||
kfree(sc->sc_ah);
|
kfree(sc->sc_ah);
|
||||||
sc->sc_ah = NULL;
|
sc->sc_ah = NULL;
|
||||||
}
|
}
|
||||||
|
@ -821,6 +816,8 @@ void ath9k_deinit_device(struct ath_softc *sc)
|
||||||
wiphy_rfkill_stop_polling(sc->hw->wiphy);
|
wiphy_rfkill_stop_polling(sc->hw->wiphy);
|
||||||
ath_deinit_leds(sc);
|
ath_deinit_leds(sc);
|
||||||
|
|
||||||
|
ath9k_ps_restore(sc);
|
||||||
|
|
||||||
ieee80211_unregister_hw(hw);
|
ieee80211_unregister_hw(hw);
|
||||||
pm_qos_remove_request(&sc->pm_qos_req);
|
pm_qos_remove_request(&sc->pm_qos_req);
|
||||||
ath_rx_cleanup(sc);
|
ath_rx_cleanup(sc);
|
||||||
|
|
|
@ -611,14 +611,12 @@ void ath9k_tasklet(unsigned long data)
|
||||||
u32 status = sc->intrstatus;
|
u32 status = sc->intrstatus;
|
||||||
u32 rxmask;
|
u32 rxmask;
|
||||||
|
|
||||||
ath9k_ps_wakeup(sc);
|
|
||||||
|
|
||||||
if (status & ATH9K_INT_FATAL) {
|
if (status & ATH9K_INT_FATAL) {
|
||||||
ath_reset(sc, true);
|
ath_reset(sc, true);
|
||||||
ath9k_ps_restore(sc);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ath9k_ps_wakeup(sc);
|
||||||
spin_lock(&sc->sc_pcu_lock);
|
spin_lock(&sc->sc_pcu_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -939,8 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||||
|
|
||||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
|
|
||||||
ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ath_reset(struct ath_softc *sc, bool retry_tx)
|
int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||||
|
@ -953,6 +949,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||||
/* Stop ANI */
|
/* Stop ANI */
|
||||||
del_timer_sync(&common->ani.timer);
|
del_timer_sync(&common->ani.timer);
|
||||||
|
|
||||||
|
ath9k_ps_wakeup(sc);
|
||||||
spin_lock_bh(&sc->sc_pcu_lock);
|
spin_lock_bh(&sc->sc_pcu_lock);
|
||||||
|
|
||||||
ieee80211_stop_queues(hw);
|
ieee80211_stop_queues(hw);
|
||||||
|
@ -999,6 +996,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||||
|
|
||||||
/* Start ANI */
|
/* Start ANI */
|
||||||
ath_start_ani(common);
|
ath_start_ani(common);
|
||||||
|
ath9k_ps_restore(sc);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1220,6 +1218,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
spin_lock_bh(&sc->sc_pcu_lock);
|
spin_lock_bh(&sc->sc_pcu_lock);
|
||||||
|
|
||||||
|
/* prevent tasklets to enable interrupts once we disable them */
|
||||||
|
ah->imask &= ~ATH9K_INT_GLOBAL;
|
||||||
|
|
||||||
/* make sure h/w will not generate any interrupt
|
/* make sure h/w will not generate any interrupt
|
||||||
* before setting the invalid flag. */
|
* before setting the invalid flag. */
|
||||||
ath9k_hw_disable_interrupts(ah);
|
ath9k_hw_disable_interrupts(ah);
|
||||||
|
@ -1242,6 +1243,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||||
|
|
||||||
|
/* we can now sync irq and kill any running tasklets, since we already
|
||||||
|
* disabled interrupts and not holding a spin lock */
|
||||||
|
synchronize_irq(sc->irq);
|
||||||
|
tasklet_kill(&sc->intr_tq);
|
||||||
|
tasklet_kill(&sc->bcon_tasklet);
|
||||||
|
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
|
|
||||||
sc->ps_idle = true;
|
sc->ps_idle = true;
|
||||||
|
@ -1706,7 +1713,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
|
|
||||||
if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
||||||
sc->config.txpowlimit = 2 * conf->power_level;
|
sc->config.txpowlimit = 2 * conf->power_level;
|
||||||
|
ath9k_ps_wakeup(sc);
|
||||||
ath_update_txpow(sc);
|
ath_update_txpow(sc);
|
||||||
|
ath9k_ps_restore(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disable_radio) {
|
if (disable_radio) {
|
||||||
|
|
|
@ -2173,9 +2173,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||||
if (needreset) {
|
if (needreset) {
|
||||||
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
|
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
|
||||||
"tx hung, resetting the chip\n");
|
"tx hung, resetting the chip\n");
|
||||||
ath9k_ps_wakeup(sc);
|
|
||||||
ath_reset(sc, true);
|
ath_reset(sc, true);
|
||||||
ath9k_ps_restore(sc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
||||||
|
|
|
@ -2629,6 +2629,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
|
||||||
.fw_name_pre = IWL4965_FW_PRE,
|
.fw_name_pre = IWL4965_FW_PRE,
|
||||||
.ucode_api_max = IWL4965_UCODE_API_MAX,
|
.ucode_api_max = IWL4965_UCODE_API_MAX,
|
||||||
.ucode_api_min = IWL4965_UCODE_API_MIN,
|
.ucode_api_min = IWL4965_UCODE_API_MIN,
|
||||||
|
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||||
.valid_tx_ant = ANT_AB,
|
.valid_tx_ant = ANT_AB,
|
||||||
.valid_rx_ant = ANT_ABC,
|
.valid_rx_ant = ANT_ABC,
|
||||||
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
|
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
|
||||||
|
|
|
@ -152,11 +152,14 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||||
|
|
||||||
eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
|
eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
|
||||||
|
|
||||||
priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
|
if (!priv->cfg->sku) {
|
||||||
|
/* not using sku overwrite */
|
||||||
|
priv->cfg->sku =
|
||||||
|
((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
|
||||||
EEPROM_SKU_CAP_BAND_POS);
|
EEPROM_SKU_CAP_BAND_POS);
|
||||||
if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
|
if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||||
priv->cfg->sku |= IWL_SKU_N;
|
priv->cfg->sku |= IWL_SKU_N;
|
||||||
|
}
|
||||||
if (!priv->cfg->sku) {
|
if (!priv->cfg->sku) {
|
||||||
IWL_ERR(priv, "Invalid device sku\n");
|
IWL_ERR(priv, "Invalid device sku\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -168,7 +171,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||||
/* not using .cfg overwrite */
|
/* not using .cfg overwrite */
|
||||||
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
|
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
|
||||||
priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
||||||
priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
|
||||||
if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
|
if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
|
||||||
IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
|
IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
|
||||||
priv->cfg->valid_tx_ant,
|
priv->cfg->valid_tx_ant,
|
||||||
|
|
|
@ -126,6 +126,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
|
||||||
ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
|
ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
|
||||||
if (!ndev) {
|
if (!ndev) {
|
||||||
dev_err(dev, "no memory for network device instance\n");
|
dev_err(dev, "no memory for network device instance\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out_priv;
|
goto out_priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +139,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!iwm->umac_profile) {
|
if (!iwm->umac_profile) {
|
||||||
dev_err(dev, "Couldn't alloc memory for profile\n");
|
dev_err(dev, "Couldn't alloc memory for profile\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out_profile;
|
goto out_profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
|
||||||
|
|
||||||
if (!fw || !fw->size || !fw->data) {
|
if (!fw || !fw->size || !fw->data) {
|
||||||
ERROR(rt2x00dev, "Failed to read Firmware.\n");
|
ERROR(rt2x00dev, "Failed to read Firmware.\n");
|
||||||
|
release_firmware(fw);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2446,6 +2446,7 @@ static struct usb_device_id rt73usb_device_table[] = {
|
||||||
{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
|
{ USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
/* Qcom */
|
/* Qcom */
|
||||||
{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
|
|
|
@ -727,7 +727,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
|
||||||
|
|
||||||
static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
u8 efuse_data, u8 offset, int *bcontinual,
|
u8 efuse_data, u8 offset, int *bcontinual,
|
||||||
u8 *write_state, struct pgpkt_struct target_pkt,
|
u8 *write_state, struct pgpkt_struct *target_pkt,
|
||||||
int *repeat_times, int *bresult, u8 word_en)
|
int *repeat_times, int *bresult, u8 word_en)
|
||||||
{
|
{
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
@ -744,8 +744,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
tmp_pkt.word_en = tmp_header & 0x0F;
|
tmp_pkt.word_en = tmp_header & 0x0F;
|
||||||
tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
|
tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
|
||||||
|
|
||||||
if (tmp_pkt.offset != target_pkt.offset) {
|
if (tmp_pkt.offset != target_pkt->offset) {
|
||||||
efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
|
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
|
||||||
*write_state = PG_STATE_HEADER;
|
*write_state = PG_STATE_HEADER;
|
||||||
} else {
|
} else {
|
||||||
for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
|
for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
|
||||||
|
@ -756,23 +756,23 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bdataempty == false) {
|
if (bdataempty == false) {
|
||||||
efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
|
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
|
||||||
*write_state = PG_STATE_HEADER;
|
*write_state = PG_STATE_HEADER;
|
||||||
} else {
|
} else {
|
||||||
match_word_en = 0x0F;
|
match_word_en = 0x0F;
|
||||||
if (!((target_pkt.word_en & BIT(0)) |
|
if (!((target_pkt->word_en & BIT(0)) |
|
||||||
(tmp_pkt.word_en & BIT(0))))
|
(tmp_pkt.word_en & BIT(0))))
|
||||||
match_word_en &= (~BIT(0));
|
match_word_en &= (~BIT(0));
|
||||||
|
|
||||||
if (!((target_pkt.word_en & BIT(1)) |
|
if (!((target_pkt->word_en & BIT(1)) |
|
||||||
(tmp_pkt.word_en & BIT(1))))
|
(tmp_pkt.word_en & BIT(1))))
|
||||||
match_word_en &= (~BIT(1));
|
match_word_en &= (~BIT(1));
|
||||||
|
|
||||||
if (!((target_pkt.word_en & BIT(2)) |
|
if (!((target_pkt->word_en & BIT(2)) |
|
||||||
(tmp_pkt.word_en & BIT(2))))
|
(tmp_pkt.word_en & BIT(2))))
|
||||||
match_word_en &= (~BIT(2));
|
match_word_en &= (~BIT(2));
|
||||||
|
|
||||||
if (!((target_pkt.word_en & BIT(3)) |
|
if (!((target_pkt->word_en & BIT(3)) |
|
||||||
(tmp_pkt.word_en & BIT(3))))
|
(tmp_pkt.word_en & BIT(3))))
|
||||||
match_word_en &= (~BIT(3));
|
match_word_en &= (~BIT(3));
|
||||||
|
|
||||||
|
@ -780,7 +780,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
badworden = efuse_word_enable_data_write(
|
badworden = efuse_word_enable_data_write(
|
||||||
hw, *efuse_addr + 1,
|
hw, *efuse_addr + 1,
|
||||||
tmp_pkt.word_en,
|
tmp_pkt.word_en,
|
||||||
target_pkt.data);
|
target_pkt->data);
|
||||||
|
|
||||||
if (0x0F != (badworden & 0x0F)) {
|
if (0x0F != (badworden & 0x0F)) {
|
||||||
u8 reorg_offset = offset;
|
u8 reorg_offset = offset;
|
||||||
|
@ -791,26 +791,26 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_word_en = 0x0F;
|
tmp_word_en = 0x0F;
|
||||||
if ((target_pkt.word_en & BIT(0)) ^
|
if ((target_pkt->word_en & BIT(0)) ^
|
||||||
(match_word_en & BIT(0)))
|
(match_word_en & BIT(0)))
|
||||||
tmp_word_en &= (~BIT(0));
|
tmp_word_en &= (~BIT(0));
|
||||||
|
|
||||||
if ((target_pkt.word_en & BIT(1)) ^
|
if ((target_pkt->word_en & BIT(1)) ^
|
||||||
(match_word_en & BIT(1)))
|
(match_word_en & BIT(1)))
|
||||||
tmp_word_en &= (~BIT(1));
|
tmp_word_en &= (~BIT(1));
|
||||||
|
|
||||||
if ((target_pkt.word_en & BIT(2)) ^
|
if ((target_pkt->word_en & BIT(2)) ^
|
||||||
(match_word_en & BIT(2)))
|
(match_word_en & BIT(2)))
|
||||||
tmp_word_en &= (~BIT(2));
|
tmp_word_en &= (~BIT(2));
|
||||||
|
|
||||||
if ((target_pkt.word_en & BIT(3)) ^
|
if ((target_pkt->word_en & BIT(3)) ^
|
||||||
(match_word_en & BIT(3)))
|
(match_word_en & BIT(3)))
|
||||||
tmp_word_en &= (~BIT(3));
|
tmp_word_en &= (~BIT(3));
|
||||||
|
|
||||||
if ((tmp_word_en & 0x0F) != 0x0F) {
|
if ((tmp_word_en & 0x0F) != 0x0F) {
|
||||||
*efuse_addr = efuse_get_current_size(hw);
|
*efuse_addr = efuse_get_current_size(hw);
|
||||||
target_pkt.offset = offset;
|
target_pkt->offset = offset;
|
||||||
target_pkt.word_en = tmp_word_en;
|
target_pkt->word_en = tmp_word_en;
|
||||||
} else
|
} else
|
||||||
*bcontinual = false;
|
*bcontinual = false;
|
||||||
*write_state = PG_STATE_HEADER;
|
*write_state = PG_STATE_HEADER;
|
||||||
|
@ -821,8 +821,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*efuse_addr += (2 * tmp_word_cnts) + 1;
|
*efuse_addr += (2 * tmp_word_cnts) + 1;
|
||||||
target_pkt.offset = offset;
|
target_pkt->offset = offset;
|
||||||
target_pkt.word_en = word_en;
|
target_pkt->word_en = word_en;
|
||||||
*write_state = PG_STATE_HEADER;
|
*write_state = PG_STATE_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
|
||||||
efuse_write_data_case1(hw, &efuse_addr,
|
efuse_write_data_case1(hw, &efuse_addr,
|
||||||
efuse_data, offset,
|
efuse_data, offset,
|
||||||
&bcontinual,
|
&bcontinual,
|
||||||
&write_state, target_pkt,
|
&write_state, &target_pkt,
|
||||||
&repeat_times, &bresult,
|
&repeat_times, &bresult,
|
||||||
word_en);
|
word_en);
|
||||||
else
|
else
|
||||||
|
|
|
@ -619,6 +619,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||||
struct sk_buff *uskb = NULL;
|
struct sk_buff *uskb = NULL;
|
||||||
u8 *pdata;
|
u8 *pdata;
|
||||||
uskb = dev_alloc_skb(skb->len + 128);
|
uskb = dev_alloc_skb(skb->len + 128);
|
||||||
|
if (!uskb) {
|
||||||
|
RT_TRACE(rtlpriv,
|
||||||
|
(COMP_INTR | COMP_RECV),
|
||||||
|
DBG_EMERG,
|
||||||
|
("can't alloc rx skb\n"));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
memcpy(IEEE80211_SKB_RXCB(uskb),
|
memcpy(IEEE80211_SKB_RXCB(uskb),
|
||||||
&rx_status,
|
&rx_status,
|
||||||
sizeof(rx_status));
|
sizeof(rx_status));
|
||||||
|
@ -641,7 +648,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||||
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
||||||
if (unlikely(!new_skb)) {
|
if (unlikely(!new_skb)) {
|
||||||
RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
|
RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
|
||||||
DBG_DMESG,
|
DBG_EMERG,
|
||||||
("can't alloc skb for rx\n"));
|
("can't alloc skb for rx\n"));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1066,9 +1073,9 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
|
||||||
struct sk_buff *skb =
|
struct sk_buff *skb =
|
||||||
dev_alloc_skb(rtlpci->rxbuffersize);
|
dev_alloc_skb(rtlpci->rxbuffersize);
|
||||||
u32 bufferaddress;
|
u32 bufferaddress;
|
||||||
entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return 0;
|
return 0;
|
||||||
|
entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
|
||||||
|
|
||||||
/*skb->dev = dev; */
|
/*skb->dev = dev; */
|
||||||
|
|
||||||
|
|
|
@ -959,7 +959,7 @@ struct ieee80211_ht_info {
|
||||||
/* block-ack parameters */
|
/* block-ack parameters */
|
||||||
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
|
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
|
||||||
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
|
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
|
||||||
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
|
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
|
||||||
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
|
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
|
||||||
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
|
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,7 @@ struct hci_conn {
|
||||||
__u32 link_mode;
|
__u32 link_mode;
|
||||||
__u8 auth_type;
|
__u8 auth_type;
|
||||||
__u8 sec_level;
|
__u8 sec_level;
|
||||||
|
__u8 pending_sec_level;
|
||||||
__u8 power_save;
|
__u8 power_save;
|
||||||
__u16 disc_timeout;
|
__u16 disc_timeout;
|
||||||
unsigned long pend;
|
unsigned long pend;
|
||||||
|
|
|
@ -379,14 +379,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
|
||||||
hci_conn_hold(acl);
|
hci_conn_hold(acl);
|
||||||
|
|
||||||
if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
|
if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
|
||||||
acl->sec_level = sec_level;
|
acl->sec_level = BT_SECURITY_LOW;
|
||||||
|
acl->pending_sec_level = sec_level;
|
||||||
acl->auth_type = auth_type;
|
acl->auth_type = auth_type;
|
||||||
hci_acl_connect(acl);
|
hci_acl_connect(acl);
|
||||||
} else {
|
|
||||||
if (acl->sec_level < sec_level)
|
|
||||||
acl->sec_level = sec_level;
|
|
||||||
if (acl->auth_type < auth_type)
|
|
||||||
acl->auth_type = auth_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ACL_LINK)
|
if (type == ACL_LINK)
|
||||||
|
@ -442,11 +438,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
|
||||||
{
|
{
|
||||||
BT_DBG("conn %p", conn);
|
BT_DBG("conn %p", conn);
|
||||||
|
|
||||||
|
if (conn->pending_sec_level > sec_level)
|
||||||
|
sec_level = conn->pending_sec_level;
|
||||||
|
|
||||||
if (sec_level > conn->sec_level)
|
if (sec_level > conn->sec_level)
|
||||||
conn->sec_level = sec_level;
|
conn->pending_sec_level = sec_level;
|
||||||
else if (conn->link_mode & HCI_LM_AUTH)
|
else if (conn->link_mode & HCI_LM_AUTH)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Make sure we preserve an existing MITM requirement*/
|
||||||
|
auth_type |= (conn->auth_type & 0x01);
|
||||||
|
|
||||||
conn->auth_type = auth_type;
|
conn->auth_type = auth_type;
|
||||||
|
|
||||||
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
|
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
|
||||||
|
|
|
@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev)
|
||||||
|
|
||||||
destroy_workqueue(hdev->workqueue);
|
destroy_workqueue(hdev->workqueue);
|
||||||
|
|
||||||
|
hci_dev_lock_bh(hdev);
|
||||||
|
hci_blacklist_clear(hdev);
|
||||||
|
hci_dev_unlock_bh(hdev);
|
||||||
|
|
||||||
__hci_dev_put(hdev);
|
__hci_dev_put(hdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
|
||||||
if (conn->state != BT_CONFIG || !conn->out)
|
if (conn->state != BT_CONFIG || !conn->out)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (conn->sec_level == BT_SECURITY_SDP)
|
if (conn->pending_sec_level == BT_SECURITY_SDP)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Only request authentication for SSP connections or non-SSP
|
/* Only request authentication for SSP connections or non-SSP
|
||||||
* devices with sec_level HIGH */
|
* devices with sec_level HIGH */
|
||||||
if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
|
if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
|
||||||
conn->sec_level != BT_SECURITY_HIGH)
|
conn->pending_sec_level != BT_SECURITY_HIGH)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
|
||||||
|
|
||||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
||||||
if (conn) {
|
if (conn) {
|
||||||
if (!ev->status)
|
if (!ev->status) {
|
||||||
conn->link_mode |= HCI_LM_AUTH;
|
conn->link_mode |= HCI_LM_AUTH;
|
||||||
else
|
conn->sec_level = conn->pending_sec_level;
|
||||||
|
} else
|
||||||
conn->sec_level = BT_SECURITY_LOW;
|
conn->sec_level = BT_SECURITY_LOW;
|
||||||
|
|
||||||
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
|
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
|
||||||
|
|
|
@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u8 l2cap_get_auth_type(struct sock *sk)
|
||||||
|
{
|
||||||
|
if (sk->sk_type == SOCK_RAW) {
|
||||||
|
switch (l2cap_pi(sk)->sec_level) {
|
||||||
|
case BT_SECURITY_HIGH:
|
||||||
|
return HCI_AT_DEDICATED_BONDING_MITM;
|
||||||
|
case BT_SECURITY_MEDIUM:
|
||||||
|
return HCI_AT_DEDICATED_BONDING;
|
||||||
|
default:
|
||||||
|
return HCI_AT_NO_BONDING;
|
||||||
|
}
|
||||||
|
} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
|
||||||
|
if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
|
||||||
|
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
|
||||||
|
|
||||||
|
if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
|
||||||
|
return HCI_AT_NO_BONDING_MITM;
|
||||||
|
else
|
||||||
|
return HCI_AT_NO_BONDING;
|
||||||
|
} else {
|
||||||
|
switch (l2cap_pi(sk)->sec_level) {
|
||||||
|
case BT_SECURITY_HIGH:
|
||||||
|
return HCI_AT_GENERAL_BONDING_MITM;
|
||||||
|
case BT_SECURITY_MEDIUM:
|
||||||
|
return HCI_AT_GENERAL_BONDING;
|
||||||
|
default:
|
||||||
|
return HCI_AT_NO_BONDING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Service level security */
|
/* Service level security */
|
||||||
static inline int l2cap_check_security(struct sock *sk)
|
static inline int l2cap_check_security(struct sock *sk)
|
||||||
{
|
{
|
||||||
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
|
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
|
||||||
__u8 auth_type;
|
__u8 auth_type;
|
||||||
|
|
||||||
if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
|
auth_type = l2cap_get_auth_type(sk);
|
||||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
|
|
||||||
auth_type = HCI_AT_NO_BONDING_MITM;
|
|
||||||
else
|
|
||||||
auth_type = HCI_AT_NO_BONDING;
|
|
||||||
|
|
||||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
|
|
||||||
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
|
|
||||||
} else {
|
|
||||||
switch (l2cap_pi(sk)->sec_level) {
|
|
||||||
case BT_SECURITY_HIGH:
|
|
||||||
auth_type = HCI_AT_GENERAL_BONDING_MITM;
|
|
||||||
break;
|
|
||||||
case BT_SECURITY_MEDIUM:
|
|
||||||
auth_type = HCI_AT_GENERAL_BONDING;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
auth_type = HCI_AT_NO_BONDING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
|
return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
|
||||||
auth_type);
|
auth_type);
|
||||||
|
@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk)
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
|
||||||
if (sk->sk_type == SOCK_RAW) {
|
auth_type = l2cap_get_auth_type(sk);
|
||||||
switch (l2cap_pi(sk)->sec_level) {
|
|
||||||
case BT_SECURITY_HIGH:
|
|
||||||
auth_type = HCI_AT_DEDICATED_BONDING_MITM;
|
|
||||||
break;
|
|
||||||
case BT_SECURITY_MEDIUM:
|
|
||||||
auth_type = HCI_AT_DEDICATED_BONDING;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
auth_type = HCI_AT_NO_BONDING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
|
|
||||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
|
|
||||||
auth_type = HCI_AT_NO_BONDING_MITM;
|
|
||||||
else
|
|
||||||
auth_type = HCI_AT_NO_BONDING;
|
|
||||||
|
|
||||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
|
|
||||||
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
|
|
||||||
} else {
|
|
||||||
switch (l2cap_pi(sk)->sec_level) {
|
|
||||||
case BT_SECURITY_HIGH:
|
|
||||||
auth_type = HCI_AT_GENERAL_BONDING_MITM;
|
|
||||||
break;
|
|
||||||
case BT_SECURITY_MEDIUM:
|
|
||||||
auth_type = HCI_AT_GENERAL_BONDING;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
auth_type = HCI_AT_NO_BONDING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hcon = hci_connect(hdev, ACL_LINK, dst,
|
hcon = hci_connect(hdev, ACL_LINK, dst,
|
||||||
l2cap_pi(sk)->sec_level, auth_type);
|
l2cap_pi(sk)->sec_level, auth_type);
|
||||||
|
@ -1127,6 +1106,7 @@ static int l2cap_do_connect(struct sock *sk)
|
||||||
if (sk->sk_type != SOCK_SEQPACKET &&
|
if (sk->sk_type != SOCK_SEQPACKET &&
|
||||||
sk->sk_type != SOCK_STREAM) {
|
sk->sk_type != SOCK_STREAM) {
|
||||||
l2cap_sock_clear_timer(sk);
|
l2cap_sock_clear_timer(sk);
|
||||||
|
if (l2cap_check_security(sk))
|
||||||
sk->sk_state = BT_CONNECTED;
|
sk->sk_state = BT_CONNECTED;
|
||||||
} else
|
} else
|
||||||
l2cap_do_start(sk);
|
l2cap_do_start(sk);
|
||||||
|
@ -1893,8 +1873,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
|
||||||
if (pi->mode == L2CAP_MODE_STREAMING) {
|
if (pi->mode == L2CAP_MODE_STREAMING) {
|
||||||
l2cap_streaming_send(sk);
|
l2cap_streaming_send(sk);
|
||||||
} else {
|
} else {
|
||||||
if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
|
if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
|
||||||
pi->conn_state && L2CAP_CONN_WAIT_F) {
|
(pi->conn_state & L2CAP_CONN_WAIT_F)) {
|
||||||
err = len;
|
err = len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1164,6 +1164,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
|
||||||
* initiator rfcomm_process_rx already calls
|
* initiator rfcomm_process_rx already calls
|
||||||
* rfcomm_session_put() */
|
* rfcomm_session_put() */
|
||||||
if (s->sock->sk->sk_state != BT_CLOSED)
|
if (s->sock->sk->sk_state != BT_CLOSED)
|
||||||
|
if (list_empty(&s->dlcs))
|
||||||
rfcomm_session_put(s);
|
rfcomm_session_put(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
|
||||||
struct ieee80211_mgmt *mgmt,
|
struct ieee80211_mgmt *mgmt,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw = &local->hw;
|
|
||||||
struct ieee80211_conf *conf = &hw->conf;
|
|
||||||
struct tid_ampdu_rx *tid_agg_rx;
|
struct tid_ampdu_rx *tid_agg_rx;
|
||||||
u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
|
u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
|
||||||
u8 dialog_token;
|
u8 dialog_token;
|
||||||
|
@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
|
||||||
goto end_no_lock;
|
goto end_no_lock;
|
||||||
}
|
}
|
||||||
/* determine default buffer size */
|
/* determine default buffer size */
|
||||||
if (buf_size == 0) {
|
if (buf_size == 0)
|
||||||
struct ieee80211_supported_band *sband;
|
buf_size = IEEE80211_MAX_AMPDU_BUF;
|
||||||
|
|
||||||
sband = local->hw.wiphy->bands[conf->channel->band];
|
|
||||||
buf_size = IEEE80211_MIN_AMPDU_BUF;
|
|
||||||
buf_size = buf_size << sband->ht_cap.ampdu_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the size doesn't exceed the maximum supported by the hw */
|
/* make sure the size doesn't exceed the maximum supported by the hw */
|
||||||
if (buf_size > local->hw.max_rx_aggregation_subframes)
|
if (buf_size > local->hw.max_rx_aggregation_subframes)
|
||||||
|
|
|
@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
|
||||||
MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
|
MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
|
||||||
"Disable 40MHz support in the 2.4GHz band");
|
"Disable 40MHz support in the 2.4GHz band");
|
||||||
|
|
||||||
|
static struct lock_class_key ieee80211_rx_skb_queue_class;
|
||||||
|
|
||||||
void ieee80211_configure_filter(struct ieee80211_local *local)
|
void ieee80211_configure_filter(struct ieee80211_local *local)
|
||||||
{
|
{
|
||||||
u64 mc;
|
u64 mc;
|
||||||
|
@ -570,7 +572,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
|
||||||
spin_lock_init(&local->filter_lock);
|
spin_lock_init(&local->filter_lock);
|
||||||
spin_lock_init(&local->queue_stop_reason_lock);
|
spin_lock_init(&local->queue_stop_reason_lock);
|
||||||
|
|
||||||
skb_queue_head_init(&local->rx_skb_queue);
|
/*
|
||||||
|
* The rx_skb_queue is only accessed from tasklets,
|
||||||
|
* but other SKB queues are used from within IRQ
|
||||||
|
* context. Therefore, this one needs a different
|
||||||
|
* locking class so our direct, non-irq-safe use of
|
||||||
|
* the queue's lock doesn't throw lockdep warnings.
|
||||||
|
*/
|
||||||
|
skb_queue_head_init_class(&local->rx_skb_queue,
|
||||||
|
&ieee80211_rx_skb_queue_class);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
|
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
|
||||||
|
|
||||||
|
|
|
@ -2230,6 +2230,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
sdata = vif_to_sdata(vif);
|
sdata = vif_to_sdata(vif);
|
||||||
|
|
||||||
|
if (!ieee80211_sdata_running(sdata))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (tim_offset)
|
if (tim_offset)
|
||||||
*tim_offset = 0;
|
*tim_offset = 0;
|
||||||
if (tim_length)
|
if (tim_length)
|
||||||
|
|
Loading…
Add table
Reference in a new issue