1 #include <linux/wireless.h>
2 #include <linux/netdevice.h> /* needed by iw_handler */
3 #include <net/iw_handler.h>
6 #include "prism54_usb.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
;
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
));
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);
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
;
64 prism54_commit(struct net_device
*ndev
, struct iw_request_info
*info
,
65 char *cwrq
, char *extra
)
71 prism54_get_name(struct net_device
*ndev
, struct iw_request_info
*info
,
72 char *cwrq
, char *extra
)
77 capabilities
= "IEEE 802.11b/g"; /* Default */
79 strncpy(cwrq
, capabilities
, IFNAMSIZ
);
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;
93 channel_packet
=kmalloc(FULL_TX_CONTROL_CHANNEL
,GFP_KERNEL
);
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 */
103 /* we dont handle freq_to_channel yet */
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
);
116 prism54_get_freq(struct net_device
*ndev
, struct iw_request_info
*info
,
117 struct iw_freq
*fwrq
, char *extra
)
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; */
140 /* down_write(&priv->mib_sem); */
142 /* if (prism54_mib_mode_helper(priv, *uwrq)) { */
143 /* up_write(&priv->mib_sem); */
144 /* return -EOPNOTSUPP; */
147 /* /\* the ACL code needs an intermediate mlmeautolevel. The wpa stuff an */
148 /* * extended one. */
150 /* if ((*uwrq == IW_MODE_MASTER) && (priv->acl.policy != MAC_POLICY_OPEN)) */
151 /* mlmeautolevel = DOT11_MLME_INTERMEDIATE; */
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); */
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
;
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.
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); */
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); */
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; */
206 /* rvalue = mgt_get_request(priv, DOT11_OID_EDTHRESHOLD, 0, NULL, &r); */
209 vwrq
->disabled
= (vwrq
->value
== 0);
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
;
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
;
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); */
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 */
294 prism54_get_wap(struct net_device
*ndev
, struct iw_request_info
*info
,
295 struct sockaddr
*awrq
, char *extra
)
300 // awrq->sa_family = ARPHRD_ETHER;
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 */
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
),
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),