root/drivers/staging/rtl8192u/r8192U_wx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. r8192_wx_get_freq
  2. r8192_wx_get_mode
  3. r8192_wx_get_rate
  4. r8192_wx_set_rate
  5. r8192_wx_set_rts
  6. r8192_wx_get_rts
  7. r8192_wx_set_power
  8. r8192_wx_get_power
  9. r8192_wx_force_reset
  10. r8192_wx_set_rawtx
  11. r8192_wx_set_crcmon
  12. r8192_wx_set_mode
  13. rtl8180_wx_get_range
  14. r8192_wx_set_scan
  15. r8192_wx_get_scan
  16. r8192_wx_set_essid
  17. r8192_wx_get_essid
  18. r8192_wx_set_freq
  19. r8192_wx_get_name
  20. r8192_wx_set_frag
  21. r8192_wx_get_frag
  22. r8192_wx_set_wap
  23. r8192_wx_get_wap
  24. r8192_wx_get_enc
  25. r8192_wx_set_enc
  26. r8192_wx_set_scan_type
  27. r8192_wx_set_retry
  28. r8192_wx_get_retry
  29. r8192_wx_get_sens
  30. r8192_wx_set_sens
  31. r8192_wx_set_enc_ext
  32. r8192_wx_set_auth
  33. r8192_wx_set_mlme
  34. r8192_wx_set_gen_ie
  35. dummy
  36. r8192_get_wireless_stats

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * This file contains wireless extension handlers.
   5  *
   6  * This is part of rtl8180 OpenSource driver.
   7  * Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
   8  *
   9  * Parts of this driver are based on the GPL part
  10  * of the official realtek driver.
  11  *
  12  * Parts of this driver are based on the rtl8180 driver skeleton
  13  * from Patric Schenke & Andres Salomon.
  14  *
  15  * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  16  *
  17  * We want to thank the Authors of those projects and the Ndiswrapper
  18  * project Authors.
  19  *
  20  *****************************************************************************/
  21 
  22 #include <linux/string.h>
  23 #include "r8192U.h"
  24 #include "r8192U_hw.h"
  25 
  26 #include "dot11d.h"
  27 #include "r8192U_wx.h"
  28 
  29 #define RATE_COUNT 12
  30 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
  31         6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
  32 
  33 #ifndef ENETDOWN
  34 #define ENETDOWN 1
  35 #endif
  36 
  37 static int r8192_wx_get_freq(struct net_device *dev,
  38                              struct iw_request_info *a,
  39                              union iwreq_data *wrqu, char *b)
  40 {
  41         struct r8192_priv *priv = ieee80211_priv(dev);
  42 
  43         return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
  44 }
  45 
  46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
  47                              union iwreq_data *wrqu, char *b)
  48 {
  49         struct r8192_priv *priv = ieee80211_priv(dev);
  50 
  51         return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
  52 }
  53 
  54 static int r8192_wx_get_rate(struct net_device *dev,
  55                              struct iw_request_info *info,
  56                              union iwreq_data *wrqu, char *extra)
  57 {
  58         struct r8192_priv *priv = ieee80211_priv(dev);
  59 
  60         return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
  61 }
  62 
  63 static int r8192_wx_set_rate(struct net_device *dev,
  64                              struct iw_request_info *info,
  65                              union iwreq_data *wrqu, char *extra)
  66 {
  67         int ret;
  68         struct r8192_priv *priv = ieee80211_priv(dev);
  69 
  70         mutex_lock(&priv->wx_mutex);
  71 
  72         ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
  73 
  74         mutex_unlock(&priv->wx_mutex);
  75 
  76         return ret;
  77 }
  78 
  79 static int r8192_wx_set_rts(struct net_device *dev,
  80                              struct iw_request_info *info,
  81                              union iwreq_data *wrqu, char *extra)
  82 {
  83         int ret;
  84         struct r8192_priv *priv = ieee80211_priv(dev);
  85 
  86         mutex_lock(&priv->wx_mutex);
  87 
  88         ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
  89 
  90         mutex_unlock(&priv->wx_mutex);
  91 
  92         return ret;
  93 }
  94 
  95 static int r8192_wx_get_rts(struct net_device *dev,
  96                              struct iw_request_info *info,
  97                              union iwreq_data *wrqu, char *extra)
  98 {
  99         struct r8192_priv *priv = ieee80211_priv(dev);
 100 
 101         return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
 102 }
 103 
 104 static int r8192_wx_set_power(struct net_device *dev,
 105                              struct iw_request_info *info,
 106                              union iwreq_data *wrqu, char *extra)
 107 {
 108         int ret;
 109         struct r8192_priv *priv = ieee80211_priv(dev);
 110 
 111         mutex_lock(&priv->wx_mutex);
 112 
 113         ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
 114 
 115         mutex_unlock(&priv->wx_mutex);
 116 
 117         return ret;
 118 }
 119 
 120 static int r8192_wx_get_power(struct net_device *dev,
 121                              struct iw_request_info *info,
 122                              union iwreq_data *wrqu, char *extra)
 123 {
 124         struct r8192_priv *priv = ieee80211_priv(dev);
 125 
 126         return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
 127 }
 128 
 129 static int r8192_wx_force_reset(struct net_device *dev,
 130                 struct iw_request_info *info,
 131                 union iwreq_data *wrqu, char *extra)
 132 {
 133         struct r8192_priv *priv = ieee80211_priv(dev);
 134 
 135         mutex_lock(&priv->wx_mutex);
 136 
 137         netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra);
 138         priv->force_reset = *extra;
 139         mutex_unlock(&priv->wx_mutex);
 140         return 0;
 141 
 142 }
 143 
 144 static int r8192_wx_set_rawtx(struct net_device *dev,
 145                                struct iw_request_info *info,
 146                                union iwreq_data *wrqu, char *extra)
 147 {
 148         struct r8192_priv *priv = ieee80211_priv(dev);
 149         int ret;
 150 
 151         mutex_lock(&priv->wx_mutex);
 152 
 153         ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
 154 
 155         mutex_unlock(&priv->wx_mutex);
 156 
 157         return ret;
 158 
 159 }
 160 
 161 static int r8192_wx_set_crcmon(struct net_device *dev,
 162                                struct iw_request_info *info,
 163                                union iwreq_data *wrqu, char *extra)
 164 {
 165         struct r8192_priv *priv = ieee80211_priv(dev);
 166         int *parms = (int *)extra;
 167         int enable = (parms[0] > 0);
 168 
 169         mutex_lock(&priv->wx_mutex);
 170 
 171         if (enable)
 172                 priv->crcmon = 1;
 173         else
 174                 priv->crcmon = 0;
 175 
 176         DMESG("bad CRC in monitor mode are %s",
 177               priv->crcmon ? "accepted" : "rejected");
 178 
 179         mutex_unlock(&priv->wx_mutex);
 180 
 181         return 0;
 182 }
 183 
 184 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
 185                              union iwreq_data *wrqu, char *b)
 186 {
 187         struct r8192_priv *priv = ieee80211_priv(dev);
 188         int ret;
 189 
 190         mutex_lock(&priv->wx_mutex);
 191 
 192         ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
 193 
 194         rtl8192_set_rxconf(dev);
 195 
 196         mutex_unlock(&priv->wx_mutex);
 197         return ret;
 198 }
 199 
 200 struct  iw_range_with_scan_capa {
 201         /* Informative stuff (to choose between different interface) */
 202         __u32           throughput;     /* To give an idea... */
 203         /* In theory this value should be the maximum benchmarked
 204          * TCP/IP throughput, because with most of these devices the
 205          * bit rate is meaningless (overhead an co) to estimate how
 206          * fast the connection will go and pick the fastest one.
 207          * I suggest people to play with Netperf or any benchmark...
 208          */
 209 
 210         /* NWID (or domain id) */
 211         __u32           min_nwid;       /* Minimal NWID we are able to set */
 212         __u32           max_nwid;       /* Maximal NWID we are able to set */
 213 
 214         /* Old Frequency (backward compat - moved lower ) */
 215         __u16           old_num_channels;
 216         __u8            old_num_frequency;
 217 
 218         /* Scan capabilities */
 219         __u8            scan_capa;
 220 };
 221 static int rtl8180_wx_get_range(struct net_device *dev,
 222                                 struct iw_request_info *info,
 223                                 union iwreq_data *wrqu, char *extra)
 224 {
 225         struct iw_range *range = (struct iw_range *)extra;
 226         struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
 227         struct r8192_priv *priv = ieee80211_priv(dev);
 228         u16 val;
 229         int i;
 230 
 231         wrqu->data.length = sizeof(*range);
 232         memset(range, 0, sizeof(*range));
 233 
 234         /* Let's try to keep this struct in the same order as in
 235          * linux/include/wireless.h
 236          */
 237 
 238         /* TODO: See what values we can set, and remove the ones we can't
 239          * set, or fill them with some default data.
 240          */
 241 
 242         /* ~5 Mb/s real (802.11b) */
 243         range->throughput = 5 * 1000 * 1000;
 244 
 245         /* TODO: Not used in 802.11b? */
 246         /* range->min_nwid; */  /* Minimal NWID we are able to set */
 247         /* TODO: Not used in 802.11b? */
 248         /* range->max_nwid; */  /* Maximal NWID we are able to set */
 249 
 250         /* Old Frequency (backward compat - moved lower ) */
 251         /* range->old_num_channels; */
 252         /* range->old_num_frequency; */
 253         /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
 254         if (priv->rf_set_sens != NULL)
 255                 range->sensitivity = priv->max_sens;    /* signal level threshold range */
 256 
 257         range->max_qual.qual = 100;
 258         /* TODO: Find real max RSSI and stick here */
 259         range->max_qual.level = 0;
 260         range->max_qual.noise = 0x100 - 98;
 261         range->max_qual.updated = 7; /* Updated all three */
 262 
 263         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
 264         /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 265         range->avg_qual.level = 0x100 - 78;
 266         range->avg_qual.noise = 0;
 267         range->avg_qual.updated = 7; /* Updated all three */
 268 
 269         range->num_bitrates = RATE_COUNT;
 270 
 271         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
 272                 range->bitrate[i] = rtl8180_rates[i];
 273 
 274         range->min_frag = MIN_FRAG_THRESHOLD;
 275         range->max_frag = MAX_FRAG_THRESHOLD;
 276 
 277         range->min_pmp = 0;
 278         range->max_pmp = 5000000;
 279         range->min_pmt = 0;
 280         range->max_pmt = 65535*1000;
 281         range->pmp_flags = IW_POWER_PERIOD;
 282         range->pmt_flags = IW_POWER_TIMEOUT;
 283         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 284 
 285         range->we_version_compiled = WIRELESS_EXT;
 286         range->we_version_source = 16;
 287 
 288         /* range->retry_capa; */        /* What retry options are supported */
 289         /* range->retry_flags; */       /* How to decode max/min retry limit */
 290         /* range->r_time_flags; */      /* How to decode max/min retry life */
 291         /* range->min_retry; */         /* Minimal number of retries */
 292         /* range->max_retry; */         /* Maximal number of retries */
 293         /* range->min_r_time; */        /* Minimal retry lifetime */
 294         /* range->max_r_time; */        /* Maximal retry lifetime */
 295 
 296         for (i = 0, val = 0; i < 14; i++) {
 297 
 298                 /* Include only legal frequencies for some countries */
 299                 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
 300                         range->freq[val].i = i + 1;
 301                         range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
 302                         range->freq[val].e = 1;
 303                         val++;
 304                 } else {
 305                         /* FIXME: do we need to set anything for channels */
 306                         /* we don't use ? */
 307                 }
 308 
 309                 if (val == IW_MAX_FREQUENCIES)
 310                         break;
 311         }
 312         range->num_frequency = val;
 313         range->num_channels = val;
 314         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
 315                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
 316         tmp->scan_capa = 0x01;
 317         return 0;
 318 }
 319 
 320 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 321                              union iwreq_data *wrqu, char *b)
 322 {
 323         struct r8192_priv *priv = ieee80211_priv(dev);
 324         struct ieee80211_device *ieee = priv->ieee80211;
 325         int ret = 0;
 326 
 327         if (!priv->up)
 328                 return -ENETDOWN;
 329 
 330         if (priv->ieee80211->LinkDetectInfo.bBusyTraffic)
 331                 return -EAGAIN;
 332         if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 333                 struct iw_scan_req *req = (struct iw_scan_req *)b;
 334 
 335                 if (req->essid_len) {
 336                         ieee->current_network.ssid_len = req->essid_len;
 337                         memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
 338                 }
 339         }
 340 
 341         mutex_lock(&priv->wx_mutex);
 342         if (priv->ieee80211->state != IEEE80211_LINKED) {
 343                 priv->ieee80211->scanning = 0;
 344                 ieee80211_softmac_scan_syncro(priv->ieee80211);
 345                 ret = 0;
 346         } else {
 347                 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
 348         }
 349         mutex_unlock(&priv->wx_mutex);
 350         return ret;
 351 }
 352 
 353 
 354 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
 355                              union iwreq_data *wrqu, char *b)
 356 {
 357 
 358         int ret;
 359         struct r8192_priv *priv = ieee80211_priv(dev);
 360 
 361         if (!priv->up)
 362                 return -ENETDOWN;
 363 
 364         mutex_lock(&priv->wx_mutex);
 365 
 366         ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
 367 
 368         mutex_unlock(&priv->wx_mutex);
 369 
 370         return ret;
 371 }
 372 
 373 static int r8192_wx_set_essid(struct net_device *dev,
 374                               struct iw_request_info *a,
 375                               union iwreq_data *wrqu, char *b)
 376 {
 377         struct r8192_priv *priv = ieee80211_priv(dev);
 378         int ret;
 379 
 380         mutex_lock(&priv->wx_mutex);
 381 
 382         ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
 383 
 384         mutex_unlock(&priv->wx_mutex);
 385 
 386         return ret;
 387 }
 388 
 389 static int r8192_wx_get_essid(struct net_device *dev,
 390                               struct iw_request_info *a,
 391                               union iwreq_data *wrqu, char *b)
 392 {
 393         int ret;
 394         struct r8192_priv *priv = ieee80211_priv(dev);
 395 
 396         mutex_lock(&priv->wx_mutex);
 397 
 398         ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
 399 
 400         mutex_unlock(&priv->wx_mutex);
 401 
 402         return ret;
 403 }
 404 
 405 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
 406                              union iwreq_data *wrqu, char *b)
 407 {
 408         int ret;
 409         struct r8192_priv *priv = ieee80211_priv(dev);
 410 
 411         mutex_lock(&priv->wx_mutex);
 412 
 413         ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
 414 
 415         mutex_unlock(&priv->wx_mutex);
 416         return ret;
 417 }
 418 
 419 static int r8192_wx_get_name(struct net_device *dev,
 420                              struct iw_request_info *info,
 421                              union iwreq_data *wrqu, char *extra)
 422 {
 423         struct r8192_priv *priv = ieee80211_priv(dev);
 424 
 425         return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
 426 }
 427 
 428 static int r8192_wx_set_frag(struct net_device *dev,
 429                              struct iw_request_info *info,
 430                              union iwreq_data *wrqu, char *extra)
 431 {
 432         struct r8192_priv *priv = ieee80211_priv(dev);
 433 
 434         if (wrqu->frag.disabled)
 435                 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
 436         else {
 437                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
 438                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
 439                         return -EINVAL;
 440 
 441                 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
 442         }
 443 
 444         return 0;
 445 }
 446 
 447 
 448 static int r8192_wx_get_frag(struct net_device *dev,
 449                              struct iw_request_info *info,
 450                              union iwreq_data *wrqu, char *extra)
 451 {
 452         struct r8192_priv *priv = ieee80211_priv(dev);
 453 
 454         wrqu->frag.value = priv->ieee80211->fts;
 455         wrqu->frag.fixed = 0;   /* no auto select */
 456         wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
 457 
 458         return 0;
 459 }
 460 
 461 
 462 static int r8192_wx_set_wap(struct net_device *dev,
 463                          struct iw_request_info *info,
 464                          union iwreq_data *awrq,
 465                          char *extra)
 466 {
 467 
 468         int ret;
 469         struct r8192_priv *priv = ieee80211_priv(dev);
 470         /* struct sockaddr *temp = (struct sockaddr *)awrq; */
 471         mutex_lock(&priv->wx_mutex);
 472 
 473         ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
 474 
 475         mutex_unlock(&priv->wx_mutex);
 476 
 477         return ret;
 478 
 479 }
 480 
 481 static int r8192_wx_get_wap(struct net_device *dev,
 482                             struct iw_request_info *info,
 483                             union iwreq_data *wrqu, char *extra)
 484 {
 485         struct r8192_priv *priv = ieee80211_priv(dev);
 486 
 487         return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
 488 }
 489 
 490 static int r8192_wx_get_enc(struct net_device *dev,
 491                             struct iw_request_info *info,
 492                             union iwreq_data *wrqu, char *key)
 493 {
 494         struct r8192_priv *priv = ieee80211_priv(dev);
 495 
 496         return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
 497 }
 498 
 499 static int r8192_wx_set_enc(struct net_device *dev,
 500                             struct iw_request_info *info,
 501                             union iwreq_data *wrqu, char *key)
 502 {
 503         struct r8192_priv *priv = ieee80211_priv(dev);
 504         struct ieee80211_device *ieee = priv->ieee80211;
 505         int ret;
 506         u32 hwkey[4] = {0, 0, 0, 0};
 507         u8 mask = 0xff;
 508         u32 key_idx = 0;
 509         u8 zero_addr[4][6] = {  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 510                                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
 511                                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
 512                                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
 513         int i;
 514 
 515         if (!priv->up)
 516                 return -ENETDOWN;
 517 
 518         mutex_lock(&priv->wx_mutex);
 519 
 520         RT_TRACE(COMP_SEC, "Setting SW wep key");
 521         ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
 522 
 523         mutex_unlock(&priv->wx_mutex);
 524 
 525 
 526 
 527         /* sometimes, the length is zero while we do not type key value */
 528         if (wrqu->encoding.length != 0) {
 529 
 530                 for (i = 0; i < 4; i++) {
 531                         hwkey[i] |=  key[4*i+0]&mask;
 532                         if (i == 1 && (4*i+1) == wrqu->encoding.length)
 533                                 mask = 0x00;
 534                         if (i == 3 && (4*i+1) == wrqu->encoding.length)
 535                                 mask = 0x00;
 536                         hwkey[i] |= (key[4*i+1]&mask)<<8;
 537                         hwkey[i] |= (key[4*i+2]&mask)<<16;
 538                         hwkey[i] |= (key[4*i+3]&mask)<<24;
 539                 }
 540 
 541                 #define CONF_WEP40  0x4
 542                 #define CONF_WEP104 0x14
 543 
 544                 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
 545                 case 0:
 546                         key_idx = ieee->tx_keyidx;
 547                         break;
 548                 case 1:
 549                         key_idx = 0;
 550                         break;
 551                 case 2:
 552                         key_idx = 1;
 553                         break;
 554                 case 3:
 555                         key_idx = 2;
 556                         break;
 557                 case 4:
 558                         key_idx = 3;
 559                         break;
 560                 default:
 561                         break;
 562                 }
 563 
 564                 if (wrqu->encoding.length == 0x5) {
 565                         ieee->pairwise_key_type = KEY_TYPE_WEP40;
 566                         EnableHWSecurityConfig8192(dev);
 567 
 568                         setKey(dev,
 569                                 key_idx,                /* EntryNo */
 570                                 key_idx,                /* KeyIndex */
 571                                 KEY_TYPE_WEP40,         /* KeyType */
 572                                 zero_addr[key_idx],
 573                                 0,                      /* DefaultKey */
 574                                 hwkey);                 /* KeyContent */
 575 
 576                 }
 577 
 578                 else if (wrqu->encoding.length == 0xd) {
 579                         ieee->pairwise_key_type = KEY_TYPE_WEP104;
 580                         EnableHWSecurityConfig8192(dev);
 581 
 582                         setKey(dev,
 583                                 key_idx,                /* EntryNo */
 584                                 key_idx,                /* KeyIndex */
 585                                 KEY_TYPE_WEP104,        /* KeyType */
 586                                 zero_addr[key_idx],
 587                                 0,                      /* DefaultKey */
 588                                 hwkey);                 /* KeyContent */
 589 
 590                 } else {
 591                         printk("wrong type in WEP, not WEP40 and WEP104\n");
 592                 }
 593 
 594         }
 595 
 596         return ret;
 597 }
 598 
 599 
 600 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
 601                                         union iwreq_data *wrqu, char *p)
 602 {
 603 
 604         struct r8192_priv *priv = ieee80211_priv(dev);
 605         int *parms = (int *)p;
 606         int mode = parms[0];
 607 
 608         priv->ieee80211->active_scan = mode;
 609 
 610         return 1;
 611 }
 612 
 613 
 614 
 615 static int r8192_wx_set_retry(struct net_device *dev,
 616                                 struct iw_request_info *info,
 617                                 union iwreq_data *wrqu, char *extra)
 618 {
 619         struct r8192_priv *priv = ieee80211_priv(dev);
 620         int err = 0;
 621 
 622         mutex_lock(&priv->wx_mutex);
 623 
 624         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
 625             wrqu->retry.disabled){
 626                 err = -EINVAL;
 627                 goto exit;
 628         }
 629         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
 630                 err = -EINVAL;
 631                 goto exit;
 632         }
 633 
 634         if (wrqu->retry.value > R8180_MAX_RETRY) {
 635                 err = -EINVAL;
 636                 goto exit;
 637         }
 638         if (wrqu->retry.flags & IW_RETRY_MAX) {
 639                 priv->retry_rts = wrqu->retry.value;
 640                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
 641 
 642         } else {
 643                 priv->retry_data = wrqu->retry.value;
 644                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
 645         }
 646 
 647         /* FIXME !
 648          * We might try to write directly the TX config register
 649          * or to restart just the (R)TX process.
 650          * I'm unsure if whole reset is really needed
 651          */
 652 
 653         rtl8192_commit(dev);
 654 exit:
 655         mutex_unlock(&priv->wx_mutex);
 656 
 657         return err;
 658 }
 659 
 660 static int r8192_wx_get_retry(struct net_device *dev,
 661                                 struct iw_request_info *info,
 662                                 union iwreq_data *wrqu, char *extra)
 663 {
 664         struct r8192_priv *priv = ieee80211_priv(dev);
 665 
 666 
 667         wrqu->retry.disabled = 0; /* can't be disabled */
 668 
 669         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
 670             IW_RETRY_LIFETIME)
 671                 return -EINVAL;
 672 
 673         if (wrqu->retry.flags & IW_RETRY_MAX) {
 674                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 675                 wrqu->retry.value = priv->retry_rts;
 676         } else {
 677                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
 678                 wrqu->retry.value = priv->retry_data;
 679         }
 680 
 681         return 0;
 682 }
 683 
 684 static int r8192_wx_get_sens(struct net_device *dev,
 685                                 struct iw_request_info *info,
 686                                 union iwreq_data *wrqu, char *extra)
 687 {
 688         struct r8192_priv *priv = ieee80211_priv(dev);
 689 
 690         if (priv->rf_set_sens == NULL)
 691                 return -1; /* we have not this support for this radio */
 692         wrqu->sens.value = priv->sens;
 693         return 0;
 694 }
 695 
 696 static int r8192_wx_set_sens(struct net_device *dev,
 697                                 struct iw_request_info *info,
 698                                 union iwreq_data *wrqu, char *extra)
 699 {
 700 
 701         struct r8192_priv *priv = ieee80211_priv(dev);
 702         short err = 0;
 703 
 704         mutex_lock(&priv->wx_mutex);
 705         if (priv->rf_set_sens == NULL) {
 706                 err = -1; /* we have not this support for this radio */
 707                 goto exit;
 708         }
 709         if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
 710                 priv->sens = wrqu->sens.value;
 711         else
 712                 err = -EINVAL;
 713 
 714 exit:
 715         mutex_unlock(&priv->wx_mutex);
 716 
 717         return err;
 718 }
 719 
 720 /* hw security need to reorganized. */
 721 static int r8192_wx_set_enc_ext(struct net_device *dev,
 722                                         struct iw_request_info *info,
 723                                         union iwreq_data *wrqu, char *extra)
 724 {
 725         int ret = 0;
 726         struct r8192_priv *priv = ieee80211_priv(dev);
 727         struct ieee80211_device *ieee = priv->ieee80211;
 728 
 729 
 730         mutex_lock(&priv->wx_mutex);
 731         ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
 732 
 733         {
 734                 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 735                 u8 zero[6] = {0};
 736                 u32 key[4] = {0};
 737                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 738                 struct iw_point *encoding = &wrqu->encoding;
 739                 u8 idx = 0, alg = 0, group = 0;
 740 
 741                 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
 742                         /* none is not allowed to use hwsec WB 2008.07.01 */
 743                         goto end_hw_sec;
 744 
 745                 /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
 746                 alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
 747                 idx = encoding->flags & IW_ENCODE_INDEX;
 748                 if (idx)
 749                         idx--;
 750                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
 751 
 752                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40)) {
 753                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
 754                                 alg = KEY_TYPE_WEP104;
 755                         ieee->pairwise_key_type = alg;
 756                         EnableHWSecurityConfig8192(dev);
 757                 }
 758                 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
 759 
 760                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
 761 
 762                         setKey(dev,
 763                                         idx,    /* EntryNao */
 764                                         idx,    /* KeyIndex */
 765                                         alg,    /* KeyType */
 766                                         zero,   /* MacAddr */
 767                                         0,      /* DefaultKey */
 768                                         key);   /* KeyContent */
 769                 } else if (group) {
 770                         ieee->group_key_type = alg;
 771                         setKey(dev,
 772                                         idx,    /* EntryNo */
 773                                         idx,    /* KeyIndex */
 774                                         alg,    /* KeyType */
 775                                         broadcast_addr, /* MacAddr */
 776                                         0,              /* DefaultKey */
 777                                         key);           /* KeyContent */
 778                 } else {        /* pairwise key */
 779                         setKey(dev,
 780                                         4,      /* EntryNo */
 781                                         idx,    /* KeyIndex */
 782                                         alg,    /* KeyType */
 783                                         (u8 *)ieee->ap_mac_addr,/* MacAddr */
 784                                         0,                      /* DefaultKey */
 785                                         key);                   /* KeyContent */
 786                 }
 787 
 788 
 789         }
 790 
 791 end_hw_sec:
 792 
 793         mutex_unlock(&priv->wx_mutex);
 794         return ret;
 795 
 796 }
 797 static int r8192_wx_set_auth(struct net_device *dev,
 798                                         struct iw_request_info *info,
 799                                         union iwreq_data *data, char *extra)
 800 {
 801         int ret = 0;
 802         struct r8192_priv *priv = ieee80211_priv(dev);
 803 
 804         mutex_lock(&priv->wx_mutex);
 805         ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
 806         mutex_unlock(&priv->wx_mutex);
 807         return ret;
 808 }
 809 
 810 static int r8192_wx_set_mlme(struct net_device *dev,
 811                                         struct iw_request_info *info,
 812                                         union iwreq_data *wrqu, char *extra)
 813 {
 814 
 815         int ret = 0;
 816         struct r8192_priv *priv = ieee80211_priv(dev);
 817 
 818         mutex_lock(&priv->wx_mutex);
 819         ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
 820 
 821         mutex_unlock(&priv->wx_mutex);
 822         return ret;
 823 }
 824 
 825 static int r8192_wx_set_gen_ie(struct net_device *dev,
 826                                         struct iw_request_info *info,
 827                                         union iwreq_data *data, char *extra)
 828 {
 829         int ret = 0;
 830         struct r8192_priv *priv = ieee80211_priv(dev);
 831 
 832         mutex_lock(&priv->wx_mutex);
 833         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
 834         mutex_unlock(&priv->wx_mutex);
 835         return ret;
 836 
 837 
 838 }
 839 
 840 static int dummy(struct net_device *dev, struct iw_request_info *a,
 841                  union iwreq_data *wrqu, char *b)
 842 {
 843         return -1;
 844 }
 845 
 846 static iw_handler r8192_wx_handlers[] = {
 847         NULL,                     /* SIOCSIWCOMMIT */
 848         r8192_wx_get_name,        /* SIOCGIWNAME */
 849         dummy,                    /* SIOCSIWNWID */
 850         dummy,                    /* SIOCGIWNWID */
 851         r8192_wx_set_freq,        /* SIOCSIWFREQ */
 852         r8192_wx_get_freq,        /* SIOCGIWFREQ */
 853         r8192_wx_set_mode,        /* SIOCSIWMODE */
 854         r8192_wx_get_mode,        /* SIOCGIWMODE */
 855         r8192_wx_set_sens,        /* SIOCSIWSENS */
 856         r8192_wx_get_sens,        /* SIOCGIWSENS */
 857         NULL,                     /* SIOCSIWRANGE */
 858         rtl8180_wx_get_range,     /* SIOCGIWRANGE */
 859         NULL,                     /* SIOCSIWPRIV */
 860         NULL,                     /* SIOCGIWPRIV */
 861         NULL,                     /* SIOCSIWSTATS */
 862         NULL,                     /* SIOCGIWSTATS */
 863         dummy,                    /* SIOCSIWSPY */
 864         dummy,                    /* SIOCGIWSPY */
 865         NULL,                     /* SIOCGIWTHRSPY */
 866         NULL,                     /* SIOCWIWTHRSPY */
 867         r8192_wx_set_wap,         /* SIOCSIWAP */
 868         r8192_wx_get_wap,         /* SIOCGIWAP */
 869         r8192_wx_set_mlme,                     /* MLME-- */
 870         dummy,                     /* SIOCGIWAPLIST -- deprecated */
 871         r8192_wx_set_scan,        /* SIOCSIWSCAN */
 872         r8192_wx_get_scan,        /* SIOCGIWSCAN */
 873         r8192_wx_set_essid,       /* SIOCSIWESSID */
 874         r8192_wx_get_essid,       /* SIOCGIWESSID */
 875         dummy,                    /* SIOCSIWNICKN */
 876         dummy,                    /* SIOCGIWNICKN */
 877         NULL,                     /* -- hole -- */
 878         NULL,                     /* -- hole -- */
 879         r8192_wx_set_rate,        /* SIOCSIWRATE */
 880         r8192_wx_get_rate,        /* SIOCGIWRATE */
 881         r8192_wx_set_rts,                    /* SIOCSIWRTS */
 882         r8192_wx_get_rts,                    /* SIOCGIWRTS */
 883         r8192_wx_set_frag,        /* SIOCSIWFRAG */
 884         r8192_wx_get_frag,        /* SIOCGIWFRAG */
 885         dummy,                    /* SIOCSIWTXPOW */
 886         dummy,                    /* SIOCGIWTXPOW */
 887         r8192_wx_set_retry,       /* SIOCSIWRETRY */
 888         r8192_wx_get_retry,       /* SIOCGIWRETRY */
 889         r8192_wx_set_enc,         /* SIOCSIWENCODE */
 890         r8192_wx_get_enc,         /* SIOCGIWENCODE */
 891         r8192_wx_set_power,                    /* SIOCSIWPOWER */
 892         r8192_wx_get_power,                    /* SIOCGIWPOWER */
 893         NULL,                   /*---hole---*/
 894         NULL,                   /*---hole---*/
 895         r8192_wx_set_gen_ie, /* NULL, */                /* SIOCSIWGENIE */
 896         NULL,                   /* SIOCSIWGENIE */
 897 
 898         r8192_wx_set_auth,/* NULL, */                   /* SIOCSIWAUTH */
 899         NULL,/* r8192_wx_get_auth, */ /* NULL, */       /* SIOCSIWAUTH */
 900         r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
 901         NULL,/* r8192_wx_get_enc_ext, *//* NULL, */                     /* SIOCSIWENCODEEXT */
 902         NULL,                   /* SIOCSIWPMKSA */
 903         NULL,                    /*---hole---*/
 904 
 905 };
 906 
 907 
 908 static const struct iw_priv_args r8192_private_args[] = {
 909 
 910         {
 911                 SIOCIWFIRSTPRIV + 0x0,
 912                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
 913         },
 914 
 915         {
 916                 SIOCIWFIRSTPRIV + 0x1,
 917                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
 918 
 919         },
 920         {
 921                 SIOCIWFIRSTPRIV + 0x2,
 922                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
 923         },
 924         {
 925                 SIOCIWFIRSTPRIV + 0x3,
 926                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
 927 
 928         }
 929 
 930 };
 931 
 932 static iw_handler r8192_private_handler[] = {
 933         r8192_wx_set_crcmon,
 934         r8192_wx_set_scan_type,
 935         r8192_wx_set_rawtx,
 936         r8192_wx_force_reset,
 937 };
 938 
 939 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
 940 {
 941         struct r8192_priv *priv = ieee80211_priv(dev);
 942         struct ieee80211_device *ieee = priv->ieee80211;
 943         struct iw_statistics *wstats = &priv->wstats;
 944         int tmp_level = 0;
 945         int tmp_qual = 0;
 946         int tmp_noise = 0;
 947 
 948         if (ieee->state < IEEE80211_LINKED) {
 949                 wstats->qual.qual = 0;
 950                 wstats->qual.level = 0;
 951                 wstats->qual.noise = 0;
 952                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 953                 return wstats;
 954         }
 955 
 956         tmp_level = (&ieee->current_network)->stats.rssi;
 957         tmp_qual = (&ieee->current_network)->stats.signal;
 958         tmp_noise = (&ieee->current_network)->stats.noise;
 959 
 960         wstats->qual.level = tmp_level;
 961         wstats->qual.qual = tmp_qual;
 962         wstats->qual.noise = tmp_noise;
 963         wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 964         return wstats;
 965 }
 966 
 967 const struct iw_handler_def  r8192_wx_handlers_def = {
 968         .standard = r8192_wx_handlers,
 969         .num_standard = ARRAY_SIZE(r8192_wx_handlers),
 970         .private = r8192_private_handler,
 971         .num_private = ARRAY_SIZE(r8192_private_handler),
 972         .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
 973         .get_wireless_stats = r8192_get_wireless_stats,
 974         .private_args = (struct iw_priv_args *)r8192_private_args,
 975 };

/* [<][>][^][v][top][bottom][index][help] */