aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ray_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ray_cs.c')
-rw-r--r--drivers/net/wireless/ray_cs.c865
1 files changed, 450 insertions, 415 deletions
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 0e0ba614259a..74d66eeddef2 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -64,7 +64,6 @@
64#define WIRELESS_SPY /* Enable spying addresses */ 64#define WIRELESS_SPY /* Enable spying addresses */
65/* Definitions we need for spy */ 65/* Definitions we need for spy */
66typedef struct iw_statistics iw_stats; 66typedef struct iw_statistics iw_stats;
67typedef struct iw_quality iw_qual;
68typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ 67typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
69 68
70#include "rayctl.h" 69#include "rayctl.h"
@@ -101,7 +100,6 @@ static int ray_dev_close(struct net_device *dev);
101static int ray_dev_config(struct net_device *dev, struct ifmap *map); 100static int ray_dev_config(struct net_device *dev, struct ifmap *map);
102static struct net_device_stats *ray_get_stats(struct net_device *dev); 101static struct net_device_stats *ray_get_stats(struct net_device *dev);
103static int ray_dev_init(struct net_device *dev); 102static int ray_dev_init(struct net_device *dev);
104static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
105 103
106static struct ethtool_ops netdev_ethtool_ops; 104static struct ethtool_ops netdev_ethtool_ops;
107 105
@@ -114,9 +112,8 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
114static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, 112static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
115 unsigned char *data); 113 unsigned char *data);
116static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); 114static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
117#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */
118static iw_stats * ray_get_wireless_stats(struct net_device * dev); 115static iw_stats * ray_get_wireless_stats(struct net_device * dev);
119#endif /* WIRELESS_EXT > 7 */ 116static const struct iw_handler_def ray_handler_def;
120 117
121/***** Prototypes for raylink functions **************************************/ 118/***** Prototypes for raylink functions **************************************/
122static int asc_to_int(char a); 119static int asc_to_int(char a);
@@ -373,11 +370,12 @@ static dev_link_t *ray_attach(void)
373 dev->hard_start_xmit = &ray_dev_start_xmit; 370 dev->hard_start_xmit = &ray_dev_start_xmit;
374 dev->set_config = &ray_dev_config; 371 dev->set_config = &ray_dev_config;
375 dev->get_stats = &ray_get_stats; 372 dev->get_stats = &ray_get_stats;
376 dev->do_ioctl = &ray_dev_ioctl;
377 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 373 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
378#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ 374 dev->wireless_handlers = &ray_handler_def;
379 dev->get_wireless_stats = ray_get_wireless_stats; 375#ifdef WIRELESS_SPY
380#endif 376 local->wireless_data.spy_data = &local->spy_data;
377 dev->wireless_data = &local->wireless_data;
378#endif /* WIRELESS_SPY */
381 379
382 dev->set_multicast_list = &set_multicast_list; 380 dev->set_multicast_list = &set_multicast_list;
383 381
@@ -1201,436 +1199,420 @@ static struct ethtool_ops netdev_ethtool_ops = {
1201 1199
1202/*====================================================================*/ 1200/*====================================================================*/
1203 1201
1204static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1202/*------------------------------------------------------------------*/
1203/*
1204 * Wireless Handler : get protocol name
1205 */
1206static int ray_get_name(struct net_device *dev,
1207 struct iw_request_info *info,
1208 char *cwrq,
1209 char *extra)
1205{ 1210{
1206 ray_dev_t *local = (ray_dev_t *)dev->priv; 1211 strcpy(cwrq, "IEEE 802.11-FH");
1207 dev_link_t *link = local->finder; 1212 return 0;
1208 int err = 0; 1213}
1209#if WIRELESS_EXT > 7
1210 struct iwreq *wrq = (struct iwreq *) ifr;
1211#endif /* WIRELESS_EXT > 7 */
1212#ifdef WIRELESS_SPY
1213 struct sockaddr address[IW_MAX_SPY];
1214#endif /* WIRELESS_SPY */
1215 1214
1216 if (!(link->state & DEV_PRESENT)) { 1215/*------------------------------------------------------------------*/
1217 DEBUG(2,"ray_dev_ioctl - device not present\n"); 1216/*
1218 return -1; 1217 * Wireless Handler : set frequency
1219 } 1218 */
1220 DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); 1219static int ray_set_freq(struct net_device *dev,
1221 /* Validate the command */ 1220 struct iw_request_info *info,
1222 switch (cmd) 1221 struct iw_freq *fwrq,
1223 { 1222 char *extra)
1224#if WIRELESS_EXT > 7 1223{
1225 /* --------------- WIRELESS EXTENSIONS --------------- */ 1224 ray_dev_t *local = (ray_dev_t *)dev->priv;
1226 /* Get name */ 1225 int err = -EINPROGRESS; /* Call commit handler */
1227 case SIOCGIWNAME:
1228 strcpy(wrq->u.name, "IEEE 802.11-FH");
1229 break;
1230
1231 /* Get frequency/channel */
1232 case SIOCGIWFREQ:
1233 wrq->u.freq.m = local->sparm.b5.a_hop_pattern;
1234 wrq->u.freq.e = 0;
1235 break;
1236
1237 /* Set frequency/channel */
1238 case SIOCSIWFREQ:
1239 /* Reject if card is already initialised */
1240 if(local->card_status != CARD_AWAITING_PARAM)
1241 {
1242 err = -EBUSY;
1243 break;
1244 }
1245 1226
1246 /* Setting by channel number */ 1227 /* Reject if card is already initialised */
1247 if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0)) 1228 if(local->card_status != CARD_AWAITING_PARAM)
1248 err = -EOPNOTSUPP; 1229 return -EBUSY;
1249 else
1250 local->sparm.b5.a_hop_pattern = wrq->u.freq.m;
1251 break;
1252 1230
1253 /* Get current network name (ESSID) */ 1231 /* Setting by channel number */
1254 case SIOCGIWESSID: 1232 if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0))
1255 if (wrq->u.data.pointer) 1233 err = -EOPNOTSUPP;
1256 { 1234 else
1257 char essid[IW_ESSID_MAX_SIZE + 1]; 1235 local->sparm.b5.a_hop_pattern = fwrq->m;
1258 /* Get the essid that was set */
1259 memcpy(essid, local->sparm.b5.a_current_ess_id,
1260 IW_ESSID_MAX_SIZE);
1261 essid[IW_ESSID_MAX_SIZE] = '\0';
1262
1263 /* Push it out ! */
1264 wrq->u.data.length = strlen(essid) + 1;
1265 wrq->u.data.flags = 1; /* active */
1266 if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)))
1267 err = -EFAULT;
1268 }
1269 break;
1270 1236
1271 /* Set desired network name (ESSID) */ 1237 return err;
1272 case SIOCSIWESSID: 1238}
1273 /* Reject if card is already initialised */ 1239
1274 if(local->card_status != CARD_AWAITING_PARAM) 1240/*------------------------------------------------------------------*/
1275 { 1241/*
1276 err = -EBUSY; 1242 * Wireless Handler : get frequency
1277 break; 1243 */
1278 } 1244static int ray_get_freq(struct net_device *dev,
1245 struct iw_request_info *info,
1246 struct iw_freq *fwrq,
1247 char *extra)
1248{
1249 ray_dev_t *local = (ray_dev_t *)dev->priv;
1279 1250
1280 if (wrq->u.data.pointer) 1251 fwrq->m = local->sparm.b5.a_hop_pattern;
1281 { 1252 fwrq->e = 0;
1282 char card_essid[IW_ESSID_MAX_SIZE + 1]; 1253 return 0;
1283 1254}
1284 /* Check if we asked for `any' */ 1255
1285 if(wrq->u.data.flags == 0) 1256/*------------------------------------------------------------------*/
1286 { 1257/*
1258 * Wireless Handler : set ESSID
1259 */
1260static int ray_set_essid(struct net_device *dev,
1261 struct iw_request_info *info,
1262 struct iw_point *dwrq,
1263 char *extra)
1264{
1265 ray_dev_t *local = (ray_dev_t *)dev->priv;
1266
1267 /* Reject if card is already initialised */
1268 if(local->card_status != CARD_AWAITING_PARAM)
1269 return -EBUSY;
1270
1271 /* Check if we asked for `any' */
1272 if(dwrq->flags == 0) {
1287 /* Corey : can you do that ? */ 1273 /* Corey : can you do that ? */
1288 err = -EOPNOTSUPP; 1274 return -EOPNOTSUPP;
1289 } 1275 } else {
1290 else
1291 {
1292 /* Check the size of the string */ 1276 /* Check the size of the string */
1293 if(wrq->u.data.length > 1277 if(dwrq->length > IW_ESSID_MAX_SIZE + 1) {
1294 IW_ESSID_MAX_SIZE + 1) 1278 return -E2BIG;
1295 {
1296 err = -E2BIG;
1297 break;
1298 }
1299 if (copy_from_user(card_essid,
1300 wrq->u.data.pointer,
1301 wrq->u.data.length)) {
1302 err = -EFAULT;
1303 break;
1304 } 1279 }
1305 card_essid[IW_ESSID_MAX_SIZE] = '\0';
1306 1280
1307 /* Set the ESSID in the card */ 1281 /* Set the ESSID in the card */
1308 memcpy(local->sparm.b5.a_current_ess_id, card_essid, 1282 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1309 IW_ESSID_MAX_SIZE); 1283 memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length);
1310 }
1311 } 1284 }
1312 break;
1313
1314 /* Get current Access Point (BSSID in our case) */
1315 case SIOCGIWAP:
1316 memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN);
1317 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
1318 break;
1319
1320 /* Get the current bit-rate */
1321 case SIOCGIWRATE:
1322 if(local->net_default_tx_rate == 3)
1323 wrq->u.bitrate.value = 2000000; /* Hum... */
1324 else
1325 wrq->u.bitrate.value = local->net_default_tx_rate * 500000;
1326 wrq->u.bitrate.fixed = 0; /* We are in auto mode */
1327 break;
1328
1329 /* Set the desired bit-rate */
1330 case SIOCSIWRATE:
1331 /* Check if rate is in range */
1332 if((wrq->u.bitrate.value != 1000000) &&
1333 (wrq->u.bitrate.value != 2000000))
1334 {
1335 err = -EINVAL;
1336 break;
1337 }
1338 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1339 if((local->fw_ver == 0x55) && /* Please check */
1340 (wrq->u.bitrate.value == 2000000))
1341 local->net_default_tx_rate = 3;
1342 else
1343 local->net_default_tx_rate = wrq->u.bitrate.value/500000;
1344 break;
1345
1346 /* Get the current RTS threshold */
1347 case SIOCGIWRTS:
1348 wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1349 + local->sparm.b5.a_rts_threshold[1];
1350#if WIRELESS_EXT > 8
1351 wrq->u.rts.disabled = (wrq->u.rts.value == 32767);
1352#endif /* WIRELESS_EXT > 8 */
1353 wrq->u.rts.fixed = 1;
1354 break;
1355
1356 /* Set the desired RTS threshold */
1357 case SIOCSIWRTS:
1358 {
1359 int rthr = wrq->u.rts.value;
1360 1285
1361 /* Reject if card is already initialised */ 1286 return -EINPROGRESS; /* Call commit handler */
1362 if(local->card_status != CARD_AWAITING_PARAM) 1287}
1363 {
1364 err = -EBUSY;
1365 break;
1366 }
1367 1288
1368 /* if(wrq->u.rts.fixed == 0) we should complain */ 1289/*------------------------------------------------------------------*/
1369#if WIRELESS_EXT > 8 1290/*
1370 if(wrq->u.rts.disabled) 1291 * Wireless Handler : get ESSID
1371 rthr = 32767; 1292 */
1293static int ray_get_essid(struct net_device *dev,
1294 struct iw_request_info *info,
1295 struct iw_point *dwrq,
1296 char *extra)
1297{
1298 ray_dev_t *local = (ray_dev_t *)dev->priv;
1299
1300 /* Get the essid that was set */
1301 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1302 extra[IW_ESSID_MAX_SIZE] = '\0';
1303
1304 /* Push it out ! */
1305 dwrq->length = strlen(extra) + 1;
1306 dwrq->flags = 1; /* active */
1307
1308 return 0;
1309}
1310
1311/*------------------------------------------------------------------*/
1312/*
1313 * Wireless Handler : get AP address
1314 */
1315static int ray_get_wap(struct net_device *dev,
1316 struct iw_request_info *info,
1317 struct sockaddr *awrq,
1318 char *extra)
1319{
1320 ray_dev_t *local = (ray_dev_t *)dev->priv;
1321
1322 memcpy(awrq->sa_data, local->bss_id, ETH_ALEN);
1323 awrq->sa_family = ARPHRD_ETHER;
1324
1325 return 0;
1326}
1327
1328/*------------------------------------------------------------------*/
1329/*
1330 * Wireless Handler : set Bit-Rate
1331 */
1332static int ray_set_rate(struct net_device *dev,
1333 struct iw_request_info *info,
1334 struct iw_param *vwrq,
1335 char *extra)
1336{
1337 ray_dev_t *local = (ray_dev_t *)dev->priv;
1338
1339 /* Reject if card is already initialised */
1340 if(local->card_status != CARD_AWAITING_PARAM)
1341 return -EBUSY;
1342
1343 /* Check if rate is in range */
1344 if((vwrq->value != 1000000) && (vwrq->value != 2000000))
1345 return -EINVAL;
1346
1347 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1348 if((local->fw_ver == 0x55) && /* Please check */
1349 (vwrq->value == 2000000))
1350 local->net_default_tx_rate = 3;
1372 else 1351 else
1373#endif /* WIRELESS_EXT > 8 */ 1352 local->net_default_tx_rate = vwrq->value/500000;
1374 if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ 1353
1375 { 1354 return 0;
1376 err = -EINVAL; 1355}
1377 break; 1356
1378 } 1357/*------------------------------------------------------------------*/
1358/*
1359 * Wireless Handler : get Bit-Rate
1360 */
1361static int ray_get_rate(struct net_device *dev,
1362 struct iw_request_info *info,
1363 struct iw_param *vwrq,
1364 char *extra)
1365{
1366 ray_dev_t *local = (ray_dev_t *)dev->priv;
1367
1368 if(local->net_default_tx_rate == 3)
1369 vwrq->value = 2000000; /* Hum... */
1370 else
1371 vwrq->value = local->net_default_tx_rate * 500000;
1372 vwrq->fixed = 0; /* We are in auto mode */
1373
1374 return 0;
1375}
1376
1377/*------------------------------------------------------------------*/
1378/*
1379 * Wireless Handler : set RTS threshold
1380 */
1381static int ray_set_rts(struct net_device *dev,
1382 struct iw_request_info *info,
1383 struct iw_param *vwrq,
1384 char *extra)
1385{
1386 ray_dev_t *local = (ray_dev_t *)dev->priv;
1387 int rthr = vwrq->value;
1388
1389 /* Reject if card is already initialised */
1390 if(local->card_status != CARD_AWAITING_PARAM)
1391 return -EBUSY;
1392
1393 /* if(wrq->u.rts.fixed == 0) we should complain */
1394 if(vwrq->disabled)
1395 rthr = 32767;
1396 else {
1397 if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
1398 return -EINVAL;
1399 }
1379 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF; 1400 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1380 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF; 1401 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1381 }
1382 break;
1383 1402
1384 /* Get the current fragmentation threshold */ 1403 return -EINPROGRESS; /* Call commit handler */
1385 case SIOCGIWFRAG: 1404}
1386 wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1387 + local->sparm.b5.a_frag_threshold[1];
1388#if WIRELESS_EXT > 8
1389 wrq->u.frag.disabled = (wrq->u.frag.value == 32767);
1390#endif /* WIRELESS_EXT > 8 */
1391 wrq->u.frag.fixed = 1;
1392 break;
1393 1405
1394 /* Set the desired fragmentation threshold */
1395 case SIOCSIWFRAG:
1396 {
1397 int fthr = wrq->u.frag.value;
1398 1406
1399 /* Reject if card is already initialised */ 1407/*------------------------------------------------------------------*/
1400 if(local->card_status != CARD_AWAITING_PARAM) 1408/*
1401 { 1409 * Wireless Handler : get RTS threshold
1402 err = -EBUSY; 1410 */
1403 break; 1411static int ray_get_rts(struct net_device *dev,
1404 } 1412 struct iw_request_info *info,
1413 struct iw_param *vwrq,
1414 char *extra)
1415{
1416 ray_dev_t *local = (ray_dev_t *)dev->priv;
1417
1418 vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8)
1419 + local->sparm.b5.a_rts_threshold[1];
1420 vwrq->disabled = (vwrq->value == 32767);
1421 vwrq->fixed = 1;
1422
1423 return 0;
1424}
1425
1426/*------------------------------------------------------------------*/
1427/*
1428 * Wireless Handler : set Fragmentation threshold
1429 */
1430static int ray_set_frag(struct net_device *dev,
1431 struct iw_request_info *info,
1432 struct iw_param *vwrq,
1433 char *extra)
1434{
1435 ray_dev_t *local = (ray_dev_t *)dev->priv;
1436 int fthr = vwrq->value;
1437
1438 /* Reject if card is already initialised */
1439 if(local->card_status != CARD_AWAITING_PARAM)
1440 return -EBUSY;
1405 1441
1406 /* if(wrq->u.frag.fixed == 0) should complain */ 1442 /* if(wrq->u.frag.fixed == 0) should complain */
1407#if WIRELESS_EXT > 8 1443 if(vwrq->disabled)
1408 if(wrq->u.frag.disabled) 1444 fthr = 32767;
1409 fthr = 32767; 1445 else {
1410 else 1446 if((fthr < 256) || (fthr > 2347)) /* To check out ! */
1411#endif /* WIRELESS_EXT > 8 */ 1447 return -EINVAL;
1412 if((fthr < 256) || (fthr > 2347)) /* To check out ! */ 1448 }
1413 {
1414 err = -EINVAL;
1415 break;
1416 }
1417 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF; 1449 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1418 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF; 1450 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1419 }
1420 break;
1421 1451
1422#endif /* WIRELESS_EXT > 7 */ 1452 return -EINPROGRESS; /* Call commit handler */
1423#if WIRELESS_EXT > 8 1453}
1424 1454
1425 /* Get the current mode of operation */ 1455/*------------------------------------------------------------------*/
1426 case SIOCGIWMODE: 1456/*
1427 if(local->sparm.b5.a_network_type) 1457 * Wireless Handler : get Fragmentation threshold
1428 wrq->u.mode = IW_MODE_INFRA; 1458 */
1429 else 1459static int ray_get_frag(struct net_device *dev,
1430 wrq->u.mode = IW_MODE_ADHOC; 1460 struct iw_request_info *info,
1431 break; 1461 struct iw_param *vwrq,
1462 char *extra)
1463{
1464 ray_dev_t *local = (ray_dev_t *)dev->priv;
1432 1465
1433 /* Set the current mode of operation */ 1466 vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8)
1434 case SIOCSIWMODE: 1467 + local->sparm.b5.a_frag_threshold[1];
1435 { 1468 vwrq->disabled = (vwrq->value == 32767);
1469 vwrq->fixed = 1;
1470
1471 return 0;
1472}
1473
1474/*------------------------------------------------------------------*/
1475/*
1476 * Wireless Handler : set Mode of Operation
1477 */
1478static int ray_set_mode(struct net_device *dev,
1479 struct iw_request_info *info,
1480 __u32 *uwrq,
1481 char *extra)
1482{
1483 ray_dev_t *local = (ray_dev_t *)dev->priv;
1484 int err = -EINPROGRESS; /* Call commit handler */
1436 char card_mode = 1; 1485 char card_mode = 1;
1437
1438 /* Reject if card is already initialised */
1439 if(local->card_status != CARD_AWAITING_PARAM)
1440 {
1441 err = -EBUSY;
1442 break;
1443 }
1444 1486
1445 switch (wrq->u.mode) 1487 /* Reject if card is already initialised */
1488 if(local->card_status != CARD_AWAITING_PARAM)
1489 return -EBUSY;
1490
1491 switch (*uwrq)
1446 { 1492 {
1447 case IW_MODE_ADHOC: 1493 case IW_MODE_ADHOC:
1448 card_mode = 0; 1494 card_mode = 0;
1449 // Fall through 1495 // Fall through
1450 case IW_MODE_INFRA: 1496 case IW_MODE_INFRA:
1451 local->sparm.b5.a_network_type = card_mode; 1497 local->sparm.b5.a_network_type = card_mode;
1452 break; 1498 break;
1453 default: 1499 default:
1454 err = -EINVAL; 1500 err = -EINVAL;
1455 } 1501 }
1456 }
1457 break;
1458 1502
1459#endif /* WIRELESS_EXT > 8 */ 1503 return err;
1460#if WIRELESS_EXT > 7 1504}
1461 /* ------------------ IWSPY SUPPORT ------------------ */
1462 /* Define the range (variations) of above parameters */
1463 case SIOCGIWRANGE:
1464 /* Basic checking... */
1465 if(wrq->u.data.pointer != (caddr_t) 0)
1466 {
1467 struct iw_range range;
1468 memset((char *) &range, 0, sizeof(struct iw_range));
1469
1470 /* Set the length (very important for backward compatibility) */
1471 wrq->u.data.length = sizeof(struct iw_range);
1472
1473#if WIRELESS_EXT > 10
1474 /* Set the Wireless Extension versions */
1475 range.we_version_compiled = WIRELESS_EXT;
1476 range.we_version_source = 9;
1477#endif /* WIRELESS_EXT > 10 */
1478
1479 /* Set information in the range struct */
1480 range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */
1481 range.num_channels = hop_pattern_length[(int)country];
1482 range.num_frequency = 0;
1483 range.max_qual.qual = 0;
1484 range.max_qual.level = 255; /* What's the correct value ? */
1485 range.max_qual.noise = 255; /* Idem */
1486 range.num_bitrates = 2;
1487 range.bitrate[0] = 1000000; /* 1 Mb/s */
1488 range.bitrate[1] = 2000000; /* 2 Mb/s */
1489
1490 /* Copy structure to the user buffer */
1491 if(copy_to_user(wrq->u.data.pointer, &range,
1492 sizeof(struct iw_range)))
1493 err = -EFAULT;
1494 }
1495 break;
1496 1505
1497#ifdef WIRELESS_SPY 1506/*------------------------------------------------------------------*/
1498 /* Set addresses to spy */ 1507/*
1499 case SIOCSIWSPY: 1508 * Wireless Handler : get Mode of Operation
1500 /* Check the number of addresses */ 1509 */
1501 if(wrq->u.data.length > IW_MAX_SPY) 1510static int ray_get_mode(struct net_device *dev,
1502 { 1511 struct iw_request_info *info,
1503 err = -E2BIG; 1512 __u32 *uwrq,
1504 break; 1513 char *extra)
1505 } 1514{
1506 local->spy_number = wrq->u.data.length; 1515 ray_dev_t *local = (ray_dev_t *)dev->priv;
1507 1516
1508 /* If there is some addresses to copy */ 1517 if(local->sparm.b5.a_network_type)
1509 if(local->spy_number > 0) 1518 *uwrq = IW_MODE_INFRA;
1510 { 1519 else
1511 int i; 1520 *uwrq = IW_MODE_ADHOC;
1512
1513 /* Copy addresses to the driver */
1514 if(copy_from_user(address, wrq->u.data.pointer,
1515 sizeof(struct sockaddr) * local->spy_number))
1516 {
1517 err = -EFAULT;
1518 break;
1519 }
1520
1521 /* Copy addresses to the lp structure */
1522 for(i = 0; i < local->spy_number; i++)
1523 memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
1524
1525 /* Reset structure... */
1526 memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
1527
1528#ifdef DEBUG_IOCTL_INFO
1529 printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n");
1530 for(i = 0; i < local->spy_number; i++)
1531 printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n",
1532 local->spy_address[i][0],
1533 local->spy_address[i][1],
1534 local->spy_address[i][2],
1535 local->spy_address[i][3],
1536 local->spy_address[i][4],
1537 local->spy_address[i][5]);
1538#endif /* DEBUG_IOCTL_INFO */
1539 }
1540 break;
1541 1521
1542 /* Get the spy list and spy stats */ 1522 return 0;
1543 case SIOCGIWSPY: 1523}
1544 /* Set the number of addresses */
1545 wrq->u.data.length = local->spy_number;
1546 1524
1547 /* If the user want to have the addresses back... */ 1525/*------------------------------------------------------------------*/
1548 if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) 1526/*
1549 { 1527 * Wireless Handler : get range info
1550 int i; 1528 */
1551 1529static int ray_get_range(struct net_device *dev,
1552 /* Copy addresses from the lp structure */ 1530 struct iw_request_info *info,
1553 for(i = 0; i < local->spy_number; i++) 1531 struct iw_point *dwrq,
1554 { 1532 char *extra)
1555 memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); 1533{
1556 address[i].sa_family = ARPHRD_ETHER; 1534 struct iw_range *range = (struct iw_range *) extra;
1557 } 1535
1558 1536 memset((char *) range, 0, sizeof(struct iw_range));
1559 /* Copy addresses to the user buffer */ 1537
1560 if(copy_to_user(wrq->u.data.pointer, address, 1538 /* Set the length (very important for backward compatibility) */
1561 sizeof(struct sockaddr) * local->spy_number)) 1539 dwrq->length = sizeof(struct iw_range);
1562 { 1540
1563 err = -EFAULT; 1541 /* Set the Wireless Extension versions */
1564 break; 1542 range->we_version_compiled = WIRELESS_EXT;
1565 } 1543 range->we_version_source = 9;
1566 1544
1567 /* Copy stats to the user buffer (just after) */ 1545 /* Set information in the range struct */
1568 if(copy_to_user(wrq->u.data.pointer + 1546 range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */
1569 (sizeof(struct sockaddr) * local->spy_number), 1547 range->num_channels = hop_pattern_length[(int)country];
1570 local->spy_stat, sizeof(iw_qual) * local->spy_number)) 1548 range->num_frequency = 0;
1571 { 1549 range->max_qual.qual = 0;
1572 err = -EFAULT; 1550 range->max_qual.level = 255; /* What's the correct value ? */
1573 break; 1551 range->max_qual.noise = 255; /* Idem */
1574 } 1552 range->num_bitrates = 2;
1575 1553 range->bitrate[0] = 1000000; /* 1 Mb/s */
1576 /* Reset updated flags */ 1554 range->bitrate[1] = 2000000; /* 2 Mb/s */
1577 for(i = 0; i < local->spy_number; i++) 1555 return 0;
1578 local->spy_stat[i].updated = 0x0; 1556}
1579 } /* if(pointer != NULL) */
1580
1581 break;
1582#endif /* WIRELESS_SPY */
1583 1557
1584 /* ------------------ PRIVATE IOCTL ------------------ */ 1558/*------------------------------------------------------------------*/
1585#ifndef SIOCIWFIRSTPRIV 1559/*
1586#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE 1560 * Wireless Private Handler : set framing mode
1587#endif /* SIOCIWFIRSTPRIV */ 1561 */
1588#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ 1562static int ray_set_framing(struct net_device *dev,
1589#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ 1563 struct iw_request_info *info,
1590#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ 1564 union iwreq_data *wrqu,
1591 case SIOCSIPFRAMING: 1565 char *extra)
1592 if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */ 1566{
1593 { 1567 translate = *(extra); /* Set framing mode */
1594 err = -EPERM;
1595 break;
1596 }
1597 translate = *(wrq->u.name); /* Set framing mode */
1598 break;
1599 case SIOCGIPFRAMING:
1600 *(wrq->u.name) = translate;
1601 break;
1602 case SIOCGIPCOUNTRY:
1603 *(wrq->u.name) = country;
1604 break;
1605 case SIOCGIWPRIV:
1606 /* Export our "private" intercace */
1607 if(wrq->u.data.pointer != (caddr_t) 0)
1608 {
1609 struct iw_priv_args priv[] =
1610 { /* cmd, set_args, get_args, name */
1611 { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
1612 { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
1613 { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
1614 };
1615 /* Set the number of ioctl available */
1616 wrq->u.data.length = 3;
1617 /* Copy structure to the user buffer */
1618 if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
1619 sizeof(priv)))
1620 err = -EFAULT;
1621 }
1622 break;
1623#endif /* WIRELESS_EXT > 7 */
1624 1568
1569 return 0;
1570}
1625 1571
1626 default: 1572/*------------------------------------------------------------------*/
1627 DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); 1573/*
1628 err = -EOPNOTSUPP; 1574 * Wireless Private Handler : get framing mode
1629 } 1575 */
1630 return err; 1576static int ray_get_framing(struct net_device *dev,
1631} /* end ray_dev_ioctl */ 1577 struct iw_request_info *info,
1632/*===========================================================================*/ 1578 union iwreq_data *wrqu,
1633#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ 1579 char *extra)
1580{
1581 *(extra) = translate;
1582
1583 return 0;
1584}
1585
1586/*------------------------------------------------------------------*/
1587/*
1588 * Wireless Private Handler : get country
1589 */
1590static int ray_get_country(struct net_device *dev,
1591 struct iw_request_info *info,
1592 union iwreq_data *wrqu,
1593 char *extra)
1594{
1595 *(extra) = country;
1596
1597 return 0;
1598}
1599
1600/*------------------------------------------------------------------*/
1601/*
1602 * Commit handler : called after a bunch of SET operations
1603 */
1604static int ray_commit(struct net_device *dev,
1605 struct iw_request_info *info, /* NULL */
1606 void *zwrq, /* NULL */
1607 char *extra) /* NULL */
1608{
1609 return 0;
1610}
1611
1612/*------------------------------------------------------------------*/
1613/*
1614 * Stats handler : return Wireless Stats
1615 */
1634static iw_stats * ray_get_wireless_stats(struct net_device * dev) 1616static iw_stats * ray_get_wireless_stats(struct net_device * dev)
1635{ 1617{
1636 ray_dev_t * local = (ray_dev_t *) dev->priv; 1618 ray_dev_t * local = (ray_dev_t *) dev->priv;
@@ -1642,13 +1624,13 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
1642 1624
1643 local->wstats.status = local->card_status; 1625 local->wstats.status = local->card_status;
1644#ifdef WIRELESS_SPY 1626#ifdef WIRELESS_SPY
1645 if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) 1627 if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0))
1646 { 1628 {
1647 /* Get it from the first node in spy list */ 1629 /* Get it from the first node in spy list */
1648 local->wstats.qual.qual = local->spy_stat[0].qual; 1630 local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
1649 local->wstats.qual.level = local->spy_stat[0].level; 1631 local->wstats.qual.level = local->spy_data.spy_stat[0].level;
1650 local->wstats.qual.noise = local->spy_stat[0].noise; 1632 local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
1651 local->wstats.qual.updated = local->spy_stat[0].updated; 1633 local->wstats.qual.updated = local->spy_data.spy_stat[0].updated;
1652 } 1634 }
1653#endif /* WIRELESS_SPY */ 1635#endif /* WIRELESS_SPY */
1654 1636
@@ -1659,7 +1641,65 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
1659 1641
1660 return &local->wstats; 1642 return &local->wstats;
1661} /* end ray_get_wireless_stats */ 1643} /* end ray_get_wireless_stats */
1662#endif /* WIRELESS_EXT > 7 */ 1644
1645/*------------------------------------------------------------------*/
1646/*
1647 * Structures to export the Wireless Handlers
1648 */
1649
1650static const iw_handler ray_handler[] = {
1651 [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
1652 [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) ray_get_name,
1653 [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) ray_set_freq,
1654 [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) ray_get_freq,
1655 [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) ray_set_mode,
1656 [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) ray_get_mode,
1657 [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
1658#ifdef WIRELESS_SPY
1659 [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
1660 [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
1661 [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
1662 [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
1663#endif /* WIRELESS_SPY */
1664 [SIOCGIWAP -SIOCIWFIRST] (iw_handler) ray_get_wap,
1665 [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
1666 [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
1667 [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) ray_set_rate,
1668 [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) ray_get_rate,
1669 [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) ray_set_rts,
1670 [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) ray_get_rts,
1671 [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) ray_set_frag,
1672 [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) ray_get_frag,
1673};
1674
1675#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
1676#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */
1677#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
1678
1679static const iw_handler ray_private_handler[] = {
1680 [0] (iw_handler) ray_set_framing,
1681 [1] (iw_handler) ray_get_framing,
1682 [3] (iw_handler) ray_get_country,
1683};
1684
1685static const struct iw_priv_args ray_private_args[] = {
1686/* cmd, set_args, get_args, name */
1687{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
1688{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
1689{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
1690};
1691
1692static const struct iw_handler_def ray_handler_def =
1693{
1694 .num_standard = sizeof(ray_handler)/sizeof(iw_handler),
1695 .num_private = sizeof(ray_private_handler)/sizeof(iw_handler),
1696 .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args),
1697 .standard = ray_handler,
1698 .private = ray_private_handler,
1699 .private_args = ray_private_args,
1700 .get_wireless_stats = ray_get_wireless_stats,
1701};
1702
1663/*===========================================================================*/ 1703/*===========================================================================*/
1664static int ray_open(struct net_device *dev) 1704static int ray_open(struct net_device *dev)
1665{ 1705{
@@ -2392,20 +2432,15 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
2392 /*local->wstats.qual.noise = none ? */ 2432 /*local->wstats.qual.noise = none ? */
2393 local->wstats.qual.updated = 0x2; 2433 local->wstats.qual.updated = 0x2;
2394 } 2434 }
2395 /* Now, for the addresses in the spy list */ 2435 /* Now, update the spy stuff */
2396 { 2436 {
2397 int i; 2437 struct iw_quality wstats;
2398 /* Look all addresses */ 2438 wstats.level = siglev;
2399 for(i = 0; i < local->spy_number; i++) 2439 /* wstats.noise = none ? */
2400 /* If match */ 2440 /* wstats.qual = none ? */
2401 if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN)) 2441 wstats.updated = 0x2;
2402 { 2442 /* Update spy records */
2403 /* Update statistics */ 2443 wireless_spy_update(dev, linksrcaddr, &wstats);
2404 /*local->spy_stat[i].qual = none ? */
2405 local->spy_stat[i].level = siglev;
2406 /*local->spy_stat[i].noise = none ? */
2407 local->spy_stat[i].updated = 0x2;
2408 }
2409 } 2444 }
2410#endif /* WIRELESS_SPY */ 2445#endif /* WIRELESS_SPY */
2411} /* end rx_data */ 2446} /* end rx_data */