root/drivers/staging/rtl8192e/rtllib_softmac_wx.c

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

DEFINITIONS

This source file includes following definitions.
  1. rtllib_wx_set_freq
  2. rtllib_wx_get_freq
  3. rtllib_wx_get_wap
  4. rtllib_wx_set_wap
  5. rtllib_wx_get_essid
  6. rtllib_wx_set_rate
  7. rtllib_wx_get_rate
  8. rtllib_wx_set_rts
  9. rtllib_wx_get_rts
  10. rtllib_wx_set_mode
  11. rtllib_wx_sync_scan_wq
  12. rtllib_wx_set_scan
  13. rtllib_wx_set_essid
  14. rtllib_wx_get_mode
  15. rtllib_wx_set_rawtx
  16. rtllib_wx_get_name
  17. rtllib_wx_set_power
  18. rtllib_wx_get_power

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* IEEE 802.11 SoftMAC layer
   3  * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
   4  *
   5  * Mostly extracted from the rtl8180-sa2400 driver for the
   6  * in-kernel generic ieee802.11 stack.
   7  *
   8  * Some pieces of code might be stolen from ipw2100 driver
   9  * copyright of who own it's copyright ;-)
  10  *
  11  * PS wx handler mostly stolen from hostap, copyright who
  12  * own it's copyright ;-)
  13  */
  14 #include <linux/etherdevice.h>
  15 
  16 #include "rtllib.h"
  17 #include "dot11d.h"
  18 /* FIXME: add A freqs */
  19 
  20 const long rtllib_wlan_frequencies[] = {
  21         2412, 2417, 2422, 2427,
  22         2432, 2437, 2442, 2447,
  23         2452, 2457, 2462, 2467,
  24         2472, 2484
  25 };
  26 EXPORT_SYMBOL(rtllib_wlan_frequencies);
  27 
  28 
  29 int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
  30                              union iwreq_data *wrqu, char *b)
  31 {
  32         int ret;
  33         struct iw_freq *fwrq = &wrqu->freq;
  34 
  35         mutex_lock(&ieee->wx_mutex);
  36 
  37         if (ieee->iw_mode == IW_MODE_INFRA) {
  38                 ret = 0;
  39                 goto out;
  40         }
  41 
  42         /* if setting by freq convert to channel */
  43         if (fwrq->e == 1) {
  44                 if ((fwrq->m >= (int) 2.412e8 &&
  45                      fwrq->m <= (int) 2.487e8)) {
  46                         int f = fwrq->m / 100000;
  47                         int c = 0;
  48 
  49                         while ((c < 14) && (f != rtllib_wlan_frequencies[c]))
  50                                 c++;
  51 
  52                         /* hack to fall through */
  53                         fwrq->e = 0;
  54                         fwrq->m = c + 1;
  55                 }
  56         }
  57 
  58         if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
  59                 ret = -EOPNOTSUPP;
  60                 goto out;
  61 
  62         } else { /* Set the channel */
  63 
  64                 if (ieee->active_channel_map[fwrq->m] != 1) {
  65                         ret = -EINVAL;
  66                         goto out;
  67                 }
  68                 ieee->current_network.channel = fwrq->m;
  69                 ieee->set_chan(ieee->dev, ieee->current_network.channel);
  70 
  71                 if (ieee->iw_mode == IW_MODE_ADHOC ||
  72                     ieee->iw_mode == IW_MODE_MASTER)
  73                         if (ieee->state == RTLLIB_LINKED) {
  74                                 rtllib_stop_send_beacons(ieee);
  75                                 rtllib_start_send_beacons(ieee);
  76                         }
  77         }
  78 
  79         ret = 0;
  80 out:
  81         mutex_unlock(&ieee->wx_mutex);
  82         return ret;
  83 }
  84 EXPORT_SYMBOL(rtllib_wx_set_freq);
  85 
  86 
  87 int rtllib_wx_get_freq(struct rtllib_device *ieee,
  88                              struct iw_request_info *a,
  89                              union iwreq_data *wrqu, char *b)
  90 {
  91         struct iw_freq *fwrq = &wrqu->freq;
  92 
  93         if (ieee->current_network.channel == 0)
  94                 return -1;
  95         fwrq->m = rtllib_wlan_frequencies[ieee->current_network.channel-1] *
  96                   100000;
  97         fwrq->e = 1;
  98         return 0;
  99 }
 100 EXPORT_SYMBOL(rtllib_wx_get_freq);
 101 
 102 int rtllib_wx_get_wap(struct rtllib_device *ieee,
 103                             struct iw_request_info *info,
 104                             union iwreq_data *wrqu, char *extra)
 105 {
 106         unsigned long flags;
 107 
 108         wrqu->ap_addr.sa_family = ARPHRD_ETHER;
 109 
 110         if (ieee->iw_mode == IW_MODE_MONITOR)
 111                 return -1;
 112 
 113         /* We want avoid to give to the user inconsistent infos*/
 114         spin_lock_irqsave(&ieee->lock, flags);
 115 
 116         if (ieee->state != RTLLIB_LINKED &&
 117                 ieee->state != RTLLIB_LINKED_SCANNING &&
 118                 ieee->wap_set == 0)
 119 
 120                 eth_zero_addr(wrqu->ap_addr.sa_data);
 121         else
 122                 memcpy(wrqu->ap_addr.sa_data,
 123                        ieee->current_network.bssid, ETH_ALEN);
 124 
 125         spin_unlock_irqrestore(&ieee->lock, flags);
 126 
 127         return 0;
 128 }
 129 EXPORT_SYMBOL(rtllib_wx_get_wap);
 130 
 131 
 132 int rtllib_wx_set_wap(struct rtllib_device *ieee,
 133                          struct iw_request_info *info,
 134                          union iwreq_data *awrq,
 135                          char *extra)
 136 {
 137 
 138         int ret = 0;
 139         unsigned long flags;
 140 
 141         short ifup = ieee->proto_started;
 142         struct sockaddr *temp = (struct sockaddr *)awrq;
 143 
 144         rtllib_stop_scan_syncro(ieee);
 145 
 146         mutex_lock(&ieee->wx_mutex);
 147         /* use ifconfig hw ether */
 148         if (ieee->iw_mode == IW_MODE_MASTER) {
 149                 ret = -1;
 150                 goto out;
 151         }
 152 
 153         if (temp->sa_family != ARPHRD_ETHER) {
 154                 ret = -EINVAL;
 155                 goto out;
 156         }
 157 
 158         if (is_zero_ether_addr(temp->sa_data)) {
 159                 spin_lock_irqsave(&ieee->lock, flags);
 160                 ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
 161                 ieee->wap_set = 0;
 162                 spin_unlock_irqrestore(&ieee->lock, flags);
 163                 ret = -1;
 164                 goto out;
 165         }
 166 
 167 
 168         if (ifup)
 169                 rtllib_stop_protocol(ieee, true);
 170 
 171         /* just to avoid to give inconsistent infos in the
 172          * get wx method. not really needed otherwise
 173          */
 174         spin_lock_irqsave(&ieee->lock, flags);
 175 
 176         ieee->cannot_notify = false;
 177         ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
 178         ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
 179 
 180         spin_unlock_irqrestore(&ieee->lock, flags);
 181 
 182         if (ifup)
 183                 rtllib_start_protocol(ieee);
 184 out:
 185         mutex_unlock(&ieee->wx_mutex);
 186         return ret;
 187 }
 188 EXPORT_SYMBOL(rtllib_wx_set_wap);
 189 
 190 int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
 191                          union iwreq_data *wrqu, char *b)
 192 {
 193         int len, ret = 0;
 194         unsigned long flags;
 195 
 196         if (ieee->iw_mode == IW_MODE_MONITOR)
 197                 return -1;
 198 
 199         /* We want avoid to give to the user inconsistent infos*/
 200         spin_lock_irqsave(&ieee->lock, flags);
 201 
 202         if (ieee->current_network.ssid[0] == '\0' ||
 203                 ieee->current_network.ssid_len == 0) {
 204                 ret = -1;
 205                 goto out;
 206         }
 207 
 208         if (ieee->state != RTLLIB_LINKED &&
 209                 ieee->state != RTLLIB_LINKED_SCANNING &&
 210                 ieee->ssid_set == 0) {
 211                 ret = -1;
 212                 goto out;
 213         }
 214         len = ieee->current_network.ssid_len;
 215         wrqu->essid.length = len;
 216         strncpy(b, ieee->current_network.ssid, len);
 217         wrqu->essid.flags = 1;
 218 
 219 out:
 220         spin_unlock_irqrestore(&ieee->lock, flags);
 221 
 222         return ret;
 223 
 224 }
 225 EXPORT_SYMBOL(rtllib_wx_get_essid);
 226 
 227 int rtllib_wx_set_rate(struct rtllib_device *ieee,
 228                              struct iw_request_info *info,
 229                              union iwreq_data *wrqu, char *extra)
 230 {
 231 
 232         u32 target_rate = wrqu->bitrate.value;
 233 
 234         ieee->rate = target_rate/100000;
 235         return 0;
 236 }
 237 EXPORT_SYMBOL(rtllib_wx_set_rate);
 238 
 239 int rtllib_wx_get_rate(struct rtllib_device *ieee,
 240                              struct iw_request_info *info,
 241                              union iwreq_data *wrqu, char *extra)
 242 {
 243         u32 tmp_rate;
 244 
 245         tmp_rate = TxCountToDataRate(ieee,
 246                                      ieee->softmac_stats.CurrentShowTxate);
 247         wrqu->bitrate.value = tmp_rate * 500000;
 248 
 249         return 0;
 250 }
 251 EXPORT_SYMBOL(rtllib_wx_get_rate);
 252 
 253 
 254 int rtllib_wx_set_rts(struct rtllib_device *ieee,
 255                              struct iw_request_info *info,
 256                              union iwreq_data *wrqu, char *extra)
 257 {
 258         if (wrqu->rts.disabled || !wrqu->rts.fixed)
 259                 ieee->rts = DEFAULT_RTS_THRESHOLD;
 260         else {
 261                 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
 262                                 wrqu->rts.value > MAX_RTS_THRESHOLD)
 263                         return -EINVAL;
 264                 ieee->rts = wrqu->rts.value;
 265         }
 266         return 0;
 267 }
 268 EXPORT_SYMBOL(rtllib_wx_set_rts);
 269 
 270 int rtllib_wx_get_rts(struct rtllib_device *ieee,
 271                              struct iw_request_info *info,
 272                              union iwreq_data *wrqu, char *extra)
 273 {
 274         wrqu->rts.value = ieee->rts;
 275         wrqu->rts.fixed = 0;    /* no auto select */
 276         wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
 277         return 0;
 278 }
 279 EXPORT_SYMBOL(rtllib_wx_get_rts);
 280 
 281 int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
 282                              union iwreq_data *wrqu, char *b)
 283 {
 284         int set_mode_status = 0;
 285 
 286         rtllib_stop_scan_syncro(ieee);
 287         mutex_lock(&ieee->wx_mutex);
 288         switch (wrqu->mode) {
 289         case IW_MODE_MONITOR:
 290         case IW_MODE_ADHOC:
 291         case IW_MODE_INFRA:
 292                 break;
 293         case IW_MODE_AUTO:
 294                 wrqu->mode = IW_MODE_INFRA;
 295                 break;
 296         default:
 297                 set_mode_status = -EINVAL;
 298                 goto out;
 299         }
 300 
 301         if (wrqu->mode == ieee->iw_mode)
 302                 goto out;
 303 
 304         if (wrqu->mode == IW_MODE_MONITOR) {
 305                 ieee->dev->type = ARPHRD_IEEE80211;
 306                 rtllib_EnableNetMonitorMode(ieee->dev, false);
 307         } else {
 308                 ieee->dev->type = ARPHRD_ETHER;
 309                 if (ieee->iw_mode == IW_MODE_MONITOR)
 310                         rtllib_DisableNetMonitorMode(ieee->dev, false);
 311         }
 312 
 313         if (!ieee->proto_started) {
 314                 ieee->iw_mode = wrqu->mode;
 315         } else {
 316                 rtllib_stop_protocol(ieee, true);
 317                 ieee->iw_mode = wrqu->mode;
 318                 rtllib_start_protocol(ieee);
 319         }
 320 
 321 out:
 322         mutex_unlock(&ieee->wx_mutex);
 323         return set_mode_status;
 324 }
 325 EXPORT_SYMBOL(rtllib_wx_set_mode);
 326 
 327 void rtllib_wx_sync_scan_wq(void *data)
 328 {
 329         struct rtllib_device *ieee = container_of_work_rsl(data,
 330                                      struct rtllib_device, wx_sync_scan_wq);
 331         short chan;
 332         enum ht_extchnl_offset chan_offset = 0;
 333         enum ht_channel_width bandwidth = 0;
 334         int b40M = 0;
 335 
 336         if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
 337                 rtllib_start_scan_syncro(ieee, 0);
 338                 goto out;
 339         }
 340 
 341         chan = ieee->current_network.channel;
 342 
 343         if (ieee->LeisurePSLeave)
 344                 ieee->LeisurePSLeave(ieee->dev);
 345         /* notify AP to be in PS mode */
 346         rtllib_sta_ps_send_null_frame(ieee, 1);
 347         rtllib_sta_ps_send_null_frame(ieee, 1);
 348 
 349         rtllib_stop_all_queues(ieee);
 350 
 351         if (ieee->data_hard_stop)
 352                 ieee->data_hard_stop(ieee->dev);
 353         rtllib_stop_send_beacons(ieee);
 354         ieee->state = RTLLIB_LINKED_SCANNING;
 355         ieee->link_change(ieee->dev);
 356         /* wait for ps packet to be kicked out successfully */
 357         msleep(50);
 358 
 359         if (ieee->ScanOperationBackupHandler)
 360                 ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
 361 
 362         if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT &&
 363             ieee->pHTInfo->bCurBW40MHz) {
 364                 b40M = 1;
 365                 chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
 366                 bandwidth = (enum ht_channel_width)ieee->pHTInfo->bCurBW40MHz;
 367                 RT_TRACE(COMP_DBG, "Scan in 40M, force to 20M first:%d, %d\n",
 368                          chan_offset, bandwidth);
 369                 ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20,
 370                                        HT_EXTCHNL_OFFSET_NO_EXT);
 371         }
 372 
 373         rtllib_start_scan_syncro(ieee, 0);
 374 
 375         if (b40M) {
 376                 RT_TRACE(COMP_DBG, "Scan in 20M, back to 40M\n");
 377                 if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
 378                         ieee->set_chan(ieee->dev, chan + 2);
 379                 else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
 380                         ieee->set_chan(ieee->dev, chan - 2);
 381                 else
 382                         ieee->set_chan(ieee->dev, chan);
 383                 ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
 384         } else {
 385                 ieee->set_chan(ieee->dev, chan);
 386         }
 387 
 388         if (ieee->ScanOperationBackupHandler)
 389                 ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE);
 390 
 391         ieee->state = RTLLIB_LINKED;
 392         ieee->link_change(ieee->dev);
 393 
 394         /* Notify AP that I wake up again */
 395         rtllib_sta_ps_send_null_frame(ieee, 0);
 396 
 397         if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 ||
 398             ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
 399                 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
 400                 ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
 401         }
 402 
 403         if (ieee->data_hard_resume)
 404                 ieee->data_hard_resume(ieee->dev);
 405 
 406         if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
 407                 rtllib_start_send_beacons(ieee);
 408 
 409         rtllib_wake_all_queues(ieee);
 410 
 411 out:
 412         mutex_unlock(&ieee->wx_mutex);
 413 
 414 }
 415 
 416 int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
 417                              union iwreq_data *wrqu, char *b)
 418 {
 419         int ret = 0;
 420 
 421         mutex_lock(&ieee->wx_mutex);
 422 
 423         if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
 424                 ret = -1;
 425                 goto out;
 426         }
 427 
 428         if (ieee->state == RTLLIB_LINKED) {
 429                 schedule_work(&ieee->wx_sync_scan_wq);
 430                 /* intentionally forget to up sem */
 431                 return 0;
 432         }
 433 
 434 out:
 435         mutex_unlock(&ieee->wx_mutex);
 436         return ret;
 437 }
 438 EXPORT_SYMBOL(rtllib_wx_set_scan);
 439 
 440 int rtllib_wx_set_essid(struct rtllib_device *ieee,
 441                         struct iw_request_info *a,
 442                         union iwreq_data *wrqu, char *extra)
 443 {
 444 
 445         int ret = 0, len, i;
 446         short proto_started;
 447         unsigned long flags;
 448 
 449         rtllib_stop_scan_syncro(ieee);
 450         mutex_lock(&ieee->wx_mutex);
 451 
 452         proto_started = ieee->proto_started;
 453 
 454         len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE);
 455 
 456         if (ieee->iw_mode == IW_MODE_MONITOR) {
 457                 ret = -1;
 458                 goto out;
 459         }
 460 
 461         for (i = 0; i < len; i++) {
 462                 if (extra[i] < 0) {
 463                         ret = -1;
 464                         goto out;
 465                 }
 466         }
 467 
 468         if (proto_started)
 469                 rtllib_stop_protocol(ieee, true);
 470 
 471 
 472         /* this is just to be sure that the GET wx callback
 473          * has consistent infos. not needed otherwise
 474          */
 475         spin_lock_irqsave(&ieee->lock, flags);
 476 
 477         if (wrqu->essid.flags && wrqu->essid.length) {
 478                 strncpy(ieee->current_network.ssid, extra, len);
 479                 ieee->current_network.ssid_len = len;
 480                 ieee->cannot_notify = false;
 481                 ieee->ssid_set = 1;
 482         } else {
 483                 ieee->ssid_set = 0;
 484                 ieee->current_network.ssid[0] = '\0';
 485                 ieee->current_network.ssid_len = 0;
 486         }
 487         spin_unlock_irqrestore(&ieee->lock, flags);
 488 
 489         if (proto_started)
 490                 rtllib_start_protocol(ieee);
 491 out:
 492         mutex_unlock(&ieee->wx_mutex);
 493         return ret;
 494 }
 495 EXPORT_SYMBOL(rtllib_wx_set_essid);
 496 
 497 int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
 498                        union iwreq_data *wrqu, char *b)
 499 {
 500         wrqu->mode = ieee->iw_mode;
 501         return 0;
 502 }
 503 EXPORT_SYMBOL(rtllib_wx_get_mode);
 504 
 505 int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
 506                         struct iw_request_info *info,
 507                         union iwreq_data *wrqu, char *extra)
 508 {
 509 
 510         int *parms = (int *)extra;
 511         int enable = (parms[0] > 0);
 512         short prev = ieee->raw_tx;
 513 
 514         mutex_lock(&ieee->wx_mutex);
 515 
 516         if (enable)
 517                 ieee->raw_tx = 1;
 518         else
 519                 ieee->raw_tx = 0;
 520 
 521         netdev_info(ieee->dev, "raw TX is %s\n",
 522                     ieee->raw_tx ? "enabled" : "disabled");
 523 
 524         if (ieee->iw_mode == IW_MODE_MONITOR) {
 525                 if (prev == 0 && ieee->raw_tx) {
 526                         if (ieee->data_hard_resume)
 527                                 ieee->data_hard_resume(ieee->dev);
 528 
 529                         netif_carrier_on(ieee->dev);
 530                 }
 531 
 532                 if (prev && ieee->raw_tx == 1)
 533                         netif_carrier_off(ieee->dev);
 534         }
 535 
 536         mutex_unlock(&ieee->wx_mutex);
 537 
 538         return 0;
 539 }
 540 EXPORT_SYMBOL(rtllib_wx_set_rawtx);
 541 
 542 int rtllib_wx_get_name(struct rtllib_device *ieee,
 543                              struct iw_request_info *info,
 544                              union iwreq_data *wrqu, char *extra)
 545 {
 546         strcpy(wrqu->name, "802.11");
 547 
 548         if (ieee->modulation & RTLLIB_CCK_MODULATION)
 549                 strcat(wrqu->name, "b");
 550         if (ieee->modulation & RTLLIB_OFDM_MODULATION)
 551                 strcat(wrqu->name, "g");
 552         if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
 553                 strcat(wrqu->name, "n");
 554         return 0;
 555 }
 556 EXPORT_SYMBOL(rtllib_wx_get_name);
 557 
 558 
 559 /* this is mostly stolen from hostap */
 560 int rtllib_wx_set_power(struct rtllib_device *ieee,
 561                                  struct iw_request_info *info,
 562                                  union iwreq_data *wrqu, char *extra)
 563 {
 564         int ret = 0;
 565 
 566         if ((!ieee->sta_wake_up) ||
 567             (!ieee->enter_sleep_state) ||
 568             (!ieee->ps_is_queue_empty)) {
 569                 netdev_warn(ieee->dev,
 570                             "%s(): PS mode is tried to be use but driver missed a callback\n",
 571                             __func__);
 572                 return -1;
 573         }
 574 
 575         mutex_lock(&ieee->wx_mutex);
 576 
 577         if (wrqu->power.disabled) {
 578                 RT_TRACE(COMP_DBG, "===>%s(): power disable\n", __func__);
 579                 ieee->ps = RTLLIB_PS_DISABLED;
 580                 goto exit;
 581         }
 582         if (wrqu->power.flags & IW_POWER_TIMEOUT) {
 583                 ieee->ps_timeout = wrqu->power.value / 1000;
 584                 RT_TRACE(COMP_DBG, "===>%s():ps_timeout is %d\n", __func__,
 585                          ieee->ps_timeout);
 586         }
 587 
 588         if (wrqu->power.flags & IW_POWER_PERIOD)
 589                 ieee->ps_period = wrqu->power.value / 1000;
 590 
 591         switch (wrqu->power.flags & IW_POWER_MODE) {
 592         case IW_POWER_UNICAST_R:
 593                 ieee->ps = RTLLIB_PS_UNICAST;
 594                 break;
 595         case IW_POWER_MULTICAST_R:
 596                 ieee->ps = RTLLIB_PS_MBCAST;
 597                 break;
 598         case IW_POWER_ALL_R:
 599                 ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;
 600                 break;
 601 
 602         case IW_POWER_ON:
 603                 break;
 604 
 605         default:
 606                 ret = -EINVAL;
 607                 goto exit;
 608 
 609         }
 610 exit:
 611         mutex_unlock(&ieee->wx_mutex);
 612         return ret;
 613 
 614 }
 615 EXPORT_SYMBOL(rtllib_wx_set_power);
 616 
 617 /* this is stolen from hostap */
 618 int rtllib_wx_get_power(struct rtllib_device *ieee,
 619                                  struct iw_request_info *info,
 620                                  union iwreq_data *wrqu, char *extra)
 621 {
 622         mutex_lock(&ieee->wx_mutex);
 623 
 624         if (ieee->ps == RTLLIB_PS_DISABLED) {
 625                 wrqu->power.disabled = 1;
 626                 goto exit;
 627         }
 628 
 629         wrqu->power.disabled = 0;
 630 
 631         if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
 632                 wrqu->power.flags = IW_POWER_TIMEOUT;
 633                 wrqu->power.value = ieee->ps_timeout * 1000;
 634         } else {
 635                 wrqu->power.flags = IW_POWER_PERIOD;
 636                 wrqu->power.value = ieee->ps_period * 1000;
 637         }
 638 
 639         if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) ==
 640             (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
 641                 wrqu->power.flags |= IW_POWER_ALL_R;
 642         else if (ieee->ps & RTLLIB_PS_MBCAST)
 643                 wrqu->power.flags |= IW_POWER_MULTICAST_R;
 644         else
 645                 wrqu->power.flags |= IW_POWER_UNICAST_R;
 646 
 647 exit:
 648         mutex_unlock(&ieee->wx_mutex);
 649         return 0;
 650 
 651 }
 652 EXPORT_SYMBOL(rtllib_wx_get_power);

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