3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #include <linux/netdevice.h>
19 #include <linux/etherdevice.h>
20 #include <linux/skbuff.h>
21 #include <net/ieee80211.h>
22 #include <net/ieee80211softmac.h>
23 #include <net/ieee80211softmac_wx.h>
24 #include <net/iw_handler.h>
27 #include "zd_netdev.h"
29 #include "zd_ieee80211.h"
31 /* Region 0 means reset regdomain to default. */
32 static int zd_set_regdomain(struct net_device *netdev,
33 struct iw_request_info *info,
34 union iwreq_data *req, char *extra)
36 const u8 *regdomain = (u8 *)req;
37 return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain);
40 static int zd_get_regdomain(struct net_device *netdev,
41 struct iw_request_info *info,
42 union iwreq_data *req, char *extra)
44 u8 *regdomain = (u8 *)req;
47 *regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev));
51 static const struct iw_priv_args zd_priv_args[] = {
53 .cmd = ZD_PRIV_SET_REGDOMAIN,
54 .set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
55 .name = "set_regdomain",
58 .cmd = ZD_PRIV_GET_REGDOMAIN,
59 .get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
60 .name = "get_regdomain",
64 #define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV]
66 static const iw_handler zd_priv_handler[] = {
67 PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain,
68 PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain,
71 static int iw_get_name(struct net_device *netdev,
72 struct iw_request_info *info,
73 union iwreq_data *req, char *extra)
75 /* FIXME: check whether 802.11a will also supported, add also
76 * zd1211B, if we support it.
78 strlcpy(req->name, "802.11g zd1211", IFNAMSIZ);
82 static int iw_set_freq(struct net_device *netdev,
83 struct iw_request_info *info,
84 union iwreq_data *req, char *extra)
87 struct zd_mac *mac = zd_netdev_mac(netdev);
88 struct iw_freq *freq = &req->freq;
91 r = zd_find_channel(&channel, freq);
94 r = zd_mac_request_channel(mac, channel);
98 static int iw_get_freq(struct net_device *netdev,
99 struct iw_request_info *info,
100 union iwreq_data *req, char *extra)
103 struct zd_mac *mac = zd_netdev_mac(netdev);
104 struct iw_freq *freq = &req->freq;
108 r = zd_mac_get_channel(mac, &channel, &flags);
112 freq->flags = (flags & MAC_FIXED_CHANNEL) ?
113 IW_FREQ_FIXED : IW_FREQ_AUTO;
114 dev_dbg_f(zd_mac_dev(mac), "channel %s\n",
115 (flags & MAC_FIXED_CHANNEL) ? "fixed" : "auto");
116 return zd_channel_to_freq(freq, channel);
119 static int iw_set_mode(struct net_device *netdev,
120 struct iw_request_info *info,
121 union iwreq_data *req, char *extra)
123 return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode);
126 static int iw_get_mode(struct net_device *netdev,
127 struct iw_request_info *info,
128 union iwreq_data *req, char *extra)
130 return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode);
133 static int iw_get_range(struct net_device *netdev,
134 struct iw_request_info *info,
135 union iwreq_data *req, char *extra)
137 struct iw_range *range = (struct iw_range *)extra;
139 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
140 req->data.length = sizeof(*range);
141 return zd_mac_get_range(zd_netdev_mac(netdev), range);
144 static int iw_set_encode(struct net_device *netdev,
145 struct iw_request_info *info,
146 union iwreq_data *data,
149 return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info,
153 static int iw_get_encode(struct net_device *netdev,
154 struct iw_request_info *info,
155 union iwreq_data *data,
158 return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info,
162 static int iw_set_encodeext(struct net_device *netdev,
163 struct iw_request_info *info,
164 union iwreq_data *data,
167 return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info,
171 static int iw_get_encodeext(struct net_device *netdev,
172 struct iw_request_info *info,
173 union iwreq_data *data,
176 return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info,
180 #define WX(x) [(x)-SIOCIWFIRST]
182 static const iw_handler zd_standard_iw_handlers[] = {
183 WX(SIOCGIWNAME) = iw_get_name,
184 WX(SIOCSIWFREQ) = iw_set_freq,
185 WX(SIOCGIWFREQ) = iw_get_freq,
186 WX(SIOCSIWMODE) = iw_set_mode,
187 WX(SIOCGIWMODE) = iw_get_mode,
188 WX(SIOCGIWRANGE) = iw_get_range,
189 WX(SIOCSIWENCODE) = iw_set_encode,
190 WX(SIOCGIWENCODE) = iw_get_encode,
191 WX(SIOCSIWENCODEEXT) = iw_set_encodeext,
192 WX(SIOCGIWENCODEEXT) = iw_get_encodeext,
193 WX(SIOCSIWAUTH) = ieee80211_wx_set_auth,
194 WX(SIOCGIWAUTH) = ieee80211_wx_get_auth,
195 WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan,
196 WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results,
197 WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid,
198 WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid,
199 WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap,
200 WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap,
201 WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate,
202 WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate,
203 WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie,
204 WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie,
205 WX(SIOCSIWMLME) = ieee80211softmac_wx_set_mlme,
208 static const struct iw_handler_def iw_handler_def = {
209 .standard = zd_standard_iw_handlers,
210 .num_standard = ARRAY_SIZE(zd_standard_iw_handlers),
211 .private = zd_priv_handler,
212 .num_private = ARRAY_SIZE(zd_priv_handler),
213 .private_args = zd_priv_args,
214 .num_private_args = ARRAY_SIZE(zd_priv_args),
215 .get_wireless_stats = zd_mac_get_wireless_stats,
218 struct net_device *zd_netdev_alloc(struct usb_interface *intf)
221 struct net_device *netdev;
224 netdev = alloc_ieee80211softmac(sizeof(struct zd_mac));
226 dev_dbg_f(&intf->dev, "out of memory\n");
230 mac = zd_netdev_mac(netdev);
231 r = zd_mac_init(mac, netdev, intf);
233 usb_set_intfdata(intf, NULL);
234 free_ieee80211(netdev);
238 SET_MODULE_OWNER(netdev);
239 SET_NETDEV_DEV(netdev, &intf->dev);
241 dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags);
242 dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features);
244 netdev->open = zd_mac_open;
245 netdev->stop = zd_mac_stop;
246 /* netdev->get_stats = */
247 /* netdev->set_multicast_list = */
248 netdev->set_mac_address = zd_mac_set_mac_address;
249 netdev->wireless_handlers = &iw_handler_def;
250 /* netdev->ethtool_ops = */
255 void zd_netdev_free(struct net_device *netdev)
260 zd_mac_clear(zd_netdev_mac(netdev));
261 free_ieee80211(netdev);
264 void zd_netdev_disconnect(struct net_device *netdev)
266 unregister_netdev(netdev);