cfg80211: pass a channel definition struct
[linux-2.6-block.git] / net / wireless / chan.c
CommitLineData
59bbb6f7
JB
1/*
2 * This file contains helper code to handle channel
3 * settings and keeping track of what is possible at
4 * any point in time.
5 *
6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
7 */
8
54858ee5 9#include <linux/export.h>
59bbb6f7
JB
10#include <net/cfg80211.h>
11#include "core.h"
e35e4d28 12#include "rdev-ops.h"
59bbb6f7 13
683b6d3b
JB
14bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
15 struct cfg80211_chan_def *chandef)
9236d838
LR
16{
17 struct ieee80211_channel *sec_chan;
18 int diff;
19
683b6d3b 20 trace_cfg80211_reg_can_beacon(wiphy, chandef);
4ee3e063 21
683b6d3b 22 switch (chandef->_type) {
9236d838
LR
23 case NL80211_CHAN_HT40PLUS:
24 diff = 20;
09a02fdb 25 break;
9236d838
LR
26 case NL80211_CHAN_HT40MINUS:
27 diff = -20;
09a02fdb 28 break;
9236d838 29 default:
4ee3e063 30 trace_cfg80211_return_bool(true);
d58e7e37 31 return true;
9236d838
LR
32 }
33
683b6d3b
JB
34 sec_chan = ieee80211_get_channel(wiphy,
35 chandef->chan->center_freq + diff);
4ee3e063
BL
36 if (!sec_chan) {
37 trace_cfg80211_return_bool(false);
9236d838 38 return false;
4ee3e063 39 }
9236d838
LR
40
41 /* we'll need a DFS capability later */
42 if (sec_chan->flags & (IEEE80211_CHAN_DISABLED |
43 IEEE80211_CHAN_PASSIVE_SCAN |
44 IEEE80211_CHAN_NO_IBSS |
4ee3e063
BL
45 IEEE80211_CHAN_RADAR)) {
46 trace_cfg80211_return_bool(false);
9236d838 47 return false;
4ee3e063
BL
48 }
49 trace_cfg80211_return_bool(true);
9236d838
LR
50 return true;
51}
683b6d3b 52EXPORT_SYMBOL(cfg80211_reg_can_beacon);
9236d838 53
e8c9bd5b 54int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
683b6d3b 55 struct cfg80211_chan_def *chandef)
9588bbd5 56{
e8c9bd5b 57 if (!rdev->ops->set_monitor_channel)
9588bbd5 58 return -EOPNOTSUPP;
4f03c1ed
MK
59 if (!cfg80211_has_monitors_only(rdev))
60 return -EBUSY;
9588bbd5 61
683b6d3b 62 return rdev_set_monitor_channel(rdev, chandef);
59bbb6f7 63}
26ab9a0c
MK
64
65void
8e95ea49 66cfg80211_get_chan_state(struct wireless_dev *wdev,
26ab9a0c
MK
67 struct ieee80211_channel **chan,
68 enum cfg80211_chan_mode *chanmode)
69{
70 *chan = NULL;
71 *chanmode = CHAN_MODE_UNDEFINED;
72
26ab9a0c
MK
73 ASSERT_WDEV_LOCK(wdev);
74
98104fde 75 if (wdev->netdev && !netif_running(wdev->netdev))
26ab9a0c
MK
76 return;
77
78 switch (wdev->iftype) {
79 case NL80211_IFTYPE_ADHOC:
80 if (wdev->current_bss) {
81 *chan = wdev->current_bss->pub.channel;
82 *chanmode = wdev->ibss_fixed
83 ? CHAN_MODE_SHARED
84 : CHAN_MODE_EXCLUSIVE;
85 return;
86 }
87 case NL80211_IFTYPE_STATION:
88 case NL80211_IFTYPE_P2P_CLIENT:
89 if (wdev->current_bss) {
90 *chan = wdev->current_bss->pub.channel;
91 *chanmode = CHAN_MODE_SHARED;
92 return;
93 }
94 break;
95 case NL80211_IFTYPE_AP:
96 case NL80211_IFTYPE_P2P_GO:
f53594a0
FF
97 if (wdev->beacon_interval) {
98 *chan = wdev->channel;
99 *chanmode = CHAN_MODE_SHARED;
100 }
101 return;
26ab9a0c 102 case NL80211_IFTYPE_MESH_POINT:
f53594a0
FF
103 if (wdev->mesh_id_len) {
104 *chan = wdev->channel;
105 *chanmode = CHAN_MODE_SHARED;
106 }
26ab9a0c
MK
107 return;
108 case NL80211_IFTYPE_MONITOR:
109 case NL80211_IFTYPE_AP_VLAN:
110 case NL80211_IFTYPE_WDS:
111 /* these interface types don't really have a channel */
112 return;
98104fde
JB
113 case NL80211_IFTYPE_P2P_DEVICE:
114 if (wdev->wiphy->features &
115 NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL)
116 *chanmode = CHAN_MODE_EXCLUSIVE;
117 return;
26ab9a0c
MK
118 case NL80211_IFTYPE_UNSPECIFIED:
119 case NUM_NL80211_IFTYPES:
120 WARN_ON(1);
121 }
122
123 return;
124}