Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 368428
b: refs/heads/master
c: 55d942f
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg committed Mar 6, 2013
1 parent b91b452 commit 7c83db9
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c07270b605f49039327c35224e27d1d3e802f8a4
refs/heads/master: 55d942f4246c79a8f3f17f92c224e641c5c26125
3 changes: 2 additions & 1 deletion trunk/include/linux/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1333,10 +1333,11 @@ struct ieee80211_vht_operation {
#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700
#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000
#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
Expand Down
5 changes: 2 additions & 3 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1228,9 +1228,8 @@ enum ieee80211_sta_rx_bandwidth {
* @addr: MAC address
* @aid: AID we assigned to the station if we're an AP
* @supp_rates: Bitmap of supported rates (per band)
* @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities
* @vht_cap: VHT capabilities of this STA; Not restricting any capabilities
* of remote STA. Taking as is.
* @ht_cap: HT capabilities of this STA; restricted to our own capabilities
* @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
* @wme: indicates whether the STA supports WME. Only valid during AP-mode.
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *), size is determined in hw information.
Expand Down
114 changes: 113 additions & 1 deletion trunk/net/mac80211/vht.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta)
{
struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
struct ieee80211_sta_vht_cap own_cap;
u32 cap_info, i;

memset(vht_cap, 0, sizeof(*vht_cap));

Expand All @@ -133,12 +135,122 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,

vht_cap->vht_supported = true;

vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info);
own_cap = sband->vht_cap;
/*
* If user has specified capability overrides, take care
* of that if the station we're setting up is the AP that
* we advertised a restricted capability set to. Override
* our own capabilities and then use those below.
*/
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
!test_sta_flag(sta, WLAN_STA_TDLS_PEER))
ieee80211_apply_vhtcap_overrides(sdata, &own_cap);

/* take some capabilities as-is */
cap_info = le32_to_cpu(vht_cap_ie->vht_cap_info);
vht_cap->cap = cap_info;
vht_cap->cap &= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
IEEE80211_VHT_CAP_RXLDPC |
IEEE80211_VHT_CAP_VHT_TXOP_PS |
IEEE80211_VHT_CAP_HTC_VHT |
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB |
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB |
IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;

/* and some based on our own capabilities */
switch (own_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
vht_cap->cap |= cap_info &
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
break;
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
vht_cap->cap |= cap_info &
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
break;
default:
/* nothing */
break;
}

/* symmetric capabilities */
vht_cap->cap |= cap_info & own_cap.cap &
(IEEE80211_VHT_CAP_SHORT_GI_80 |
IEEE80211_VHT_CAP_SHORT_GI_160);

/* remaining ones */
if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {
vht_cap->cap |= cap_info &
(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX |
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX);
}

if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
vht_cap->cap |= cap_info &
IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;

if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
vht_cap->cap |= cap_info &
IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;

if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
vht_cap->cap |= cap_info &
IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;

if (own_cap.cap & IEEE80211_VHT_CAP_TXSTBC)
vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_RXSTBC_MASK;

if (own_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_TXSTBC;

/* Copy peer MCS info, the driver might need them. */
memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs,
sizeof(struct ieee80211_vht_mcs_info));

/* but also restrict MCSes */
for (i = 0; i < 8; i++) {
u16 own_rx, own_tx, peer_rx, peer_tx;

own_rx = le16_to_cpu(own_cap.vht_mcs.rx_mcs_map);
own_rx = (own_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;

own_tx = le16_to_cpu(own_cap.vht_mcs.tx_mcs_map);
own_tx = (own_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;

peer_rx = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
peer_rx = (peer_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;

peer_tx = le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
peer_tx = (peer_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;

if (peer_tx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
if (own_rx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
peer_tx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
else if (own_rx < peer_tx)
peer_tx = own_rx;
}

if (peer_rx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
if (own_tx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
peer_rx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
else if (own_tx < peer_rx)
peer_rx = own_tx;
}

vht_cap->vht_mcs.rx_mcs_map &=
~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
vht_cap->vht_mcs.rx_mcs_map |= cpu_to_le16(peer_rx << i * 2);

vht_cap->vht_mcs.tx_mcs_map &=
~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
vht_cap->vht_mcs.tx_mcs_map |= cpu_to_le16(peer_tx << i * 2);
}

/* finally set up the bandwidth */
switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
Expand Down

0 comments on commit 7c83db9

Please sign in to comment.