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 */
76 strlcpy(req
->name
, "IEEE 802.11b/g", IFNAMSIZ
);
80 static int iw_get_nick(struct net_device
*netdev
,
81 struct iw_request_info
*info
,
82 union iwreq_data
*req
, char *extra
)
84 strcpy(extra
, "zd1211");
85 req
->data
.length
= strlen(extra
);
90 static int iw_set_freq(struct net_device
*netdev
,
91 struct iw_request_info
*info
,
92 union iwreq_data
*req
, char *extra
)
95 struct zd_mac
*mac
= zd_netdev_mac(netdev
);
96 struct iw_freq
*freq
= &req
->freq
;
99 r
= zd_find_channel(&channel
, freq
);
102 r
= zd_mac_request_channel(mac
, channel
);
106 static int iw_get_freq(struct net_device
*netdev
,
107 struct iw_request_info
*info
,
108 union iwreq_data
*req
, char *extra
)
110 struct zd_mac
*mac
= zd_netdev_mac(netdev
);
111 struct iw_freq
*freq
= &req
->freq
;
113 return zd_channel_to_freq(freq
, zd_mac_get_channel(mac
));
116 static int iw_set_mode(struct net_device
*netdev
,
117 struct iw_request_info
*info
,
118 union iwreq_data
*req
, char *extra
)
120 return zd_mac_set_mode(zd_netdev_mac(netdev
), req
->mode
);
123 static int iw_get_mode(struct net_device
*netdev
,
124 struct iw_request_info
*info
,
125 union iwreq_data
*req
, char *extra
)
127 return zd_mac_get_mode(zd_netdev_mac(netdev
), &req
->mode
);
130 static int iw_get_range(struct net_device
*netdev
,
131 struct iw_request_info
*info
,
132 union iwreq_data
*req
, char *extra
)
134 struct iw_range
*range
= (struct iw_range
*)extra
;
136 dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev
)), "\n");
137 req
->data
.length
= sizeof(*range
);
138 return zd_mac_get_range(zd_netdev_mac(netdev
), range
);
141 static int iw_set_encode(struct net_device
*netdev
,
142 struct iw_request_info
*info
,
143 union iwreq_data
*data
,
146 return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev
), info
,
150 static int iw_get_encode(struct net_device
*netdev
,
151 struct iw_request_info
*info
,
152 union iwreq_data
*data
,
155 return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev
), info
,
159 static int iw_set_encodeext(struct net_device
*netdev
,
160 struct iw_request_info
*info
,
161 union iwreq_data
*data
,
164 return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev
), info
,
168 static int iw_get_encodeext(struct net_device
*netdev
,
169 struct iw_request_info
*info
,
170 union iwreq_data
*data
,
173 return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev
), info
,
177 #define WX(x) [(x)-SIOCIWFIRST]
179 static const iw_handler zd_standard_iw_handlers
[] = {
180 WX(SIOCGIWNAME
) = iw_get_name
,
181 WX(SIOCGIWNICKN
) = iw_get_nick
,
182 WX(SIOCSIWFREQ
) = iw_set_freq
,
183 WX(SIOCGIWFREQ
) = iw_get_freq
,
184 WX(SIOCSIWMODE
) = iw_set_mode
,
185 WX(SIOCGIWMODE
) = iw_get_mode
,
186 WX(SIOCGIWRANGE
) = iw_get_range
,
187 WX(SIOCSIWENCODE
) = iw_set_encode
,
188 WX(SIOCGIWENCODE
) = iw_get_encode
,
189 WX(SIOCSIWENCODEEXT
) = iw_set_encodeext
,
190 WX(SIOCGIWENCODEEXT
) = iw_get_encodeext
,
191 WX(SIOCSIWAUTH
) = ieee80211_wx_set_auth
,
192 WX(SIOCGIWAUTH
) = ieee80211_wx_get_auth
,
193 WX(SIOCSIWSCAN
) = ieee80211softmac_wx_trigger_scan
,
194 WX(SIOCGIWSCAN
) = ieee80211softmac_wx_get_scan_results
,
195 WX(SIOCSIWESSID
) = ieee80211softmac_wx_set_essid
,
196 WX(SIOCGIWESSID
) = ieee80211softmac_wx_get_essid
,
197 WX(SIOCSIWAP
) = ieee80211softmac_wx_set_wap
,
198 WX(SIOCGIWAP
) = ieee80211softmac_wx_get_wap
,
199 WX(SIOCSIWRATE
) = ieee80211softmac_wx_set_rate
,
200 WX(SIOCGIWRATE
) = ieee80211softmac_wx_get_rate
,
201 WX(SIOCSIWGENIE
) = ieee80211softmac_wx_set_genie
,
202 WX(SIOCGIWGENIE
) = ieee80211softmac_wx_get_genie
,
203 WX(SIOCSIWMLME
) = ieee80211softmac_wx_set_mlme
,
206 static const struct iw_handler_def iw_handler_def
= {
207 .standard
= zd_standard_iw_handlers
,
208 .num_standard
= ARRAY_SIZE(zd_standard_iw_handlers
),
209 .private = zd_priv_handler
,
210 .num_private
= ARRAY_SIZE(zd_priv_handler
),
211 .private_args
= zd_priv_args
,
212 .num_private_args
= ARRAY_SIZE(zd_priv_args
),
213 .get_wireless_stats
= zd_mac_get_wireless_stats
,
216 struct net_device
*zd_netdev_alloc(struct usb_interface
*intf
)
219 struct net_device
*netdev
;
222 netdev
= alloc_ieee80211softmac(sizeof(struct zd_mac
));
224 dev_dbg_f(&intf
->dev
, "out of memory\n");
228 mac
= zd_netdev_mac(netdev
);
229 r
= zd_mac_init(mac
, netdev
, intf
);
231 usb_set_intfdata(intf
, NULL
);
232 free_ieee80211(netdev
);
236 SET_NETDEV_DEV(netdev
, &intf
->dev
);
238 dev_dbg_f(&intf
->dev
, "netdev->flags %#06hx\n", netdev
->flags
);
239 dev_dbg_f(&intf
->dev
, "netdev->features %#010lx\n", netdev
->features
);
241 netdev
->open
= zd_mac_open
;
242 netdev
->stop
= zd_mac_stop
;
243 /* netdev->get_stats = */
244 netdev
->set_multicast_list
= zd_mac_set_multicast_list
;
245 netdev
->set_mac_address
= zd_mac_set_mac_address
;
246 netdev
->wireless_handlers
= &iw_handler_def
;
247 /* netdev->ethtool_ops = */
252 void zd_netdev_free(struct net_device
*netdev
)
257 zd_mac_clear(zd_netdev_mac(netdev
));
258 free_ieee80211(netdev
);
261 void zd_netdev_disconnect(struct net_device
*netdev
)
263 unregister_netdev(netdev
);