diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-29 12:55:38 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-29 12:55:38 -0400 |
commit | 737be10d8cb783d1cadb1868b061abb2b4314eae (patch) | |
tree | 1b72ea0d454affab6d6cc743939cfb316fad14b3 | |
parent | 03c4444650969431b3a5effde4995de767e3013a (diff) | |
parent | d3a58df87a2e4c2301ac843604202d290a48440b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
-rw-r--r-- | include/linux/ieee80211.h | 1 | ||||
-rw-r--r-- | include/net/mac80211.h | 46 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 6 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 53 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 1 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 1 | ||||
-rw-r--r-- | net/mac80211/status.c | 25 | ||||
-rw-r--r-- | net/mac80211/trace.h | 85 | ||||
-rw-r--r-- | net/wireless/core.c | 5 | ||||
-rw-r--r-- | net/wireless/genregdb.awk | 14 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 21 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 3 |
13 files changed, 234 insertions, 29 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index f194ccb8539c..6bff13f74050 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -1711,6 +1711,7 @@ enum ieee80211_eid { | |||
1711 | WLAN_EID_RRM_ENABLED_CAPABILITIES = 70, | 1711 | WLAN_EID_RRM_ENABLED_CAPABILITIES = 70, |
1712 | WLAN_EID_MULTIPLE_BSSID = 71, | 1712 | WLAN_EID_MULTIPLE_BSSID = 71, |
1713 | WLAN_EID_BSS_COEX_2040 = 72, | 1713 | WLAN_EID_BSS_COEX_2040 = 72, |
1714 | WLAN_EID_BSS_INTOLERANT_CHL_REPORT = 73, | ||
1714 | WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74, | 1715 | WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74, |
1715 | WLAN_EID_RIC_DESCRIPTOR = 75, | 1716 | WLAN_EID_RIC_DESCRIPTOR = 75, |
1716 | WLAN_EID_MMIE = 76, | 1717 | WLAN_EID_MMIE = 76, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2c78997bc48d..421b6ecb4b2c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -189,6 +189,43 @@ struct ieee80211_chanctx_conf { | |||
189 | }; | 189 | }; |
190 | 190 | ||
191 | /** | 191 | /** |
192 | * enum ieee80211_chanctx_switch_mode - channel context switch mode | ||
193 | * @CHANCTX_SWMODE_REASSIGN_VIF: Both old and new contexts already | ||
194 | * exist (and will continue to exist), but the virtual interface | ||
195 | * needs to be switched from one to the other. | ||
196 | * @CHANCTX_SWMODE_SWAP_CONTEXTS: The old context exists but will stop | ||
197 | * to exist with this call, the new context doesn't exist but | ||
198 | * will be active after this call, the virtual interface switches | ||
199 | * from the old to the new (note that the driver may of course | ||
200 | * implement this as an on-the-fly chandef switch of the existing | ||
201 | * hardware context, but the mac80211 pointer for the old context | ||
202 | * will cease to exist and only the new one will later be used | ||
203 | * for changes/removal.) | ||
204 | */ | ||
205 | enum ieee80211_chanctx_switch_mode { | ||
206 | CHANCTX_SWMODE_REASSIGN_VIF, | ||
207 | CHANCTX_SWMODE_SWAP_CONTEXTS, | ||
208 | }; | ||
209 | |||
210 | /** | ||
211 | * struct ieee80211_vif_chanctx_switch - vif chanctx switch information | ||
212 | * | ||
213 | * This is structure is used to pass information about a vif that | ||
214 | * needs to switch from one chanctx to another. The | ||
215 | * &ieee80211_chanctx_switch_mode defines how the switch should be | ||
216 | * done. | ||
217 | * | ||
218 | * @vif: the vif that should be switched from old_ctx to new_ctx | ||
219 | * @old_ctx: the old context to which the vif was assigned | ||
220 | * @new_ctx: the new context to which the vif must be assigned | ||
221 | */ | ||
222 | struct ieee80211_vif_chanctx_switch { | ||
223 | struct ieee80211_vif *vif; | ||
224 | struct ieee80211_chanctx_conf *old_ctx; | ||
225 | struct ieee80211_chanctx_conf *new_ctx; | ||
226 | }; | ||
227 | |||
228 | /** | ||
192 | * enum ieee80211_bss_change - BSS change notification flags | 229 | * enum ieee80211_bss_change - BSS change notification flags |
193 | * | 230 | * |
194 | * These flags are used with the bss_info_changed() callback | 231 | * These flags are used with the bss_info_changed() callback |
@@ -2736,6 +2773,11 @@ enum ieee80211_roc_type { | |||
2736 | * to vif. Possible use is for hw queue remapping. | 2773 | * to vif. Possible use is for hw queue remapping. |
2737 | * @unassign_vif_chanctx: Notifies device driver about channel context being | 2774 | * @unassign_vif_chanctx: Notifies device driver about channel context being |
2738 | * unbound from vif. | 2775 | * unbound from vif. |
2776 | * @switch_vif_chanctx: switch a number of vifs from one chanctx to | ||
2777 | * another, as specified in the list of | ||
2778 | * @ieee80211_vif_chanctx_switch passed to the driver, according | ||
2779 | * to the mode defined in &ieee80211_chanctx_switch_mode. | ||
2780 | * | ||
2739 | * @start_ap: Start operation on the AP interface, this is called after all the | 2781 | * @start_ap: Start operation on the AP interface, this is called after all the |
2740 | * information in bss_conf is set and beacon can be retrieved. A channel | 2782 | * information in bss_conf is set and beacon can be retrieved. A channel |
2741 | * context is bound before this is called. Note that if the driver uses | 2783 | * context is bound before this is called. Note that if the driver uses |
@@ -2952,6 +2994,10 @@ struct ieee80211_ops { | |||
2952 | void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, | 2994 | void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, |
2953 | struct ieee80211_vif *vif, | 2995 | struct ieee80211_vif *vif, |
2954 | struct ieee80211_chanctx_conf *ctx); | 2996 | struct ieee80211_chanctx_conf *ctx); |
2997 | int (*switch_vif_chanctx)(struct ieee80211_hw *hw, | ||
2998 | struct ieee80211_vif_chanctx_switch *vifs, | ||
2999 | int n_vifs, | ||
3000 | enum ieee80211_chanctx_switch_mode mode); | ||
2955 | 3001 | ||
2956 | void (*restart_complete)(struct ieee80211_hw *hw); | 3002 | void (*restart_complete)(struct ieee80211_hw *hw); |
2957 | 3003 | ||
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 40a648938985..e205ebabfa50 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -34,8 +34,7 @@ static ssize_t ieee80211_if_read( | |||
34 | ssize_t ret = -EINVAL; | 34 | ssize_t ret = -EINVAL; |
35 | 35 | ||
36 | read_lock(&dev_base_lock); | 36 | read_lock(&dev_base_lock); |
37 | if (sdata->dev->reg_state == NETREG_REGISTERED) | 37 | ret = (*format)(sdata, buf, sizeof(buf)); |
38 | ret = (*format)(sdata, buf, sizeof(buf)); | ||
39 | read_unlock(&dev_base_lock); | 38 | read_unlock(&dev_base_lock); |
40 | 39 | ||
41 | if (ret >= 0) | 40 | if (ret >= 0) |
@@ -62,8 +61,7 @@ static ssize_t ieee80211_if_write( | |||
62 | 61 | ||
63 | ret = -ENODEV; | 62 | ret = -ENODEV; |
64 | rtnl_lock(); | 63 | rtnl_lock(); |
65 | if (sdata->dev->reg_state == NETREG_REGISTERED) | 64 | ret = (*write)(sdata, buf, count); |
66 | ret = (*write)(sdata, buf, count); | ||
67 | rtnl_unlock(); | 65 | rtnl_unlock(); |
68 | 66 | ||
69 | return ret; | 67 | return ret; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 696ef78b1fb7..bd782dcffcc7 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -1048,6 +1048,59 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, | |||
1048 | trace_drv_return_void(local); | 1048 | trace_drv_return_void(local); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static inline int | ||
1052 | drv_switch_vif_chanctx(struct ieee80211_local *local, | ||
1053 | struct ieee80211_vif_chanctx_switch *vifs, | ||
1054 | int n_vifs, | ||
1055 | enum ieee80211_chanctx_switch_mode mode) | ||
1056 | { | ||
1057 | int ret = 0; | ||
1058 | int i; | ||
1059 | |||
1060 | if (!local->ops->switch_vif_chanctx) | ||
1061 | return -EOPNOTSUPP; | ||
1062 | |||
1063 | for (i = 0; i < n_vifs; i++) { | ||
1064 | struct ieee80211_chanctx *new_ctx = | ||
1065 | container_of(vifs[i].new_ctx, | ||
1066 | struct ieee80211_chanctx, | ||
1067 | conf); | ||
1068 | struct ieee80211_chanctx *old_ctx = | ||
1069 | container_of(vifs[i].old_ctx, | ||
1070 | struct ieee80211_chanctx, | ||
1071 | conf); | ||
1072 | |||
1073 | WARN_ON_ONCE(!old_ctx->driver_present); | ||
1074 | WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS && | ||
1075 | new_ctx->driver_present) || | ||
1076 | (mode == CHANCTX_SWMODE_REASSIGN_VIF && | ||
1077 | !new_ctx->driver_present)); | ||
1078 | } | ||
1079 | |||
1080 | trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode); | ||
1081 | ret = local->ops->switch_vif_chanctx(&local->hw, | ||
1082 | vifs, n_vifs, mode); | ||
1083 | trace_drv_return_int(local, ret); | ||
1084 | |||
1085 | if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) { | ||
1086 | for (i = 0; i < n_vifs; i++) { | ||
1087 | struct ieee80211_chanctx *new_ctx = | ||
1088 | container_of(vifs[i].new_ctx, | ||
1089 | struct ieee80211_chanctx, | ||
1090 | conf); | ||
1091 | struct ieee80211_chanctx *old_ctx = | ||
1092 | container_of(vifs[i].old_ctx, | ||
1093 | struct ieee80211_chanctx, | ||
1094 | conf); | ||
1095 | |||
1096 | new_ctx->driver_present = true; | ||
1097 | old_ctx->driver_present = false; | ||
1098 | } | ||
1099 | } | ||
1100 | |||
1101 | return ret; | ||
1102 | } | ||
1103 | |||
1051 | static inline int drv_start_ap(struct ieee80211_local *local, | 1104 | static inline int drv_start_ap(struct ieee80211_local *local, |
1052 | struct ieee80211_sub_if_data *sdata) | 1105 | struct ieee80211_sub_if_data *sdata) |
1053 | { | 1106 | { |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 1bbac94da58d..18ee0a256b1e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1677,6 +1677,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1677 | sdata->u.ibss.control_port = params->control_port; | 1677 | sdata->u.ibss.control_port = params->control_port; |
1678 | sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs; | 1678 | sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs; |
1679 | sdata->u.ibss.basic_rates = params->basic_rates; | 1679 | sdata->u.ibss.basic_rates = params->basic_rates; |
1680 | sdata->u.ibss.last_scan_completed = jiffies; | ||
1680 | 1681 | ||
1681 | /* fix basic_rates if channel does not support these rates */ | 1682 | /* fix basic_rates if channel does not support these rates */ |
1682 | rate_flags = ieee80211_chandef_rate_flags(¶ms->chandef); | 1683 | rate_flags = ieee80211_chandef_rate_flags(¶ms->chandef); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 79fc98815da8..81a8e2a0b6aa 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -399,6 +399,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
399 | sdata->vif.type = NL80211_IFTYPE_MONITOR; | 399 | sdata->vif.type = NL80211_IFTYPE_MONITOR; |
400 | snprintf(sdata->name, IFNAMSIZ, "%s-monitor", | 400 | snprintf(sdata->name, IFNAMSIZ, "%s-monitor", |
401 | wiphy_name(local->hw.wiphy)); | 401 | wiphy_name(local->hw.wiphy)); |
402 | sdata->wdev.iftype = NL80211_IFTYPE_MONITOR; | ||
402 | 403 | ||
403 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; | 404 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; |
404 | 405 | ||
@@ -1285,6 +1286,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1285 | sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); | 1286 | sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); |
1286 | sdata->control_port_no_encrypt = false; | 1287 | sdata->control_port_no_encrypt = false; |
1287 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; | 1288 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; |
1289 | sdata->vif.bss_conf.idle = true; | ||
1288 | 1290 | ||
1289 | sdata->noack_map = 0; | 1291 | sdata->noack_map = 0; |
1290 | 1292 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 632d372bb511..a9b46d8ea22f 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -240,6 +240,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | |||
240 | 240 | ||
241 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); | 241 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); |
242 | 242 | ||
243 | kfree(rcu_dereference_raw(sta->sta.rates)); | ||
243 | kfree(sta); | 244 | kfree(sta); |
244 | } | 245 | } |
245 | 246 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 60cb7a665976..ba29ebc86141 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local, | |||
541 | */ | 541 | */ |
542 | #define STA_LOST_PKT_THRESHOLD 50 | 542 | #define STA_LOST_PKT_THRESHOLD 50 |
543 | 543 | ||
544 | static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) | ||
545 | { | ||
546 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
547 | |||
548 | /* This packet was aggregated but doesn't carry status info */ | ||
549 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && | ||
550 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | ||
551 | return; | ||
552 | |||
553 | if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD) | ||
554 | return; | ||
555 | |||
556 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, | ||
557 | sta->lost_packets, GFP_ATOMIC); | ||
558 | sta->lost_packets = 0; | ||
559 | } | ||
560 | |||
544 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | 561 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
545 | { | 562 | { |
546 | struct sk_buff *skb2; | 563 | struct sk_buff *skb2; |
@@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
680 | if (info->flags & IEEE80211_TX_STAT_ACK) { | 697 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
681 | if (sta->lost_packets) | 698 | if (sta->lost_packets) |
682 | sta->lost_packets = 0; | 699 | sta->lost_packets = 0; |
683 | } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) { | 700 | } else { |
684 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, | 701 | ieee80211_lost_packet(sta, skb); |
685 | sta->sta.addr, | ||
686 | sta->lost_packets, | ||
687 | GFP_ATOMIC); | ||
688 | sta->lost_packets = 0; | ||
689 | } | 702 | } |
690 | } | 703 | } |
691 | 704 | ||
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 762e4cd16386..cfe1a0688b5c 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -1389,6 +1389,91 @@ TRACE_EVENT(drv_change_chanctx, | |||
1389 | ) | 1389 | ) |
1390 | ); | 1390 | ); |
1391 | 1391 | ||
1392 | #if !defined(__TRACE_VIF_ENTRY) | ||
1393 | #define __TRACE_VIF_ENTRY | ||
1394 | struct trace_vif_entry { | ||
1395 | enum nl80211_iftype vif_type; | ||
1396 | bool p2p; | ||
1397 | char vif_name[IFNAMSIZ]; | ||
1398 | } __packed; | ||
1399 | |||
1400 | struct trace_chandef_entry { | ||
1401 | u32 control_freq; | ||
1402 | u32 chan_width; | ||
1403 | u32 center_freq1; | ||
1404 | u32 center_freq2; | ||
1405 | } __packed; | ||
1406 | |||
1407 | struct trace_switch_entry { | ||
1408 | struct trace_vif_entry vif; | ||
1409 | struct trace_chandef_entry old_chandef; | ||
1410 | struct trace_chandef_entry new_chandef; | ||
1411 | } __packed; | ||
1412 | |||
1413 | #define SWITCH_ENTRY_ASSIGN(to, from) local_vifs[i].to = vifs[i].from | ||
1414 | #endif | ||
1415 | |||
1416 | TRACE_EVENT(drv_switch_vif_chanctx, | ||
1417 | TP_PROTO(struct ieee80211_local *local, | ||
1418 | struct ieee80211_vif_chanctx_switch *vifs, | ||
1419 | int n_vifs, enum ieee80211_chanctx_switch_mode mode), | ||
1420 | TP_ARGS(local, vifs, n_vifs, mode), | ||
1421 | |||
1422 | TP_STRUCT__entry( | ||
1423 | LOCAL_ENTRY | ||
1424 | __field(int, n_vifs) | ||
1425 | __field(u32, mode) | ||
1426 | __dynamic_array(u8, vifs, | ||
1427 | sizeof(struct trace_switch_entry) * n_vifs) | ||
1428 | ), | ||
1429 | |||
1430 | TP_fast_assign( | ||
1431 | LOCAL_ASSIGN; | ||
1432 | __entry->n_vifs = n_vifs; | ||
1433 | __entry->mode = mode; | ||
1434 | { | ||
1435 | struct trace_switch_entry *local_vifs = | ||
1436 | __get_dynamic_array(vifs); | ||
1437 | int i; | ||
1438 | |||
1439 | for (i = 0; i < n_vifs; i++) { | ||
1440 | struct ieee80211_sub_if_data *sdata; | ||
1441 | |||
1442 | sdata = container_of(vifs[i].vif, | ||
1443 | struct ieee80211_sub_if_data, | ||
1444 | vif); | ||
1445 | |||
1446 | SWITCH_ENTRY_ASSIGN(vif.vif_type, vif->type); | ||
1447 | SWITCH_ENTRY_ASSIGN(vif.p2p, vif->p2p); | ||
1448 | strncpy(local_vifs[i].vif.vif_name, | ||
1449 | sdata->name, | ||
1450 | sizeof(local_vifs[i].vif.vif_name)); | ||
1451 | SWITCH_ENTRY_ASSIGN(old_chandef.control_freq, | ||
1452 | old_ctx->def.chan->center_freq); | ||
1453 | SWITCH_ENTRY_ASSIGN(old_chandef.chan_width, | ||
1454 | old_ctx->def.width); | ||
1455 | SWITCH_ENTRY_ASSIGN(old_chandef.center_freq1, | ||
1456 | old_ctx->def.center_freq1); | ||
1457 | SWITCH_ENTRY_ASSIGN(old_chandef.center_freq2, | ||
1458 | old_ctx->def.center_freq2); | ||
1459 | SWITCH_ENTRY_ASSIGN(new_chandef.control_freq, | ||
1460 | new_ctx->def.chan->center_freq); | ||
1461 | SWITCH_ENTRY_ASSIGN(new_chandef.chan_width, | ||
1462 | new_ctx->def.width); | ||
1463 | SWITCH_ENTRY_ASSIGN(new_chandef.center_freq1, | ||
1464 | new_ctx->def.center_freq1); | ||
1465 | SWITCH_ENTRY_ASSIGN(new_chandef.center_freq2, | ||
1466 | new_ctx->def.center_freq2); | ||
1467 | } | ||
1468 | } | ||
1469 | ), | ||
1470 | |||
1471 | TP_printk( | ||
1472 | LOCAL_PR_FMT " n_vifs:%d mode:%d", | ||
1473 | LOCAL_PR_ARG, __entry->n_vifs, __entry->mode | ||
1474 | ) | ||
1475 | ); | ||
1476 | |||
1392 | DECLARE_EVENT_CLASS(local_sdata_chanctx, | 1477 | DECLARE_EVENT_CLASS(local_sdata_chanctx, |
1393 | TP_PROTO(struct ieee80211_local *local, | 1478 | TP_PROTO(struct ieee80211_local *local, |
1394 | struct ieee80211_sub_if_data *sdata, | 1479 | struct ieee80211_sub_if_data *sdata, |
diff --git a/net/wireless/core.c b/net/wireless/core.c index d03d8bdb29ca..a1c40654dd9b 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -130,7 +130,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
130 | newname)) | 130 | newname)) |
131 | pr_err("failed to rename debugfs dir to %s!\n", newname); | 131 | pr_err("failed to rename debugfs dir to %s!\n", newname); |
132 | 132 | ||
133 | nl80211_notify_dev_rename(rdev); | 133 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); |
134 | 134 | ||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
@@ -660,6 +660,8 @@ int wiphy_register(struct wiphy *wiphy) | |||
660 | return res; | 660 | return res; |
661 | } | 661 | } |
662 | 662 | ||
663 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); | ||
664 | |||
663 | return 0; | 665 | return 0; |
664 | } | 666 | } |
665 | EXPORT_SYMBOL(wiphy_register); | 667 | EXPORT_SYMBOL(wiphy_register); |
@@ -698,6 +700,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
698 | rfkill_unregister(rdev->rfkill); | 700 | rfkill_unregister(rdev->rfkill); |
699 | 701 | ||
700 | rtnl_lock(); | 702 | rtnl_lock(); |
703 | nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); | ||
701 | rdev->wiphy.registered = false; | 704 | rdev->wiphy.registered = false; |
702 | 705 | ||
703 | WARN_ON(!list_empty(&rdev->wdev_list)); | 706 | WARN_ON(!list_empty(&rdev->wdev_list)); |
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk index b35da8dc85de..40c37fc5b67c 100644 --- a/net/wireless/genregdb.awk +++ b/net/wireless/genregdb.awk | |||
@@ -68,17 +68,7 @@ function parse_reg_rule() | |||
68 | sub(/,/, "", units) | 68 | sub(/,/, "", units) |
69 | dfs_cac = $9 | 69 | dfs_cac = $9 |
70 | if (units == "mW") { | 70 | if (units == "mW") { |
71 | if (power == 100) { | 71 | power = 10 * log(power)/log(10) |
72 | power = 20 | ||
73 | } else if (power == 200) { | ||
74 | power = 23 | ||
75 | } else if (power == 500) { | ||
76 | power = 27 | ||
77 | } else if (power == 1000) { | ||
78 | power = 30 | ||
79 | } else { | ||
80 | print "Unknown power value in database!" | ||
81 | } | ||
82 | } else { | 72 | } else { |
83 | dfs_cac = $8 | 73 | dfs_cac = $8 |
84 | } | 74 | } |
@@ -117,7 +107,7 @@ function parse_reg_rule() | |||
117 | 107 | ||
118 | } | 108 | } |
119 | flags = flags "0" | 109 | flags = flags "0" |
120 | printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags | 110 | printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags |
121 | rules++ | 111 | rules++ |
122 | } | 112 | } |
123 | 113 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 62bdb1adaa4d..ba4f1723c83a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1226,6 +1226,7 @@ struct nl80211_dump_wiphy_state { | |||
1226 | }; | 1226 | }; |
1227 | 1227 | ||
1228 | static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | 1228 | static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, |
1229 | enum nl80211_commands cmd, | ||
1229 | struct sk_buff *msg, u32 portid, u32 seq, | 1230 | struct sk_buff *msg, u32 portid, u32 seq, |
1230 | int flags, struct nl80211_dump_wiphy_state *state) | 1231 | int flags, struct nl80211_dump_wiphy_state *state) |
1231 | { | 1232 | { |
@@ -1240,7 +1241,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1240 | rdev->wiphy.mgmt_stypes; | 1241 | rdev->wiphy.mgmt_stypes; |
1241 | u32 features; | 1242 | u32 features; |
1242 | 1243 | ||
1243 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); | 1244 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
1244 | if (!hdr) | 1245 | if (!hdr) |
1245 | return -ENOBUFS; | 1246 | return -ENOBUFS; |
1246 | 1247 | ||
@@ -1254,6 +1255,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1254 | cfg80211_rdev_list_generation)) | 1255 | cfg80211_rdev_list_generation)) |
1255 | goto nla_put_failure; | 1256 | goto nla_put_failure; |
1256 | 1257 | ||
1258 | if (cmd != NL80211_CMD_NEW_WIPHY) | ||
1259 | goto finish; | ||
1260 | |||
1257 | switch (state->split_start) { | 1261 | switch (state->split_start) { |
1258 | case 0: | 1262 | case 0: |
1259 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, | 1263 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, |
@@ -1682,6 +1686,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1682 | state->split_start = 0; | 1686 | state->split_start = 0; |
1683 | break; | 1687 | break; |
1684 | } | 1688 | } |
1689 | finish: | ||
1685 | return genlmsg_end(msg, hdr); | 1690 | return genlmsg_end(msg, hdr); |
1686 | 1691 | ||
1687 | nla_put_failure: | 1692 | nla_put_failure: |
@@ -1756,7 +1761,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1756 | continue; | 1761 | continue; |
1757 | /* attempt to fit multiple wiphy data chunks into the skb */ | 1762 | /* attempt to fit multiple wiphy data chunks into the skb */ |
1758 | do { | 1763 | do { |
1759 | ret = nl80211_send_wiphy(rdev, skb, | 1764 | ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, |
1765 | skb, | ||
1760 | NETLINK_CB(cb->skb).portid, | 1766 | NETLINK_CB(cb->skb).portid, |
1761 | cb->nlh->nlmsg_seq, | 1767 | cb->nlh->nlmsg_seq, |
1762 | NLM_F_MULTI, state); | 1768 | NLM_F_MULTI, state); |
@@ -1811,7 +1817,8 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1811 | if (!msg) | 1817 | if (!msg) |
1812 | return -ENOMEM; | 1818 | return -ENOMEM; |
1813 | 1819 | ||
1814 | if (nl80211_send_wiphy(rdev, msg, info->snd_portid, info->snd_seq, 0, | 1820 | if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg, |
1821 | info->snd_portid, info->snd_seq, 0, | ||
1815 | &state) < 0) { | 1822 | &state) < 0) { |
1816 | nlmsg_free(msg); | 1823 | nlmsg_free(msg); |
1817 | return -ENOBUFS; | 1824 | return -ENOBUFS; |
@@ -10101,16 +10108,20 @@ static const struct genl_ops nl80211_ops[] = { | |||
10101 | 10108 | ||
10102 | /* notification functions */ | 10109 | /* notification functions */ |
10103 | 10110 | ||
10104 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 10111 | void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, |
10112 | enum nl80211_commands cmd) | ||
10105 | { | 10113 | { |
10106 | struct sk_buff *msg; | 10114 | struct sk_buff *msg; |
10107 | struct nl80211_dump_wiphy_state state = {}; | 10115 | struct nl80211_dump_wiphy_state state = {}; |
10108 | 10116 | ||
10117 | WARN_ON(cmd != NL80211_CMD_NEW_WIPHY && | ||
10118 | cmd != NL80211_CMD_DEL_WIPHY); | ||
10119 | |||
10109 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 10120 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
10110 | if (!msg) | 10121 | if (!msg) |
10111 | return; | 10122 | return; |
10112 | 10123 | ||
10113 | if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) { | 10124 | if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) { |
10114 | nlmsg_free(msg); | 10125 | nlmsg_free(msg); |
10115 | return; | 10126 | return; |
10116 | } | 10127 | } |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 1e6df9630f42..49c9a482dd12 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -5,7 +5,8 @@ | |||
5 | 5 | ||
6 | int nl80211_init(void); | 6 | int nl80211_init(void); |
7 | void nl80211_exit(void); | 7 | void nl80211_exit(void); |
8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); | 8 | void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, |
9 | enum nl80211_commands cmd); | ||
9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 10 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
10 | struct wireless_dev *wdev); | 11 | struct wireless_dev *wdev); |
11 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, | 12 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |