Merge branch 'master' of ssh://ra.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem

This commit is contained in:
John W. Linville 2011-11-09 13:41:11 -05:00
commit e29ec62470
15 changed files with 95 additions and 29 deletions

View File

@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {
/* Canyon CN-BTU1 with HID interfaces */ /* Canyon CN-BTU1 with HID interfaces */
{ USB_DEVICE(0x0c10, 0x0000) }, { USB_DEVICE(0x0c10, 0x0000) },
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x413c, 0x8197) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };

View File

@ -253,6 +253,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
int r; int r;
sband = wiphy->bands[IEEE80211_BAND_2GHZ]; sband = wiphy->bands[IEEE80211_BAND_2GHZ];
if (!sband)
return;
/* /*
* If no country IE has been received always enable active scan * If no country IE has been received always enable active scan

View File

@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
} }
} }
/* TODO: verify if needed for SSLPN or LCN */
static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
{ {
const struct b43_phy *phy = &dev->phy; const struct b43_phy *phy = &dev->phy;
@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
unsigned int plcp_fragment_len; unsigned int plcp_fragment_len;
u32 mac_ctl = 0; u32 mac_ctl = 0;
u16 phy_ctl = 0; u16 phy_ctl = 0;
bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
phy->type == B43_PHYTYPE_N ||
phy->type == B43_PHYTYPE_HT);
u8 extra_ft = 0; u8 extra_ft = 0;
struct ieee80211_rate *txrate; struct ieee80211_rate *txrate;
struct ieee80211_tx_rate *rates; struct ieee80211_tx_rate *rates;
@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
extra_ft |= B43_TXH_EFT_RTSFB_CCK; extra_ft |= B43_TXH_EFT_RTSFB_CCK;
if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
phy->type == B43_PHYTYPE_N) { fill_phy_ctl1) {
txhdr->phy_ctl1_rts = cpu_to_le16( txhdr->phy_ctl1_rts = cpu_to_le16(
b43_generate_tx_phy_ctl1(dev, rts_rate)); b43_generate_tx_phy_ctl1(dev, rts_rate));
txhdr->phy_ctl1_rts_fb = cpu_to_le16( txhdr->phy_ctl1_rts_fb = cpu_to_le16(
@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
break; break;
} }
if (phy->type == B43_PHYTYPE_N) { if (fill_phy_ctl1) {
txhdr->phy_ctl1 = txhdr->phy_ctl1 =
cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
txhdr->phy_ctl1_fb = txhdr->phy_ctl1_fb =
@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
/* Link quality statistics */ /* Link quality statistics */
switch (chanstat & B43_RX_CHAN_PHYTYPE) { switch (chanstat & B43_RX_CHAN_PHYTYPE) {
case B43_PHYTYPE_HT:
/* TODO: is max the right choice? */
status.signal = max_t(__s8,
max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
rxhdr->phy_ht_power2);
break;
case B43_PHYTYPE_N: case B43_PHYTYPE_N:
/* Broadcom has code for min and avg, but always uses max */
if (rxhdr->power0 == 16 || rxhdr->power0 == 32) if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
status.signal = max(rxhdr->power1, rxhdr->power2); status.signal = max(rxhdr->power1, rxhdr->power2);
else else

View File

@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {
} __packed; } __packed;
} __packed; } __packed;
union { union {
/* HT-PHY */
struct {
PAD_BYTES(1);
__s8 phy_ht_power0;
} __packed;
/* RSSI for N-PHYs */ /* RSSI for N-PHYs */
struct { struct {
__s8 power2; __s8 power2;
@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {
__le16 phy_status2; /* PHY RX Status 2 */ __le16 phy_status2; /* PHY RX Status 2 */
} __packed; } __packed;
__le16 phy_status3; /* PHY RX Status 3 */ union {
/* HT-PHY */
struct {
__s8 phy_ht_power1;
__s8 phy_ht_power2;
} __packed;
__le16 phy_status3; /* PHY RX Status 3 */
} __packed;
union { union {
/* Tested with 598.314, 644.1001 and 666.2 */ /* Tested with 598.314, 644.1001 and 666.2 */
struct { struct {

View File

@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
{ {
uint dmactrlflags = di->dma.dmactrlflags; uint dmactrlflags;
if (di == NULL) { if (di == NULL) {
DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
return 0; return 0;
} }
dmactrlflags = di->dma.dmactrlflags;
dmactrlflags &= ~mask; dmactrlflags &= ~mask;
dmactrlflags |= flags; dmactrlflags |= flags;

View File

@ -1469,7 +1469,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
s32 rssi, const u8 *ie_buf, size_t ie_len, s32 rssi, const u8 *ie_buf, size_t ie_len,
u16 beacon_period, u16 cap_info_bitmap, u8 band) u16 beacon_period, u16 cap_info_bitmap, u8 band)
{ {
struct mwifiex_bssdescriptor *bss_desc = NULL; struct mwifiex_bssdescriptor *bss_desc;
int ret; int ret;
unsigned long flags; unsigned long flags;
u8 *beacon_ie; u8 *beacon_ie;
@ -1484,6 +1484,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
if (!beacon_ie) { if (!beacon_ie) {
kfree(bss_desc);
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
return -ENOMEM; return -ENOMEM;
} }

View File

@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
break; break;
} }
/* Fail if SSID isn't present in the filters */ /* Fail if SSID isn't present in the filters */
if (j == req->n_ssids) { if (j == cmd->n_ssids) {
ret = -EINVAL; ret = -EINVAL;
goto out_free; goto out_free;
} }

View File

@ -39,8 +39,11 @@
#define L2CAP_DEFAULT_ACK_TO 200 #define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LE_DEFAULT_MTU 23 #define L2CAP_LE_DEFAULT_MTU 23
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ #define L2CAP_DISC_TIMEOUT (100)
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ #define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */
#define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
/* L2CAP socket address */ /* L2CAP socket address */
struct sockaddr_l2 { struct sockaddr_l2 {

View File

@ -456,6 +456,9 @@ enum station_parameters_apply_mask {
* as the AC bitmap in the QoS info field * as the AC bitmap in the QoS info field
* @max_sp: max Service Period. same format as the MAX_SP in the * @max_sp: max Service Period. same format as the MAX_SP in the
* QoS info field (but already shifted down) * QoS info field (but already shifted down)
* @sta_modify_mask: bitmap indicating which parameters changed
* (for those that don't have a natural "no change" value),
* see &enum station_parameters_apply_mask
*/ */
struct station_parameters { struct station_parameters {
u8 *supported_rates; u8 *supported_rates;
@ -615,6 +618,7 @@ struct sta_bss_parameters {
* user space MLME/SME implementation. The information is provided for * user space MLME/SME implementation. The information is provided for
* the cfg80211_new_sta() calls to notify user space of the IEs. * the cfg80211_new_sta() calls to notify user space of the IEs.
* @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
* @sta_flags: station flags mask & values
*/ */
struct station_info { struct station_info {
u32 filled; u32 filled;

View File

@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
goto encrypt; goto encrypt;
auth: auth:
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0; return 0;
if (!hci_conn_auth(conn, sec_level, auth_type)) if (!hci_conn_auth(conn, sec_level, auth_type))

View File

@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg)
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
/* sk is owned by user. Try again later */ /* sk is owned by user. Try again later */
__set_chan_timer(chan, HZ / 5); __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
bh_unlock_sock(sk); bh_unlock_sock(sk);
chan_put(chan); chan_put(chan);
return; return;
@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
l2cap_state_change(chan, BT_DISCONN); l2cap_state_change(chan, BT_DISCONN);
__clear_chan_timer(chan); __clear_chan_timer(chan);
__set_chan_timer(chan, HZ / 5); __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
break; break;
} }
@ -2661,7 +2661,7 @@ 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, HZ * 5); __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
l2cap_send_disconn_req(conn, chan, ECONNRESET); l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done; goto done;
} }
@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
l2cap_state_change(chan, BT_DISCONN); l2cap_state_change(chan, BT_DISCONN);
__clear_chan_timer(chan); __clear_chan_timer(chan);
__set_chan_timer(chan, HZ / 5); __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
bh_unlock_sock(sk); bh_unlock_sock(sk);
return 0; return 0;
} }
@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
l2cap_state_change(chan,BT_DISCONN); l2cap_state_change(chan,BT_DISCONN);
__clear_chan_timer(chan); __clear_chan_timer(chan);
__set_chan_timer(chan, HZ / 5); __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
bh_unlock_sock(sk); bh_unlock_sock(sk);
return 0; return 0;
} }
@ -3998,7 +3998,7 @@ 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, HZ * 5); __set_chan_timer(chan, 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 {
@ -4066,7 +4066,7 @@ static 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, HZ / 10); __set_chan_timer(chan, 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;
@ -4086,7 +4086,7 @@ static 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, HZ / 10); __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
res = L2CAP_CR_SEC_BLOCK; res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO; stat = L2CAP_CS_NO_INFO;
} }

View File

@ -1485,6 +1485,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
int i, j, err; int i, j, err;
bool have_higher_than_11mbit = false; bool have_higher_than_11mbit = false;
u16 ap_ht_cap_flags; u16 ap_ht_cap_flags;
int min_rate = INT_MAX, min_rate_index = -1;
/* AssocResp and ReassocResp have identical structure */ /* AssocResp and ReassocResp have identical structure */
@ -1551,6 +1552,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rates |= BIT(j); rates |= BIT(j);
if (is_basic) if (is_basic)
basic_rates |= BIT(j); basic_rates |= BIT(j);
if (rate < min_rate) {
min_rate = rate;
min_rate_index = j;
}
break; break;
} }
} }
@ -1568,11 +1573,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rates |= BIT(j); rates |= BIT(j);
if (is_basic) if (is_basic)
basic_rates |= BIT(j); basic_rates |= BIT(j);
if (rate < min_rate) {
min_rate = rate;
min_rate_index = j;
}
break; break;
} }
} }
} }
/*
* some buggy APs don't advertise basic_rates. use the lowest
* supported rate instead.
*/
if (unlikely(!basic_rates) && min_rate_index >= 0) {
printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
"Using min supported rate instead.\n", sdata->name);
basic_rates = BIT(min_rate_index);
}
sta->sta.supp_rates[wk->chan->band] = rates; sta->sta.supp_rates[wk->chan->band] = rates;
sdata->vif.bss_conf.basic_rates = basic_rates; sdata->vif.bss_conf.basic_rates = basic_rates;

View File

@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
* Use MoreData flag to indicate whether there are * Use MoreData flag to indicate whether there are
* more buffered frames for this STA * more buffered frames for this STA
*/ */
if (!more_data) if (more_data || !skb_queue_empty(&frames))
hdr->frame_control &=
cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
else
hdr->frame_control |= hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_MOREDATA); cpu_to_le16(IEEE80211_FCTL_MOREDATA);
else
hdr->frame_control &=
cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
if (ieee80211_is_data_qos(hdr->frame_control) || if (ieee80211_is_data_qos(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control)) ieee80211_is_qos_nullfunc(hdr->frame_control))

View File

@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
.len = NL80211_HT_CAPABILITY_LEN },
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
[NL80211_ATTR_IE] = { .type = NLA_BINARY, [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res; goto bad_res;
} }
if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
result = -EINVAL;
goto bad_res;
}
nla_for_each_nested(nl_txq_params, nla_for_each_nested(nl_txq_params,
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
rem_txq_params) { rem_txq_params) {

View File

@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
{ {
const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
int r;
/* equal if both missing */
if (!ie1 && !ie2) if (!ie1 && !ie2)
return 0; return 0;
if (!ie1 || !ie2) /* sort missing IE before (left of) present IE */
if (!ie1)
return -1; return -1;
if (!ie2)
return 1;
r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); /* sort by length first, then by contents */
if (r == 0 && ie1[1] != ie2[1]) if (ie1[1] != ie2[1])
return ie2[1] - ie1[1]; return ie2[1] - ie1[1];
return r; return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
} }
static bool is_bss(struct cfg80211_bss *a, static bool is_bss(struct cfg80211_bss *a,