diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 65 | ||||
-rw-r--r-- | net/wireless/trace.h | 22 |
3 files changed, 66 insertions, 23 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index 39788711ce6e..d03d8bdb29ca 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -402,6 +402,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
402 | rdev->wiphy.rts_threshold = (u32) -1; | 402 | rdev->wiphy.rts_threshold = (u32) -1; |
403 | rdev->wiphy.coverage_class = 0; | 403 | rdev->wiphy.coverage_class = 0; |
404 | 404 | ||
405 | rdev->wiphy.max_num_csa_counters = 1; | ||
406 | |||
405 | return &rdev->wiphy; | 407 | return &rdev->wiphy; |
406 | } | 408 | } |
407 | EXPORT_SYMBOL(wiphy_new); | 409 | EXPORT_SYMBOL(wiphy_new); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4c0ca40ef90e..ca19b1520389 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -371,8 +371,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
371 | [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, | 371 | [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, |
372 | [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, | 372 | [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, |
373 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, | 373 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, |
374 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, | 374 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY }, |
375 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, | 375 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY }, |
376 | [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, | 376 | [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, |
377 | [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, | 377 | [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, |
378 | [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, | 378 | [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, |
@@ -1670,6 +1670,13 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1670 | } | 1670 | } |
1671 | nla_nest_end(msg, nested); | 1671 | nla_nest_end(msg, nested); |
1672 | } | 1672 | } |
1673 | state->split_start++; | ||
1674 | break; | ||
1675 | case 12: | ||
1676 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH && | ||
1677 | nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS, | ||
1678 | rdev->wiphy.max_num_csa_counters)) | ||
1679 | goto nla_put_failure; | ||
1673 | 1680 | ||
1674 | /* done */ | 1681 | /* done */ |
1675 | state->split_start = 0; | 1682 | state->split_start = 0; |
@@ -5864,6 +5871,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5864 | u8 radar_detect_width = 0; | 5871 | u8 radar_detect_width = 0; |
5865 | int err; | 5872 | int err; |
5866 | bool need_new_beacon = false; | 5873 | bool need_new_beacon = false; |
5874 | int len, i; | ||
5867 | 5875 | ||
5868 | if (!rdev->ops->channel_switch || | 5876 | if (!rdev->ops->channel_switch || |
5869 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | 5877 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) |
@@ -5922,26 +5930,55 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5922 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) | 5930 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) |
5923 | return -EINVAL; | 5931 | return -EINVAL; |
5924 | 5932 | ||
5925 | params.counter_offset_beacon = | 5933 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); |
5926 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | 5934 | if (!len || (len % sizeof(u16))) |
5927 | if (params.counter_offset_beacon >= params.beacon_csa.tail_len) | ||
5928 | return -EINVAL; | 5935 | return -EINVAL; |
5929 | 5936 | ||
5930 | /* sanity check - counters should be the same */ | 5937 | params.n_counter_offsets_beacon = len / sizeof(u16); |
5931 | if (params.beacon_csa.tail[params.counter_offset_beacon] != | 5938 | if (rdev->wiphy.max_num_csa_counters && |
5932 | params.count) | 5939 | (params.n_counter_offsets_beacon > |
5940 | rdev->wiphy.max_num_csa_counters)) | ||
5933 | return -EINVAL; | 5941 | return -EINVAL; |
5934 | 5942 | ||
5943 | params.counter_offsets_beacon = | ||
5944 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | ||
5945 | |||
5946 | /* sanity checks - counters should fit and be the same */ | ||
5947 | for (i = 0; i < params.n_counter_offsets_beacon; i++) { | ||
5948 | u16 offset = params.counter_offsets_beacon[i]; | ||
5949 | |||
5950 | if (offset >= params.beacon_csa.tail_len) | ||
5951 | return -EINVAL; | ||
5952 | |||
5953 | if (params.beacon_csa.tail[offset] != params.count) | ||
5954 | return -EINVAL; | ||
5955 | } | ||
5956 | |||
5935 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { | 5957 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { |
5936 | params.counter_offset_presp = | 5958 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); |
5937 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | 5959 | if (!len || (len % sizeof(u16))) |
5938 | if (params.counter_offset_presp >= | ||
5939 | params.beacon_csa.probe_resp_len) | ||
5940 | return -EINVAL; | 5960 | return -EINVAL; |
5941 | 5961 | ||
5942 | if (params.beacon_csa.probe_resp[params.counter_offset_presp] != | 5962 | params.n_counter_offsets_presp = len / sizeof(u16); |
5943 | params.count) | 5963 | if (rdev->wiphy.max_num_csa_counters && |
5964 | (params.n_counter_offsets_beacon > | ||
5965 | rdev->wiphy.max_num_csa_counters)) | ||
5944 | return -EINVAL; | 5966 | return -EINVAL; |
5967 | |||
5968 | params.counter_offsets_presp = | ||
5969 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | ||
5970 | |||
5971 | /* sanity checks - counters should fit and be the same */ | ||
5972 | for (i = 0; i < params.n_counter_offsets_presp; i++) { | ||
5973 | u16 offset = params.counter_offsets_presp[i]; | ||
5974 | |||
5975 | if (offset >= params.beacon_csa.probe_resp_len) | ||
5976 | return -EINVAL; | ||
5977 | |||
5978 | if (params.beacon_csa.probe_resp[offset] != | ||
5979 | params.count) | ||
5980 | return -EINVAL; | ||
5981 | } | ||
5945 | } | 5982 | } |
5946 | 5983 | ||
5947 | skip_beacons: | 5984 | skip_beacons: |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index cdfbb00e1b37..560ed77084e9 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1876,29 +1876,33 @@ TRACE_EVENT(rdev_channel_switch, | |||
1876 | WIPHY_ENTRY | 1876 | WIPHY_ENTRY |
1877 | NETDEV_ENTRY | 1877 | NETDEV_ENTRY |
1878 | CHAN_DEF_ENTRY | 1878 | CHAN_DEF_ENTRY |
1879 | __field(u16, counter_offset_beacon) | ||
1880 | __field(u16, counter_offset_presp) | ||
1881 | __field(bool, radar_required) | 1879 | __field(bool, radar_required) |
1882 | __field(bool, block_tx) | 1880 | __field(bool, block_tx) |
1883 | __field(u8, count) | 1881 | __field(u8, count) |
1882 | __dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon) | ||
1883 | __dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp) | ||
1884 | ), | 1884 | ), |
1885 | TP_fast_assign( | 1885 | TP_fast_assign( |
1886 | WIPHY_ASSIGN; | 1886 | WIPHY_ASSIGN; |
1887 | NETDEV_ASSIGN; | 1887 | NETDEV_ASSIGN; |
1888 | CHAN_DEF_ASSIGN(¶ms->chandef); | 1888 | CHAN_DEF_ASSIGN(¶ms->chandef); |
1889 | __entry->counter_offset_beacon = params->counter_offset_beacon; | ||
1890 | __entry->counter_offset_presp = params->counter_offset_presp; | ||
1891 | __entry->radar_required = params->radar_required; | 1889 | __entry->radar_required = params->radar_required; |
1892 | __entry->block_tx = params->block_tx; | 1890 | __entry->block_tx = params->block_tx; |
1893 | __entry->count = params->count; | 1891 | __entry->count = params->count; |
1892 | memcpy(__get_dynamic_array(bcn_ofs), | ||
1893 | params->counter_offsets_beacon, | ||
1894 | params->n_counter_offsets_beacon * sizeof(u16)); | ||
1895 | |||
1896 | /* probe response offsets are optional */ | ||
1897 | if (params->n_counter_offsets_presp) | ||
1898 | memcpy(__get_dynamic_array(pres_ofs), | ||
1899 | params->counter_offsets_presp, | ||
1900 | params->n_counter_offsets_presp * sizeof(u16)); | ||
1894 | ), | 1901 | ), |
1895 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT | 1902 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT |
1896 | ", block_tx: %d, count: %u, radar_required: %d" | 1903 | ", block_tx: %d, count: %u, radar_required: %d", |
1897 | ", counter offsets (beacon/presp): %u/%u", | ||
1898 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, | 1904 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, |
1899 | __entry->block_tx, __entry->count, __entry->radar_required, | 1905 | __entry->block_tx, __entry->count, __entry->radar_required) |
1900 | __entry->counter_offset_beacon, | ||
1901 | __entry->counter_offset_presp) | ||
1902 | ); | 1906 | ); |
1903 | 1907 | ||
1904 | TRACE_EVENT(rdev_set_qos_map, | 1908 | TRACE_EVENT(rdev_set_qos_map, |