提交 5e58e528 编写于 作者: D David S. Miller
...@@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = { ...@@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = {
/* Apple MacBookAir3,1, MacBookAir3,2 */ /* Apple MacBookAir3,1, MacBookAir3,2 */
{ USB_DEVICE(0x05ac, 0x821b) }, { USB_DEVICE(0x05ac, 0x821b) },
/* Apple MacBookPro8,2 */
{ USB_DEVICE(0x05ac, 0x821a) },
/* AVM BlueFRITZ! USB v2.0 */ /* AVM BlueFRITZ! USB v2.0 */
{ USB_DEVICE(0x057c, 0x3800) }, { USB_DEVICE(0x057c, 0x3800) },
...@@ -690,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb) ...@@ -690,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb)
break; break;
case HCI_ACLDATA_PKT: case HCI_ACLDATA_PKT:
if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1) if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 &&
hdev->conn_hash.le_num < 1))
return -ENODEV; return -ENODEV;
urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC);
......
...@@ -1048,6 +1048,8 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -1048,6 +1048,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
"Starting driver with initial channel: %d MHz\n", "Starting driver with initial channel: %d MHz\n",
curchan->center_freq); curchan->center_freq);
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
/* setup initial channel */ /* setup initial channel */
...@@ -1143,6 +1145,8 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -1143,6 +1145,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
mutex_unlock: mutex_unlock:
mutex_unlock(&sc->mutex); mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
return r; return r;
} }
......
...@@ -443,6 +443,7 @@ struct carl9170_ba_stats { ...@@ -443,6 +443,7 @@ struct carl9170_ba_stats {
u8 ampdu_len; u8 ampdu_len;
u8 ampdu_ack_len; u8 ampdu_ack_len;
bool clear; bool clear;
bool req;
}; };
struct carl9170_sta_info { struct carl9170_sta_info {
......
...@@ -1355,6 +1355,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, ...@@ -1355,6 +1355,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
tid_info = rcu_dereference(sta_info->agg[tid]); tid_info = rcu_dereference(sta_info->agg[tid]);
sta_info->stats[tid].clear = true; sta_info->stats[tid].clear = true;
sta_info->stats[tid].req = false;
if (tid_info) { if (tid_info) {
bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE);
......
...@@ -383,6 +383,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, ...@@ -383,6 +383,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
if (sta_info->stats[tid].clear) { if (sta_info->stats[tid].clear) {
sta_info->stats[tid].clear = false; sta_info->stats[tid].clear = false;
sta_info->stats[tid].req = false;
sta_info->stats[tid].ampdu_len = 0; sta_info->stats[tid].ampdu_len = 0;
sta_info->stats[tid].ampdu_ack_len = 0; sta_info->stats[tid].ampdu_ack_len = 0;
} }
...@@ -391,10 +392,16 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, ...@@ -391,10 +392,16 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
if (txinfo->status.rates[0].count == 1) if (txinfo->status.rates[0].count == 1)
sta_info->stats[tid].ampdu_ack_len++; sta_info->stats[tid].ampdu_ack_len++;
if (!(txinfo->flags & IEEE80211_TX_STAT_ACK))
sta_info->stats[tid].req = true;
if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
super->s.rix = sta_info->stats[tid].ampdu_len; super->s.rix = sta_info->stats[tid].ampdu_len;
super->s.cnt = sta_info->stats[tid].ampdu_ack_len; super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
txinfo->flags |= IEEE80211_TX_STAT_AMPDU; txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
if (sta_info->stats[tid].req)
txinfo->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
sta_info->stats[tid].clear = true; sta_info->stats[tid].clear = true;
} }
spin_unlock_bh(&tid_info->lock); spin_unlock_bh(&tid_info->lock);
......
...@@ -1805,6 +1805,15 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, ...@@ -1805,6 +1805,15 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (!ctx->vif || !iwl_legacy_is_ready_rf(priv)) {
/*
* Huh? But wait ... this can maybe happen when
* we're in the middle of a firmware restart!
*/
err = -EBUSY;
goto out;
}
interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
if (!(interface_modes & BIT(newtype))) { if (!(interface_modes & BIT(newtype))) {
...@@ -1832,6 +1841,7 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, ...@@ -1832,6 +1841,7 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw,
/* success */ /* success */
iwl_legacy_teardown_interface(priv, vif, true); iwl_legacy_teardown_interface(priv, vif, true);
vif->type = newtype; vif->type = newtype;
vif->p2p = newp2p;
err = iwl_legacy_setup_interface(priv, ctx); err = iwl_legacy_setup_interface(priv, ctx);
WARN_ON(err); WARN_ON(err);
/* /*
......
...@@ -93,6 +93,7 @@ MODULE_LICENSE("GPL"); ...@@ -93,6 +93,7 @@ MODULE_LICENSE("GPL");
struct iwl_mod_params iwl3945_mod_params = { struct iwl_mod_params iwl3945_mod_params = {
.sw_crypto = 1, .sw_crypto = 1,
.restart_fw = 1, .restart_fw = 1,
.disable_hw_scan = 1,
/* the rest are 0 by default */ /* the rest are 0 by default */
}; };
...@@ -3960,8 +3961,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -3960,8 +3961,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* "the hard way", rather than using device's scan. * "the hard way", rather than using device's scan.
*/ */
if (iwl3945_mod_params.disable_hw_scan) { if (iwl3945_mod_params.disable_hw_scan) {
dev_printk(KERN_DEBUG, &(pdev->dev), IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
"sw scan support is deprecated\n");
iwl3945_hw_ops.hw_scan = NULL; iwl3945_hw_ops.hw_scan = NULL;
} }
...@@ -4280,8 +4280,7 @@ MODULE_PARM_DESC(swcrypto, ...@@ -4280,8 +4280,7 @@ MODULE_PARM_DESC(swcrypto,
"using software crypto (default 1 [software])"); "using software crypto (default 1 [software])");
module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
int, S_IRUGO); int, S_IRUGO);
MODULE_PARM_DESC(disable_hw_scan, MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)");
"disable hardware scanning (default 0) (deprecated)");
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR); module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "debug output mask"); MODULE_PARM_DESC(debug, "debug output mask");
......
...@@ -730,8 +730,12 @@ static struct usb_device_id rt2800usb_device_table[] = { ...@@ -730,8 +730,12 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Buffalo */ /* Buffalo */
{ USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Conceptronic */ /* Conceptronic */
{ USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
...@@ -818,6 +822,7 @@ static struct usb_device_id rt2800usb_device_table[] = { ...@@ -818,6 +822,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Pegatron */ /* Pegatron */
{ USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Philips */ /* Philips */
{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Planex */ /* Planex */
...@@ -899,6 +904,8 @@ static struct usb_device_id rt2800usb_device_table[] = { ...@@ -899,6 +904,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sitecom */ /* Sitecom */
{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Toshiba */
{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zinwell */ /* Zinwell */
{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif #endif
...@@ -961,7 +968,6 @@ static struct usb_device_id rt2800usb_device_table[] = { ...@@ -961,7 +968,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Planex */ /* Planex */
{ USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
...@@ -975,8 +981,6 @@ static struct usb_device_id rt2800usb_device_table[] = { ...@@ -975,8 +981,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Sweex */ /* Sweex */
{ USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Toshiba */
{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zyxel */ /* Zyxel */
{ USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif #endif
......
...@@ -84,6 +84,8 @@ enum { ...@@ -84,6 +84,8 @@ enum {
HCI_SERVICE_CACHE, HCI_SERVICE_CACHE,
HCI_LINK_KEYS, HCI_LINK_KEYS,
HCI_DEBUG_KEYS, HCI_DEBUG_KEYS,
HCI_RESET,
}; };
/* HCI ioctl defines */ /* HCI ioctl defines */
......
...@@ -186,6 +186,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) ...@@ -186,6 +186,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG("%s %ld", hdev->name, opt); BT_DBG("%s %ld", hdev->name, opt);
/* Reset device */ /* Reset device */
set_bit(HCI_RESET, &hdev->flags);
hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
} }
...@@ -213,8 +214,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) ...@@ -213,8 +214,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Mandatory initialization */ /* Mandatory initialization */
/* Reset */ /* Reset */
if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
set_bit(HCI_RESET, &hdev->flags);
hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
}
/* Read Local Supported Features */ /* Read Local Supported Features */
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
...@@ -584,6 +587,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -584,6 +587,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_req_cancel(hdev, ENODEV); hci_req_cancel(hdev, ENODEV);
hci_req_lock(hdev); hci_req_lock(hdev);
/* Stop timer, it might be running */
del_timer_sync(&hdev->cmd_timer);
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
hci_req_unlock(hdev); hci_req_unlock(hdev);
return 0; return 0;
...@@ -623,7 +629,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -623,7 +629,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Drop last sent command */ /* Drop last sent command */
if (hdev->sent_cmd) { if (hdev->sent_cmd) {
del_timer_sync(&hdev->cmd_timer);
kfree_skb(hdev->sent_cmd); kfree_skb(hdev->sent_cmd);
hdev->sent_cmd = NULL; hdev->sent_cmd = NULL;
} }
...@@ -1074,6 +1079,7 @@ static void hci_cmd_timer(unsigned long arg) ...@@ -1074,6 +1079,7 @@ static void hci_cmd_timer(unsigned long arg)
BT_ERR("%s command tx timeout", hdev->name); BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
clear_bit(HCI_RESET, &hdev->flags);
tasklet_schedule(&hdev->cmd_task); tasklet_schedule(&hdev->cmd_task);
} }
......
...@@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status); BT_DBG("%s status 0x%x", hdev->name, status);
clear_bit(HCI_RESET, &hdev->flags);
hci_req_complete(hdev, HCI_OP_RESET, status); hci_req_complete(hdev, HCI_OP_RESET, status);
} }
...@@ -1847,7 +1849,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1847,7 +1849,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (ev->opcode != HCI_OP_NOP) if (ev->opcode != HCI_OP_NOP)
del_timer(&hdev->cmd_timer); del_timer(&hdev->cmd_timer);
if (ev->ncmd) { if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
if (!skb_queue_empty(&hdev->cmd_q)) if (!skb_queue_empty(&hdev->cmd_q))
tasklet_schedule(&hdev->cmd_task); tasklet_schedule(&hdev->cmd_task);
......
...@@ -1116,7 +1116,9 @@ int l2cap_ertm_send(struct sock *sk) ...@@ -1116,7 +1116,9 @@ int l2cap_ertm_send(struct sock *sk)
bt_cb(skb)->tx_seq = pi->next_tx_seq; bt_cb(skb)->tx_seq = pi->next_tx_seq;
pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
pi->unacked_frames++; if (bt_cb(skb)->retries == 1)
pi->unacked_frames++;
pi->frames_sent++; pi->frames_sent++;
if (skb_queue_is_last(TX_QUEUE(sk), skb)) if (skb_queue_is_last(TX_QUEUE(sk), skb))
......
...@@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason) ...@@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp); L2CAP_CONN_RSP, sizeof(rsp), &rsp);
} else }
l2cap_chan_del(sk, reason);
l2cap_chan_del(sk, reason);
break; break;
case BT_CONNECT: case BT_CONNECT:
......
...@@ -1230,6 +1230,8 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, ...@@ -1230,6 +1230,8 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
if (!hdev) if (!hdev)
return cmd_status(sk, index, mgmt_op, ENODEV); return cmd_status(sk, index, mgmt_op, ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) { if (!test_bit(HCI_UP, &hdev->flags)) {
err = cmd_status(sk, index, mgmt_op, ENETDOWN); err = cmd_status(sk, index, mgmt_op, ENETDOWN);
goto failed; goto failed;
......
...@@ -342,7 +342,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, ...@@ -342,7 +342,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
if (IS_ERR(key->u.ccmp.tfm)) { if (IS_ERR(key->u.ccmp.tfm)) {
err = PTR_ERR(key->u.ccmp.tfm); err = PTR_ERR(key->u.ccmp.tfm);
kfree(key); kfree(key);
key = ERR_PTR(err); return ERR_PTR(err);
} }
break; break;
case WLAN_CIPHER_SUITE_AES_CMAC: case WLAN_CIPHER_SUITE_AES_CMAC:
...@@ -360,7 +360,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, ...@@ -360,7 +360,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
if (IS_ERR(key->u.aes_cmac.tfm)) { if (IS_ERR(key->u.aes_cmac.tfm)) {
err = PTR_ERR(key->u.aes_cmac.tfm); err = PTR_ERR(key->u.aes_cmac.tfm);
kfree(key); kfree(key);
key = ERR_PTR(err); return ERR_PTR(err);
} }
break; break;
} }
...@@ -400,11 +400,12 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -400,11 +400,12 @@ int ieee80211_key_link(struct ieee80211_key *key,
{ {
struct ieee80211_key *old_key; struct ieee80211_key *old_key;
int idx, ret; int idx, ret;
bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; bool pairwise;
BUG_ON(!sdata); BUG_ON(!sdata);
BUG_ON(!key); BUG_ON(!key);
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
idx = key->conf.keyidx; idx = key->conf.keyidx;
key->local = sdata->local; key->local = sdata->local;
key->sdata = sdata; key->sdata = sdata;
......
...@@ -659,18 +659,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, ...@@ -659,18 +659,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
struct ieee80211_local *local = hw_to_local(mp->hw); struct ieee80211_local *local = hw_to_local(mp->hw);
u16 sta_cap = sta->ht_cap.cap; u16 sta_cap = sta->ht_cap.cap;
int n_supported = 0;
int ack_dur; int ack_dur;
int stbc; int stbc;
int i; int i;
/* fall back to the old minstrel for legacy stations */ /* fall back to the old minstrel for legacy stations */
if (!sta->ht_cap.ht_supported) { if (!sta->ht_cap.ht_supported)
msp->is_ht = false; goto use_legacy;
memset(&msp->legacy, 0, sizeof(msp->legacy));
msp->legacy.r = msp->ratelist;
msp->legacy.sample_table = msp->sample_table;
return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
}
BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) !=
MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS); MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS);
...@@ -725,7 +721,22 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, ...@@ -725,7 +721,22 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
mi->groups[i].supported = mi->groups[i].supported =
mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
if (mi->groups[i].supported)
n_supported++;
} }
if (!n_supported)
goto use_legacy;
return;
use_legacy:
msp->is_ht = false;
memset(&msp->legacy, 0, sizeof(msp->legacy));
msp->legacy.r = msp->ratelist;
msp->legacy.sample_table = msp->sample_table;
return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
} }
static void static void
......
...@@ -612,7 +612,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, ...@@ -612,7 +612,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
skipped++; skipped++;
continue; continue;
} }
if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + if (skipped &&
!time_after(jiffies, tid_agg_rx->reorder_time[j] +
HT_RX_REORDER_BUF_TIMEOUT)) HT_RX_REORDER_BUF_TIMEOUT))
goto set_release_timer; goto set_release_timer;
......
...@@ -123,6 +123,15 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, ...@@ -123,6 +123,15 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
} }
} }
/* must hold dev->bss_lock! */
static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
struct cfg80211_internal_bss *bss)
{
list_del_init(&bss->list);
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
}
/* must hold dev->bss_lock! */ /* must hold dev->bss_lock! */
void cfg80211_bss_expire(struct cfg80211_registered_device *dev) void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
{ {
...@@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev) ...@@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
continue; continue;
if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
continue; continue;
list_del(&bss->list); __cfg80211_unlink_bss(dev, bss);
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
expired = true; expired = true;
} }
...@@ -585,16 +592,23 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, ...@@ -585,16 +592,23 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
struct cfg80211_internal_bss *res; struct cfg80211_internal_bss *res;
size_t ielen = len - offsetof(struct ieee80211_mgmt, size_t ielen = len - offsetof(struct ieee80211_mgmt,
u.probe_resp.variable); u.probe_resp.variable);
size_t privsz = wiphy->bss_priv_size; size_t privsz;
if (WARN_ON(!mgmt))
return NULL;
if (WARN_ON(!wiphy))
return NULL;
if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
(signal < 0 || signal > 100))) (signal < 0 || signal > 100)))
return NULL; return NULL;
if (WARN_ON(!mgmt || !wiphy || if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
return NULL; return NULL;
privsz = wiphy->bss_priv_size;
res = kzalloc(sizeof(*res) + privsz + ielen, gfp); res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
if (!res) if (!res)
return NULL; return NULL;
...@@ -662,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) ...@@ -662,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
spin_lock_bh(&dev->bss_lock); spin_lock_bh(&dev->bss_lock);
if (!list_empty(&bss->list)) { if (!list_empty(&bss->list)) {
list_del_init(&bss->list); __cfg80211_unlink_bss(dev, bss);
dev->bss_generation++; dev->bss_generation++;
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
} }
spin_unlock_bh(&dev->bss_lock); spin_unlock_bh(&dev->bss_lock);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册