Initial import from the website's tarball, on the 18th of october 2004
[islsm.git] / usb_ioctl.c
bloba37af4d7c754ecb2bba0e5e16dbff3d5c4398e25
1 #include <linux/wireless.h>
2 #include <linux/netdevice.h> /* needed by iw_handler */
3 #include <net/iw_handler.h>
5 #include "ioctl.h"
6 #include "prism54_usb.h"
7 #include "channels.h"
9 #define SUPPORTED_WIRELESS_EXT 16
11 void make_tx_control_channel(struct p54u *p54u, void *buf, int chan)
13 struct p54u_mgmt_rx_frame *mgmt = &p54u->mgmt_frame;
14 struct p54u_tx *tx = (struct p54u_tx *) buf;
15 struct p54u_tx_control *txc = (struct p54u_tx_control *) &tx->data;
16 struct p54u_tx_control_channel *tx_chan = (struct p54u_tx_control_channel *) &txc->data;
17 int i;
19 tx->magic1 = P54U_TX_MAGIC1_CHANNEL;
20 tx->length = cpu_to_le16(sizeof(*txc)-sizeof(void*)+sizeof(*tx_chan));
21 txc->magic1 = cpu_to_le16(P54U_TX_CONTROL_NORESPONSE);
22 txc->length = cpu_to_le16(sizeof(*tx_chan));
23 /* numbered from 0 */
24 chan = chan-1;
27 tx_chan->magic1 = cpu_to_le32(P54U_TX_CONTROL_CHANNEL_MAGIC1_SCAN);
28 tx_chan->freq = mgmt->l3[chan];
29 tx_chan->unknown1 = cpu_to_le16(0x4808);
30 /* maybe this is only a 32-bits value */
31 tx_chan->l1data[0] = mgmt->l1[chan].data[0];
32 tx_chan->l1data[1] = mgmt->l1[chan].data[1];
33 tx_chan->l1data[2] = mgmt->l1[chan].data[2];
34 tx_chan->l1data[3] = mgmt->l1[chan].data[3];
36 #define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y)
37 for(i = 0; i < P54U_CHANNEL_DEFS; i++) {
38 tx_chan->str[i].head=mgmt->l2[chan].data[i].head;
39 tx_chan->str[i].tail=mgmt->l2[chan].data[i].tail;
40 tx_chan->str[i].subtails[3]=SUB(tx_chan->str[i].tail,12);
41 tx_chan->str[i].subtails[2]=SUB(tx_chan->str[i].subtails[3],12);
42 tx_chan->str[i].subtails[1]=SUB(tx_chan->str[i].subtails[2],12);
43 tx_chan->str[i].subtails[0]=SUB(tx_chan->str[i].subtails[1],14);
46 return;
49 /**** WARNING *****/
50 /* _ALL_ of these calls are bogus except for set_channel_freq */
51 /* I expect to complete statistics soon enough */
53 struct iw_statistics *
54 p54u_wireless_stats(struct net_device *ndev)
56 struct p54u *priv = netdev_priv(ndev);
58 /* completely bogus */
59 return &priv->iwstatistics;
63 static int
64 prism54_commit(struct net_device *ndev, struct iw_request_info *info,
65 char *cwrq, char *extra)
67 return 0;
70 static int
71 prism54_get_name(struct net_device *ndev, struct iw_request_info *info,
72 char *cwrq, char *extra)
74 char *capabilities;
75 int rvalue;
77 capabilities = "IEEE 802.11b/g"; /* Default */
79 strncpy(cwrq, capabilities, IFNAMSIZ);
81 return 0;
85 static int
86 prism54_set_freq(struct net_device *netdev, struct iw_request_info *info,
87 struct iw_freq *fwrq, char *extra)
89 struct p54u *p54u = netdev_priv(netdev);
90 char* channel_packet = 0;
91 int c;
93 channel_packet=kmalloc(FULL_TX_CONTROL_CHANNEL,GFP_KERNEL);
94 if (!channel_packet)
95 return -ENOMEM;
97 memset(channel_packet,0,FULL_TX_CONTROL_CHANNEL);
99 if (fwrq->m < 1000 && fwrq->m >= 1 && fwrq->m < P54U_NR_CHANNELS)
100 /* we have a valid channel number */
101 c = fwrq->m;
102 else
103 /* we dont handle freq_to_channel yet */
104 return -ENOTSUPP;
106 make_tx_control_channel(p54u, channel_packet, c);
107 p54u_control_msg(netdev, p54u_freqs[c-1], FULL_TX_CONTROL_CHANNEL);
108 p54u_wait_data(netdev);
110 kfree(channel_packet);
112 return p54u->err;
115 static int
116 prism54_get_freq(struct net_device *ndev, struct iw_request_info *info,
117 struct iw_freq *fwrq, char *extra)
119 fwrq->m = 272;
120 fwrq->e = 0;
122 return 0;
125 static int
126 prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
127 __u32 * uwrq, char *extra)
129 /* islpci_private *priv = netdev_priv(ndev); */
130 /* u32 mlmeautolevel = CARD_DEFAULT_MLME_MODE; */
132 /* /\* Let's see if the user passed a valid Linux Wireless mode *\/ */
133 /* if (*uwrq > IW_MODE_MONITOR || *uwrq < IW_MODE_AUTO) { */
134 /* printk(KERN_DEBUG */
135 /* "%s: %s() You passed a non-valid init_mode.\n", */
136 /* priv->ndev->name, __FUNCTION__); */
137 /* return -EINVAL; */
138 /* } */
140 /* down_write(&priv->mib_sem); */
142 /* if (prism54_mib_mode_helper(priv, *uwrq)) { */
143 /* up_write(&priv->mib_sem); */
144 /* return -EOPNOTSUPP; */
145 /* } */
147 /* /\* the ACL code needs an intermediate mlmeautolevel. The wpa stuff an */
148 /* * extended one. */
149 /* *\/ */
150 /* if ((*uwrq == IW_MODE_MASTER) && (priv->acl.policy != MAC_POLICY_OPEN)) */
151 /* mlmeautolevel = DOT11_MLME_INTERMEDIATE; */
152 /* if (priv->wpa) */
153 /* mlmeautolevel = DOT11_MLME_EXTENDED; */
155 /* mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel); */
157 /* mgt_commit(priv); */
158 /* priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) */
159 /* ? priv->monitor_type : ARPHRD_ETHER; */
160 /* up_write(&priv->mib_sem); */
162 return 0;
165 /* Use mib cache */
166 static int
167 prism54_get_mode(struct net_device *ndev, struct iw_request_info *info,
168 __u32 * uwrq, char *extra)
170 /* islpci_private *priv = netdev_priv(ndev); */
172 /* BUG_ON((priv->iw_mode < IW_MODE_AUTO) || (priv->iw_mode > */
173 /* IW_MODE_MONITOR)); */
174 *uwrq = IW_MODE_INFRA;
176 return 0;
179 /* we use DOT11_OID_EDTHRESHOLD. From what I guess the card will not try to
180 * emit data if (sensitivity > rssi - noise) (in dBm).
181 * prism54_set_sens does not seem to work.
184 static int
185 prism54_set_sens(struct net_device *ndev, struct iw_request_info *info,
186 struct iw_param *vwrq, char *extra)
188 /* islpci_private *priv = netdev_priv(ndev); */
189 /* u32 sens; */
191 /* /\* by default the card sets this to 20. *\/ */
192 /* sens = vwrq->disabled ? 20 : vwrq->value; */
194 /* return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens); */
195 return 0;
198 static int
199 prism54_get_sens(struct net_device *ndev, struct iw_request_info *info,
200 struct iw_param *vwrq, char *extra)
202 /* islpci_private *priv = netdev_priv(ndev); */
203 /* union oid_res_t r; */
204 /* int rvalue; */
206 /* rvalue = mgt_get_request(priv, DOT11_OID_EDTHRESHOLD, 0, NULL, &r); */
208 vwrq->value = 0;
209 vwrq->disabled = (vwrq->value == 0);
210 vwrq->fixed = 1;
212 return 0;
215 static int
216 prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
217 struct iw_point *dwrq, char *extra)
219 struct iw_range *range = (struct iw_range *) extra;
220 char *data;
221 int i, m, rvalue;
223 memset(range, 0, sizeof (struct iw_range));
224 dwrq->length = sizeof (struct iw_range);
226 /* set the wireless extension version number */
227 range->we_version_source = SUPPORTED_WIRELESS_EXT;
228 range->we_version_compiled = WIRELESS_EXT;
230 /* Now the encoding capabilities */
231 range->num_encoding_sizes = 3;
232 /* 64(40) bits WEP */
233 range->encoding_size[0] = 5;
234 /* 128(104) bits WEP */
235 range->encoding_size[1] = 13;
236 /* 256 bits for WPA-PSK */
237 range->encoding_size[2] = 32;
238 /* 4 keys are allowed */
239 range->max_encoding_tokens = 4;
241 /* we don't know the quality range... */
242 range->max_qual.level = 0;
243 range->max_qual.noise = 0;
244 range->max_qual.qual = 0;
245 /* these value describe an average quality. Needs more tweaking... */
246 range->avg_qual.level = -80; /* -80 dBm */
247 range->avg_qual.noise = 0; /* don't know what to put here */
248 range->avg_qual.qual = 0;
250 range->sensitivity = 200;
252 /* retry limit capabilities */
253 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
254 range->retry_flags = IW_RETRY_LIMIT;
255 range->r_time_flags = IW_RETRY_LIFETIME;
257 /* I don't know the range. Put stupid things here */
258 range->min_retry = 1;
259 range->max_retry = 65535;
260 range->min_r_time = 1024;
261 range->max_r_time = 65535 * 1024;
263 /* txpower is supported in dBm's */
264 range->txpower_capa = IW_TXPOW_DBM;
266 return 0;
269 /* Set AP address*/
271 static int
272 prism54_set_wap(struct net_device *ndev, struct iw_request_info *info,
273 struct sockaddr *awrq, char *extra)
275 /* islpci_private *priv = netdev_priv(ndev); */
276 /* char bssid[6]; */
277 /* int rvalue; */
279 /* if (awrq->sa_family != ARPHRD_ETHER) */
280 /* return -EINVAL; */
282 /* /\* prepare the structure for the set object *\/ */
283 /* memcpy(&bssid[0], awrq->sa_data, 6); */
285 /* /\* set the bssid -- does this make sense when in AP mode? *\/ */
286 /* rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid); */
288 return -EINPROGRESS; /* Call commit handler */
291 /* get AP address*/
293 static int
294 prism54_get_wap(struct net_device *ndev, struct iw_request_info *info,
295 struct sockaddr *awrq, char *extra)
297 int rvalue;
299 rvalue = 0;
300 // awrq->sa_family = ARPHRD_ETHER;
302 return rvalue;
305 static int
306 prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
307 struct iw_param *vwrq, char *extra)
309 /* hehe the device does this automagicaly */
310 return 0;
314 static const iw_handler prism54_handler[] = {
315 (iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
316 (iw_handler) prism54_get_name, /* SIOCGIWNAME */
317 (iw_handler) NULL, /* SIOCSIWNWID */
318 (iw_handler) NULL, /* SIOCGIWNWID */
319 (iw_handler) prism54_set_freq, /* SIOCSIWFREQ */
320 (iw_handler) prism54_get_freq, /* SIOCGIWFREQ */
321 (iw_handler) prism54_set_mode, /* SIOCSIWMODE */
322 (iw_handler) prism54_get_mode, /* SIOCGIWMODE */
323 (iw_handler) prism54_set_sens, /* SIOCSIWSENS */
324 (iw_handler) prism54_get_sens, /* SIOCGIWSENS */
325 (iw_handler) NULL, /* SIOCSIWRANGE */
326 (iw_handler) prism54_get_range, /* SIOCGIWRANGE */
327 (iw_handler) NULL, /* SIOCSIWPRIV */
328 (iw_handler) NULL, /* SIOCGIWPRIV */
329 (iw_handler) NULL, /* SIOCSIWSTATS */
330 (iw_handler) NULL, /* SIOCGIWSTATS */
331 (iw_handler) NULL, // prism54_set_spy, /* SIOCSIWSPY */
332 (iw_handler) NULL, // iw_handler_get_spy, /* SIOCGIWSPY */
333 (iw_handler) NULL, // iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
334 (iw_handler) NULL, // iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
335 (iw_handler) prism54_set_wap, /* SIOCSIWAP */
336 (iw_handler) prism54_get_wap, /* SIOCGIWAP */
337 (iw_handler) NULL, /* -- hole -- */
338 (iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
339 (iw_handler) NULL, // (iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
340 (iw_handler) NULL, // (iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
341 (iw_handler) NULL, // (iw_handler) prism54_set_essid, /* SIOCSIWESSID */
342 (iw_handler) NULL, // (iw_handler) prism54_get_essid, /* SIOCGIWESSID */
343 (iw_handler) NULL, // (iw_handler) prism54_set_nick, /* SIOCSIWNICKN */
344 (iw_handler) NULL, // (iw_handler) prism54_get_nick, /* SIOCGIWNICKN */
345 (iw_handler) NULL, /* -- hole -- */
346 (iw_handler) NULL, /* -- hole -- */
347 (iw_handler) NULL, // (iw_handler) prism54_set_rate, /* SIOCSIWRATE */
348 (iw_handler) NULL, // (iw_handler) prism54_get_rate, /* SIOCGIWRATE */
349 (iw_handler) NULL, // (iw_handler) prism54_set_rts, /* SIOCSIWRTS */
350 (iw_handler) NULL, // (iw_handler) prism54_get_rts, /* SIOCGIWRTS */
351 (iw_handler) NULL, // (iw_handler) prism54_set_frag, /* SIOCSIWFRAG */
352 (iw_handler) NULL, // (iw_handler) prism54_get_frag, /* SIOCGIWFRAG */
353 (iw_handler) NULL, // (iw_handler) prism54_set_txpower, /* SIOCSIWTXPOW */
354 (iw_handler) NULL, // (iw_handler) prism54_get_txpower, /* SIOCGIWTXPOW */
355 (iw_handler) NULL, // (iw_handler) prism54_set_retry, /* SIOCSIWRETRY */
356 (iw_handler) NULL, // (iw_handler) prism54_get_retry, /* SIOCGIWRETRY */
357 (iw_handler) NULL, // (iw_handler) prism54_set_encode, /* SIOCSIWENCODE */
358 (iw_handler) NULL, // (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
359 (iw_handler) NULL, /* SIOCSIWPOWER */
360 (iw_handler) NULL, /* SIOCGIWPOWER */
363 static const struct iw_priv_args prism54_private_args[] = {};
365 static const iw_handler prism54_private_handler[] = {};
367 const struct iw_handler_def p54u_handler_def = {
368 .num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
369 .num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
370 .num_private_args =
371 sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
372 .standard = (iw_handler *) prism54_handler,
373 .private = (iw_handler *) prism54_private_handler,
374 .private_args = (struct iw_priv_args *) prism54_private_args,
375 .spy_offset = 0,//offsetof(islpci_private, spy_data),