Commit 9d4990a2 authored by John W. Linville's avatar John W. Linville

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
parents 64f0a836 2504a642
...@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = { ...@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */ /* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) }, { USB_DEVICE(0x413c, 0x8197) },
{ } /* Terminating entry */ { } /* Terminating entry */
...@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb) ...@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb)
usb_fill_bulk_urb(urb, data->udev, pipe, usb_fill_bulk_urb(urb, data->udev, pipe,
skb->data, skb->len, btusb_tx_complete, skb); skb->data, skb->len, btusb_tx_complete, skb);
if (skb->priority >= HCI_PRIO_MAX - 1)
urb->transfer_flags = URB_ISO_ASAP;
hdev->stat.acl_tx++; hdev->stat.acl_tx++;
break; break;
......
...@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, ...@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
fc = hdr->frame_control; fc = hdr->frame_control;
for (i = 0; i < sc->hw->max_rates; i++) { for (i = 0; i < sc->hw->max_rates; i++) {
struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
if (!rate->count) if (rate->idx < 0 || !rate->count)
break; break;
final_ts_idx = i; final_ts_idx = i;
......
...@@ -841,7 +841,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -841,7 +841,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
ret = mwifiex_set_rf_channel(priv, channel, ret = mwifiex_set_rf_channel(priv, channel,
priv->adapter->channel_type); priv->adapter->channel_type);
ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ /* As this is new association, clear locally stored
* keys and security related flags */
priv->sec_info.wpa_enabled = false;
priv->sec_info.wpa2_enabled = false;
priv->wep_key_curr_index = 0;
ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
if (mode == NL80211_IFTYPE_ADHOC) { if (mode == NL80211_IFTYPE_ADHOC) {
/* "privacy" is set only for ad-hoc mode */ /* "privacy" is set only for ad-hoc mode */
...@@ -886,6 +891,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -886,6 +891,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
dev_dbg(priv->adapter->dev, dev_dbg(priv->adapter->dev,
"info: setting wep encryption" "info: setting wep encryption"
" with key len %d\n", sme->key_len); " with key len %d\n", sme->key_len);
priv->wep_key_curr_index = sme->key_idx;
ret = mwifiex_set_encode(priv, sme->key, sme->key_len, ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
sme->key_idx, 0); sme->key_idx, 0);
} }
......
...@@ -256,4 +256,6 @@ void l2cap_exit(void); ...@@ -256,4 +256,6 @@ void l2cap_exit(void);
int sco_init(void); int sco_init(void);
void sco_exit(void); void sco_exit(void);
void bt_sock_reclassify_lock(struct sock *sk, int proto);
#endif /* __BLUETOOTH_H */ #endif /* __BLUETOOTH_H */
...@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn); ...@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn);
static inline void hci_conn_hold(struct hci_conn *conn) static inline void hci_conn_hold(struct hci_conn *conn)
{ {
atomic_inc(&conn->refcnt); atomic_inc(&conn->refcnt);
cancel_delayed_work_sync(&conn->disc_work); cancel_delayed_work(&conn->disc_work);
} }
static inline void hci_conn_put(struct hci_conn *conn) static inline void hci_conn_put(struct hci_conn *conn)
...@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn) ...@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
} else { } else {
timeo = msecs_to_jiffies(10); timeo = msecs_to_jiffies(10);
} }
cancel_delayed_work_sync(&conn->disc_work); cancel_delayed_work(&conn->disc_work);
queue_delayed_work(conn->hdev->workqueue, queue_delayed_work(conn->hdev->workqueue,
&conn->disc_work, jiffies + timeo); &conn->disc_work, timeo);
} }
} }
......
...@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan, ...@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
{ {
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
if (!__cancel_delayed_work(work)) if (!cancel_delayed_work(work))
l2cap_chan_hold(chan); l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout); schedule_delayed_work(work, timeout);
} }
...@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan, ...@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
static inline void l2cap_clear_timer(struct l2cap_chan *chan, static inline void l2cap_clear_timer(struct l2cap_chan *chan,
struct delayed_work *work) struct delayed_work *work)
{ {
if (__cancel_delayed_work(work)) if (cancel_delayed_work(work))
l2cap_chan_put(chan); l2cap_chan_put(chan);
} }
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
L2CAP_DEFAULT_RETRANS_TO); msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
L2CAP_DEFAULT_MONITOR_TO); msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
L2CAP_DEFAULT_ACK_TO); msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
...@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); ...@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(struct sock *sk); struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void l2cap_chan_close(struct l2cap_chan *chan, int reason); void l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan); void l2cap_chan_destroy(struct l2cap_chan *chan);
inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst); bdaddr_t *dst);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
u32 priority); u32 priority);
......
...@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = { ...@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
"slock-AF_BLUETOOTH-BTPROTO_AVDTP", "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
}; };
static inline void bt_sock_reclassify_lock(struct socket *sock, int proto) void bt_sock_reclassify_lock(struct sock *sk, int proto)
{ {
struct sock *sk = sock->sk; BUG_ON(!sk);
if (!sk)
return;
BUG_ON(sock_owned_by_user(sk)); BUG_ON(sock_owned_by_user(sk));
sock_lock_init_class_and_name(sk, sock_lock_init_class_and_name(sk,
bt_slock_key_strings[proto], &bt_slock_key[proto], bt_slock_key_strings[proto], &bt_slock_key[proto],
bt_key_strings[proto], &bt_lock_key[proto]); bt_key_strings[proto], &bt_lock_key[proto]);
} }
EXPORT_SYMBOL(bt_sock_reclassify_lock);
int bt_sock_register(int proto, const struct net_proto_family *ops) int bt_sock_register(int proto, const struct net_proto_family *ops)
{ {
...@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto, ...@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto,
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(net, sock, proto, kern); err = bt_proto[proto]->create(net, sock, proto, kern);
bt_sock_reclassify_lock(sock, proto); if (!err)
bt_sock_reclassify_lock(sock->sk, proto);
module_put(bt_proto[proto]->owner); module_put(bt_proto[proto]->owner);
} }
......
...@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) ...@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp; struct hci_cp_auth_requested cp;
/* encrypt must be pending if auth is also pending */
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
cp.handle = cpu_to_le16(conn->handle); cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp); sizeof(cp), &cp);
......
...@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */ /* Reset device */
skb_queue_purge(&hdev->cmd_q); skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
if (!test_bit(HCI_RAW, &hdev->flags)) { if (!test_bit(HCI_RAW, &hdev->flags) &&
test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags); set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0, __hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(250)); msecs_to_jiffies(250));
......
...@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) ...@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
hci_chan_del(conn->hchan); hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
__cancel_delayed_work(&conn->info_timer); cancel_delayed_work_sync(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
__cancel_delayed_work(&conn->security_timer); cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn); smp_chan_destroy(conn);
} }
...@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr ...@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
return c1; return c1;
} }
inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst) int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
{ {
struct sock *sk = chan->sk; struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src; bdaddr_t *src = &bt_sk(sk)->src;
...@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd ...@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) { cmd->ident == conn->info_ident) {
__cancel_delayed_work(&conn->info_timer); cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0; conn->info_ident = 0;
...@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr ...@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default: default:
sk->sk_err = ECONNRESET; sk->sk_err = ECONNRESET;
__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); __set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
l2cap_send_disconn_req(conn, chan, ECONNRESET); l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done; goto done;
} }
...@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm ...@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0; return 0;
__cancel_delayed_work(&conn->info_timer); cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) { if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
...@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) ...@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
if (encrypt == 0x00) { if (encrypt == 0x00) {
if (chan->sec_level == BT_SECURITY_MEDIUM) { if (chan->sec_level == BT_SECURITY_MEDIUM) {
__clear_chan_timer(chan); __clear_chan_timer(chan);
__set_chan_timer(chan, L2CAP_ENC_TIMEOUT); __set_chan_timer(chan,
msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
} else if (chan->sec_level == BT_SECURITY_HIGH) } else if (chan->sec_level == BT_SECURITY_HIGH)
l2cap_chan_close(chan, ECONNREFUSED); l2cap_chan_close(chan, ECONNREFUSED);
} else { } else {
...@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) ...@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) { if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0); smp_distribute_keys(conn, 0);
__cancel_delayed_work(&conn->security_timer); cancel_delayed_work(&conn->security_timer);
} }
rcu_read_lock(); rcu_read_lock();
...@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) ...@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
L2CAP_CONN_REQ, sizeof(req), &req); L2CAP_CONN_REQ, sizeof(req), &req);
} else { } else {
__clear_chan_timer(chan); __clear_chan_timer(chan);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT); __set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
} }
} else if (chan->state == BT_CONNECT2) { } else if (chan->state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp; struct l2cap_conn_rsp rsp;
...@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) ...@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
} }
} else { } else {
l2cap_state_change(chan, BT_DISCONN); l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT); __set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
res = L2CAP_CR_SEC_BLOCK; res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO; stat = L2CAP_CS_NO_INFO;
} }
......
...@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) ...@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
if (!sk) if (!sk)
return NULL; return NULL;
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
l2cap_sock_init(sk, parent); l2cap_sock_init(sk, parent);
return l2cap_pi(sk)->chan; return l2cap_pi(sk)->chan;
...@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p ...@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct; sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sock_reset_flag(sk, SOCK_ZAPPED); sock_reset_flag(sk, SOCK_ZAPPED);
......
...@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) ...@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
break; break;
case BT_DISCONN: case BT_DISCONN:
/* When socket is closed and we are not RFCOMM /* rfcomm_session_put is called later so don't do
* initiator rfcomm_process_rx already calls * anything here otherwise we will mess up the session
* rfcomm_session_put() */ * reference counter:
if (s->sock->sk->sk_state != BT_CLOSED) *
if (list_empty(&s->dlcs)) * (a) when we are the initiator dlc_unlink will drive
rfcomm_session_put(s); * the reference counter to 0 (there is no initial put
* after session_add)
*
* (b) when we are not the initiator rfcomm_rx_process
* will explicitly call put to balance the initial hold
* done after session add.
*/
break; break;
} }
} }
......
...@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * ...@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if (!sk) if (!sk)
goto done; goto done;
bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
rfcomm_sock_init(sk, parent); rfcomm_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, &src); bacpy(&bt_sk(sk)->src, &src);
bacpy(&bt_sk(sk)->dst, &dst); bacpy(&bt_sk(sk)->dst, &dst);
......
...@@ -63,14 +63,14 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, ...@@ -63,14 +63,14 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
int res = scnprintf(buf, sizeof(buf), int res = scnprintf(buf, sizeof(buf),
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
TEST(AUTH), TEST(ASSOC), TEST(PS_STA), TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
TEST(PS_DRIVER), TEST(AUTHORIZED), TEST(PS_DRIVER), TEST(AUTHORIZED),
TEST(SHORT_PREAMBLE), TEST(SHORT_PREAMBLE),
TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
TEST(TDLS_PEER_AUTH)); TEST(TDLS_PEER_AUTH), TEST(RATE_CONTROL));
#undef TEST #undef TEST
return simple_read_from_buffer(userbuf, count, ppos, buf, res); return simple_read_from_buffer(userbuf, count, ppos, buf, res);
} }
......
...@@ -336,7 +336,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, ...@@ -336,7 +336,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
int i; int i;
u32 mask; u32 mask;
if (sta) { if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
ista = &sta->sta; ista = &sta->sta;
priv_sta = sta->rate_ctrl_priv; priv_sta = sta->rate_ctrl_priv;
} }
......
...@@ -41,7 +41,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local, ...@@ -41,7 +41,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_sta *ista = &sta->sta; struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv; void *priv_sta = sta->rate_ctrl_priv;
if (!ref) if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
return; return;
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
...@@ -62,6 +62,7 @@ static inline void rate_control_rate_init(struct sta_info *sta) ...@@ -62,6 +62,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
ref->ops->rate_init(ref->priv, sband, ista, priv_sta); ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
} }
static inline void rate_control_rate_update(struct ieee80211_local *local, static inline void rate_control_rate_update(struct ieee80211_local *local,
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
* @WLAN_STA_SP: Station is in a service period, so don't try to * @WLAN_STA_SP: Station is in a service period, so don't try to
* reply to other uAPSD trigger frames or PS-Poll. * reply to other uAPSD trigger frames or PS-Poll.
* @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame. * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
* @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
*/ */
enum ieee80211_sta_info_flags { enum ieee80211_sta_info_flags {
WLAN_STA_AUTH, WLAN_STA_AUTH,
...@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags { ...@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_UAPSD, WLAN_STA_UAPSD,
WLAN_STA_SP, WLAN_STA_SP,
WLAN_STA_4ADDR_EVENT, WLAN_STA_4ADDR_EVENT,
WLAN_STA_RATE_CONTROL,
}; };
enum ieee80211_sta_state { enum ieee80211_sta_state {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment