root/drivers/staging/wlan-ng/prism2mgmt.c

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

DEFINITIONS

This source file includes following definitions.
  1. p80211rate_to_p2bit
  2. prism2mgmt_scan
  3. prism2mgmt_scan_results
  4. prism2mgmt_start
  5. prism2mgmt_readpda
  6. prism2mgmt_ramdl_state
  7. prism2mgmt_ramdl_write
  8. prism2mgmt_flashdl_state
  9. prism2mgmt_flashdl_write
  10. prism2mgmt_autojoin
  11. prism2mgmt_wlansniff

   1 // SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
   2 /* src/prism2/driver/prism2mgmt.c
   3  *
   4  * Management request handler functions.
   5  *
   6  * Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
   7  * --------------------------------------------------------------------
   8  *
   9  * linux-wlan
  10  *
  11  *   The contents of this file are subject to the Mozilla Public
  12  *   License Version 1.1 (the "License"); you may not use this file
  13  *   except in compliance with the License. You may obtain a copy of
  14  *   the License at http://www.mozilla.org/MPL/
  15  *
  16  *   Software distributed under the License is distributed on an "AS
  17  *   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  18  *   implied. See the License for the specific language governing
  19  *   rights and limitations under the License.
  20  *
  21  *   Alternatively, the contents of this file may be used under the
  22  *   terms of the GNU Public License version 2 (the "GPL"), in which
  23  *   case the provisions of the GPL are applicable instead of the
  24  *   above.  If you wish to allow the use of your version of this file
  25  *   only under the terms of the GPL and not to allow others to use
  26  *   your version of this file under the MPL, indicate your decision
  27  *   by deleting the provisions above and replace them with the notice
  28  *   and other provisions required by the GPL.  If you do not delete
  29  *   the provisions above, a recipient may use your version of this
  30  *   file under either the MPL or the GPL.
  31  *
  32  * --------------------------------------------------------------------
  33  *
  34  * Inquiries regarding the linux-wlan Open Source project can be
  35  * made directly to:
  36  *
  37  * AbsoluteValue Systems Inc.
  38  * info@linux-wlan.com
  39  * http://www.linux-wlan.com
  40  *
  41  * --------------------------------------------------------------------
  42  *
  43  * Portions of the development of this software were funded by
  44  * Intersil Corporation as part of PRISM(R) chipset product development.
  45  *
  46  * --------------------------------------------------------------------
  47  *
  48  * The functions in this file handle management requests sent from
  49  * user mode.
  50  *
  51  * Most of these functions have two separate blocks of code that are
  52  * conditional on whether this is a station or an AP.  This is used
  53  * to separate out the STA and AP responses to these management primitives.
  54  * It's a choice (good, bad, indifferent?) to have the code in the same
  55  * place so it's clear that the same primitive is implemented in both
  56  * cases but has different behavior.
  57  *
  58  * --------------------------------------------------------------------
  59  */
  60 
  61 #include <linux/if_arp.h>
  62 #include <linux/module.h>
  63 #include <linux/kernel.h>
  64 #include <linux/wait.h>
  65 #include <linux/sched.h>
  66 #include <linux/types.h>
  67 #include <linux/wireless.h>
  68 #include <linux/netdevice.h>
  69 #include <linux/delay.h>
  70 #include <linux/io.h>
  71 #include <asm/byteorder.h>
  72 #include <linux/random.h>
  73 #include <linux/usb.h>
  74 #include <linux/bitops.h>
  75 
  76 #include "p80211types.h"
  77 #include "p80211hdr.h"
  78 #include "p80211mgmt.h"
  79 #include "p80211conv.h"
  80 #include "p80211msg.h"
  81 #include "p80211netdev.h"
  82 #include "p80211metadef.h"
  83 #include "p80211metastruct.h"
  84 #include "hfa384x.h"
  85 #include "prism2mgmt.h"
  86 
  87 /* Converts 802.11 format rate specifications to prism2 */
  88 static inline u16 p80211rate_to_p2bit(u32 rate)
  89 {
  90         switch (rate & ~BIT(7)) {
  91         case 2:
  92                 return BIT(0);
  93         case 4:
  94                 return BIT(1);
  95         case 11:
  96                 return BIT(2);
  97         case 22:
  98                 return BIT(3);
  99         default:
 100                 return 0;
 101         }
 102 }
 103 
 104 /*----------------------------------------------------------------
 105  * prism2mgmt_scan
 106  *
 107  * Initiate a scan for BSSs.
 108  *
 109  * This function corresponds to MLME-scan.request and part of
 110  * MLME-scan.confirm.  As far as I can tell in the standard, there
 111  * are no restrictions on when a scan.request may be issued.  We have
 112  * to handle in whatever state the driver/MAC happen to be.
 113  *
 114  * Arguments:
 115  *      wlandev         wlan device structure
 116  *      msgp            ptr to msg buffer
 117  *
 118  * Returns:
 119  *      0       success and done
 120  *      <0      success, but we're waiting for something to finish.
 121  *      >0      an error occurred while handling the message.
 122  * Side effects:
 123  *
 124  * Call context:
 125  *      process thread  (usually)
 126  *      interrupt
 127  *----------------------------------------------------------------
 128  */
 129 int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp)
 130 {
 131         int result = 0;
 132         struct hfa384x *hw = wlandev->priv;
 133         struct p80211msg_dot11req_scan *msg = msgp;
 134         u16 roamingmode, word;
 135         int i, timeout;
 136         int istmpenable = 0;
 137 
 138         struct hfa384x_host_scan_request_data scanreq;
 139 
 140         /* gatekeeper check */
 141         if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
 142                                      hw->ident_sta_fw.minor,
 143                                      hw->ident_sta_fw.variant) <
 144             HFA384x_FIRMWARE_VERSION(1, 3, 2)) {
 145                 netdev_err(wlandev->netdev,
 146                            "HostScan not supported with current firmware (<1.3.2).\n");
 147                 result = 1;
 148                 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
 149                 goto exit;
 150         }
 151 
 152         memset(&scanreq, 0, sizeof(scanreq));
 153 
 154         /* save current roaming mode */
 155         result = hfa384x_drvr_getconfig16(hw,
 156                                           HFA384x_RID_CNFROAMINGMODE,
 157                                           &roamingmode);
 158         if (result) {
 159                 netdev_err(wlandev->netdev,
 160                            "getconfig(ROAMMODE) failed. result=%d\n", result);
 161                 msg->resultcode.data =
 162                     P80211ENUM_resultcode_implementation_failure;
 163                 goto exit;
 164         }
 165 
 166         /* drop into mode 3 for the scan */
 167         result = hfa384x_drvr_setconfig16(hw,
 168                                           HFA384x_RID_CNFROAMINGMODE,
 169                                           HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
 170         if (result) {
 171                 netdev_err(wlandev->netdev,
 172                            "setconfig(ROAMINGMODE) failed. result=%d\n",
 173                            result);
 174                 msg->resultcode.data =
 175                     P80211ENUM_resultcode_implementation_failure;
 176                 goto exit;
 177         }
 178 
 179         /* active or passive? */
 180         if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
 181                                      hw->ident_sta_fw.minor,
 182                                      hw->ident_sta_fw.variant) >
 183             HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
 184                 if (msg->scantype.data != P80211ENUM_scantype_active)
 185                         word = msg->maxchanneltime.data;
 186                 else
 187                         word = 0;
 188 
 189                 result =
 190                     hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
 191                                              word);
 192                 if (result) {
 193                         netdev_warn(wlandev->netdev,
 194                                     "Passive scan not supported with current firmware.  (<1.5.1)\n");
 195                 }
 196         }
 197 
 198         /* set up the txrate to be 2MBPS. Should be fastest basicrate... */
 199         word = HFA384x_RATEBIT_2;
 200         scanreq.tx_rate = cpu_to_le16(word);
 201 
 202         /* set up the channel list */
 203         word = 0;
 204         for (i = 0; i < msg->channellist.data.len; i++) {
 205                 u8 channel = msg->channellist.data.data[i];
 206 
 207                 if (channel > 14)
 208                         continue;
 209                 /* channel 1 is BIT 0 ... channel 14 is BIT 13 */
 210                 word |= (1 << (channel - 1));
 211         }
 212         scanreq.channel_list = cpu_to_le16(word);
 213 
 214         /* set up the ssid, if present. */
 215         scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len);
 216         memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
 217 
 218         /* Enable the MAC port if it's not already enabled  */
 219         result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
 220         if (result) {
 221                 netdev_err(wlandev->netdev,
 222                            "getconfig(PORTSTATUS) failed. result=%d\n", result);
 223                 msg->resultcode.data =
 224                     P80211ENUM_resultcode_implementation_failure;
 225                 goto exit;
 226         }
 227         if (word == HFA384x_PORTSTATUS_DISABLED) {
 228                 __le16 wordbuf[17];
 229 
 230                 result = hfa384x_drvr_setconfig16(hw,
 231                                         HFA384x_RID_CNFROAMINGMODE,
 232                                         HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
 233                 if (result) {
 234                         netdev_err(wlandev->netdev,
 235                                    "setconfig(ROAMINGMODE) failed. result=%d\n",
 236                                    result);
 237                         msg->resultcode.data =
 238                             P80211ENUM_resultcode_implementation_failure;
 239                         goto exit;
 240                 }
 241                 /* Construct a bogus SSID and assign it to OwnSSID and
 242                  * DesiredSSID
 243                  */
 244                 wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN);
 245                 get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
 246                 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
 247                                                 wordbuf,
 248                                                 HFA384x_RID_CNFOWNSSID_LEN);
 249                 if (result) {
 250                         netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n");
 251                         msg->resultcode.data =
 252                             P80211ENUM_resultcode_implementation_failure;
 253                         goto exit;
 254                 }
 255                 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
 256                                                 wordbuf,
 257                                                 HFA384x_RID_CNFDESIREDSSID_LEN);
 258                 if (result) {
 259                         netdev_err(wlandev->netdev,
 260                                    "Failed to set DesiredSSID.\n");
 261                         msg->resultcode.data =
 262                             P80211ENUM_resultcode_implementation_failure;
 263                         goto exit;
 264                 }
 265                 /* bsstype */
 266                 result = hfa384x_drvr_setconfig16(hw,
 267                                                   HFA384x_RID_CNFPORTTYPE,
 268                                                   HFA384x_PORTTYPE_IBSS);
 269                 if (result) {
 270                         netdev_err(wlandev->netdev,
 271                                    "Failed to set CNFPORTTYPE.\n");
 272                         msg->resultcode.data =
 273                             P80211ENUM_resultcode_implementation_failure;
 274                         goto exit;
 275                 }
 276                 /* ibss options */
 277                 result = hfa384x_drvr_setconfig16(hw,
 278                                         HFA384x_RID_CREATEIBSS,
 279                                         HFA384x_CREATEIBSS_JOINCREATEIBSS);
 280                 if (result) {
 281                         netdev_err(wlandev->netdev,
 282                                    "Failed to set CREATEIBSS.\n");
 283                         msg->resultcode.data =
 284                             P80211ENUM_resultcode_implementation_failure;
 285                         goto exit;
 286                 }
 287                 result = hfa384x_drvr_enable(hw, 0);
 288                 if (result) {
 289                         netdev_err(wlandev->netdev,
 290                                    "drvr_enable(0) failed. result=%d\n",
 291                                    result);
 292                         msg->resultcode.data =
 293                             P80211ENUM_resultcode_implementation_failure;
 294                         goto exit;
 295                 }
 296                 istmpenable = 1;
 297         }
 298 
 299         /* Figure out our timeout first Kus, then HZ */
 300         timeout = msg->channellist.data.len * msg->maxchanneltime.data;
 301         timeout = (timeout * HZ) / 1000;
 302 
 303         /* Issue the scan request */
 304         hw->scanflag = 0;
 305 
 306         result = hfa384x_drvr_setconfig(hw,
 307                                         HFA384x_RID_HOSTSCAN, &scanreq,
 308                                         sizeof(scanreq));
 309         if (result) {
 310                 netdev_err(wlandev->netdev,
 311                            "setconfig(SCANREQUEST) failed. result=%d\n",
 312                            result);
 313                 msg->resultcode.data =
 314                     P80211ENUM_resultcode_implementation_failure;
 315                 goto exit;
 316         }
 317 
 318         /* sleep until info frame arrives */
 319         wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
 320 
 321         msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
 322         if (hw->scanflag == -1)
 323                 hw->scanflag = 0;
 324 
 325         msg->numbss.data = hw->scanflag;
 326 
 327         hw->scanflag = 0;
 328 
 329         /* Disable port if we temporarily enabled it. */
 330         if (istmpenable) {
 331                 result = hfa384x_drvr_disable(hw, 0);
 332                 if (result) {
 333                         netdev_err(wlandev->netdev,
 334                                    "drvr_disable(0) failed. result=%d\n",
 335                                    result);
 336                         msg->resultcode.data =
 337                             P80211ENUM_resultcode_implementation_failure;
 338                         goto exit;
 339                 }
 340         }
 341 
 342         /* restore original roaming mode */
 343         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
 344                                           roamingmode);
 345         if (result) {
 346                 netdev_err(wlandev->netdev,
 347                            "setconfig(ROAMMODE) failed. result=%d\n", result);
 348                 msg->resultcode.data =
 349                     P80211ENUM_resultcode_implementation_failure;
 350                 goto exit;
 351         }
 352 
 353         result = 0;
 354         msg->resultcode.data = P80211ENUM_resultcode_success;
 355 
 356 exit:
 357         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 358 
 359         return result;
 360 }
 361 
 362 /*----------------------------------------------------------------
 363  * prism2mgmt_scan_results
 364  *
 365  * Retrieve the BSS description for one of the BSSs identified in
 366  * a scan.
 367  *
 368  * Arguments:
 369  *      wlandev         wlan device structure
 370  *      msgp            ptr to msg buffer
 371  *
 372  * Returns:
 373  *      0       success and done
 374  *      <0      success, but we're waiting for something to finish.
 375  *      >0      an error occurred while handling the message.
 376  * Side effects:
 377  *
 378  * Call context:
 379  *      process thread  (usually)
 380  *      interrupt
 381  *----------------------------------------------------------------
 382  */
 383 int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp)
 384 {
 385         int result = 0;
 386         struct p80211msg_dot11req_scan_results *req;
 387         struct hfa384x *hw = wlandev->priv;
 388         struct hfa384x_hscan_result_sub *item = NULL;
 389 
 390         int count;
 391 
 392         req = msgp;
 393 
 394         req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 395 
 396         if (!hw->scanresults) {
 397                 netdev_err(wlandev->netdev,
 398                            "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
 399                 result = 2;
 400                 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 401                 goto exit;
 402         }
 403 
 404         count = (hw->scanresults->framelen - 3) / 32;
 405         if (count > HFA384x_SCANRESULT_MAX)
 406                 count = HFA384x_SCANRESULT_MAX;
 407 
 408         if (req->bssindex.data >= count) {
 409                 netdev_dbg(wlandev->netdev,
 410                            "requested index (%d) out of range (%d)\n",
 411                            req->bssindex.data, count);
 412                 result = 2;
 413                 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 414                 goto exit;
 415         }
 416 
 417         item = &hw->scanresults->info.hscanresult.result[req->bssindex.data];
 418         /* signal and noise */
 419         req->signal.status = P80211ENUM_msgitem_status_data_ok;
 420         req->noise.status = P80211ENUM_msgitem_status_data_ok;
 421         req->signal.data = le16_to_cpu(item->sl);
 422         req->noise.data = le16_to_cpu(item->anl);
 423 
 424         /* BSSID */
 425         req->bssid.status = P80211ENUM_msgitem_status_data_ok;
 426         req->bssid.data.len = WLAN_BSSID_LEN;
 427         memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
 428 
 429         /* SSID */
 430         req->ssid.status = P80211ENUM_msgitem_status_data_ok;
 431         req->ssid.data.len = le16_to_cpu(item->ssid.len);
 432         req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN);
 433         memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
 434 
 435         /* supported rates */
 436         for (count = 0; count < 10; count++)
 437                 if (item->supprates[count] == 0)
 438                         break;
 439 
 440 #define REQBASICRATE(N) \
 441         do { \
 442                 if ((count >= (N)) && DOT11_RATE5_ISBASIC_GET(  \
 443                         item->supprates[(N) - 1])) { \
 444                         req->basicrate ## N .data = item->supprates[(N) - 1]; \
 445                         req->basicrate ## N .status = \
 446                                 P80211ENUM_msgitem_status_data_ok; \
 447                 } \
 448         } while (0)
 449 
 450         REQBASICRATE(1);
 451         REQBASICRATE(2);
 452         REQBASICRATE(3);
 453         REQBASICRATE(4);
 454         REQBASICRATE(5);
 455         REQBASICRATE(6);
 456         REQBASICRATE(7);
 457         REQBASICRATE(8);
 458 
 459 #define REQSUPPRATE(N) \
 460         do { \
 461                 if (count >= (N)) {                                     \
 462                         req->supprate ## N .data = item->supprates[(N) - 1]; \
 463                         req->supprate ## N .status = \
 464                                 P80211ENUM_msgitem_status_data_ok; \
 465                 } \
 466         } while (0)
 467 
 468         REQSUPPRATE(1);
 469         REQSUPPRATE(2);
 470         REQSUPPRATE(3);
 471         REQSUPPRATE(4);
 472         REQSUPPRATE(5);
 473         REQSUPPRATE(6);
 474         REQSUPPRATE(7);
 475         REQSUPPRATE(8);
 476 
 477         /* beacon period */
 478         req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
 479         req->beaconperiod.data = le16_to_cpu(item->bcnint);
 480 
 481         /* timestamps */
 482         req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
 483         req->timestamp.data = jiffies;
 484         req->localtime.status = P80211ENUM_msgitem_status_data_ok;
 485         req->localtime.data = jiffies;
 486 
 487         /* atim window */
 488         req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
 489         req->ibssatimwindow.data = le16_to_cpu(item->atim);
 490 
 491         /* Channel */
 492         req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
 493         req->dschannel.data = le16_to_cpu(item->chid);
 494 
 495         /* capinfo bits */
 496         count = le16_to_cpu(item->capinfo);
 497         req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
 498         req->capinfo.data = count;
 499 
 500         /* privacy flag */
 501         req->privacy.status = P80211ENUM_msgitem_status_data_ok;
 502         req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
 503 
 504         /* cfpollable */
 505         req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
 506         req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
 507 
 508         /* cfpollreq */
 509         req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
 510         req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
 511 
 512         /* bsstype */
 513         req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
 514         req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
 515             P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
 516 
 517         result = 0;
 518         req->resultcode.data = P80211ENUM_resultcode_success;
 519 
 520 exit:
 521         return result;
 522 }
 523 
 524 /*----------------------------------------------------------------
 525  * prism2mgmt_start
 526  *
 527  * Start a BSS.  Any station can do this for IBSS, only AP for ESS.
 528  *
 529  * Arguments:
 530  *      wlandev         wlan device structure
 531  *      msgp            ptr to msg buffer
 532  *
 533  * Returns:
 534  *      0       success and done
 535  *      <0      success, but we're waiting for something to finish.
 536  *      >0      an error occurred while handling the message.
 537  * Side effects:
 538  *
 539  * Call context:
 540  *      process thread  (usually)
 541  *      interrupt
 542  *----------------------------------------------------------------
 543  */
 544 int prism2mgmt_start(struct wlandevice *wlandev, void *msgp)
 545 {
 546         int result = 0;
 547         struct hfa384x *hw = wlandev->priv;
 548         struct p80211msg_dot11req_start *msg = msgp;
 549 
 550         struct p80211pstrd *pstr;
 551         u8 bytebuf[80];
 552         struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
 553         u16 word;
 554 
 555         wlandev->macmode = WLAN_MACMODE_NONE;
 556 
 557         /* Set the SSID */
 558         memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
 559 
 560         /*** ADHOC IBSS ***/
 561         /* see if current f/w is less than 8c3 */
 562         if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
 563                                      hw->ident_sta_fw.minor,
 564                                      hw->ident_sta_fw.variant) <
 565             HFA384x_FIRMWARE_VERSION(0, 8, 3)) {
 566                 /* Ad-Hoc not quite supported on Prism2 */
 567                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 568                 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
 569                 goto done;
 570         }
 571 
 572         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 573 
 574         /*** STATION ***/
 575         /* Set the REQUIRED config items */
 576         /* SSID */
 577         pstr = (struct p80211pstrd *)&msg->ssid.data;
 578         prism2mgmt_pstr2bytestr(p2bytestr, pstr);
 579         result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
 580                                         bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
 581         if (result) {
 582                 netdev_err(wlandev->netdev, "Failed to set CnfOwnSSID\n");
 583                 goto failed;
 584         }
 585         result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
 586                                         bytebuf,
 587                                         HFA384x_RID_CNFDESIREDSSID_LEN);
 588         if (result) {
 589                 netdev_err(wlandev->netdev, "Failed to set CnfDesiredSSID\n");
 590                 goto failed;
 591         }
 592 
 593         /* bsstype - we use the default in the ap firmware */
 594         /* IBSS port */
 595         hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
 596 
 597         /* beacon period */
 598         word = msg->beaconperiod.data;
 599         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
 600         if (result) {
 601                 netdev_err(wlandev->netdev,
 602                            "Failed to set beacon period=%d.\n", word);
 603                 goto failed;
 604         }
 605 
 606         /* dschannel */
 607         word = msg->dschannel.data;
 608         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
 609         if (result) {
 610                 netdev_err(wlandev->netdev,
 611                            "Failed to set channel=%d.\n", word);
 612                 goto failed;
 613         }
 614         /* Basic rates */
 615         word = p80211rate_to_p2bit(msg->basicrate1.data);
 616         if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok)
 617                 word |= p80211rate_to_p2bit(msg->basicrate2.data);
 618 
 619         if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok)
 620                 word |= p80211rate_to_p2bit(msg->basicrate3.data);
 621 
 622         if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok)
 623                 word |= p80211rate_to_p2bit(msg->basicrate4.data);
 624 
 625         if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok)
 626                 word |= p80211rate_to_p2bit(msg->basicrate5.data);
 627 
 628         if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok)
 629                 word |= p80211rate_to_p2bit(msg->basicrate6.data);
 630 
 631         if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok)
 632                 word |= p80211rate_to_p2bit(msg->basicrate7.data);
 633 
 634         if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok)
 635                 word |= p80211rate_to_p2bit(msg->basicrate8.data);
 636 
 637         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
 638         if (result) {
 639                 netdev_err(wlandev->netdev,
 640                            "Failed to set basicrates=%d.\n", word);
 641                 goto failed;
 642         }
 643 
 644         /* Operational rates (supprates and txratecontrol) */
 645         word = p80211rate_to_p2bit(msg->operationalrate1.data);
 646         if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok)
 647                 word |= p80211rate_to_p2bit(msg->operationalrate2.data);
 648 
 649         if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok)
 650                 word |= p80211rate_to_p2bit(msg->operationalrate3.data);
 651 
 652         if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok)
 653                 word |= p80211rate_to_p2bit(msg->operationalrate4.data);
 654 
 655         if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok)
 656                 word |= p80211rate_to_p2bit(msg->operationalrate5.data);
 657 
 658         if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok)
 659                 word |= p80211rate_to_p2bit(msg->operationalrate6.data);
 660 
 661         if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok)
 662                 word |= p80211rate_to_p2bit(msg->operationalrate7.data);
 663 
 664         if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok)
 665                 word |= p80211rate_to_p2bit(msg->operationalrate8.data);
 666 
 667         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
 668         if (result) {
 669                 netdev_err(wlandev->netdev,
 670                            "Failed to set supprates=%d.\n", word);
 671                 goto failed;
 672         }
 673 
 674         result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
 675         if (result) {
 676                 netdev_err(wlandev->netdev, "Failed to set txrates=%d.\n",
 677                            word);
 678                 goto failed;
 679         }
 680 
 681         /* Set the macmode so the frame setup code knows what to do */
 682         if (msg->bsstype.data == P80211ENUM_bsstype_independent) {
 683                 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
 684                 /* lets extend the data length a bit */
 685                 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
 686         }
 687 
 688         /* Enable the Port */
 689         result = hfa384x_drvr_enable(hw, 0);
 690         if (result) {
 691                 netdev_err(wlandev->netdev,
 692                            "Enable macport failed, result=%d.\n", result);
 693                 goto failed;
 694         }
 695 
 696         msg->resultcode.data = P80211ENUM_resultcode_success;
 697 
 698         goto done;
 699 failed:
 700         netdev_dbg(wlandev->netdev,
 701                    "Failed to set a config option, result=%d\n", result);
 702         msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 703 
 704 done:
 705         return 0;
 706 }
 707 
 708 /*----------------------------------------------------------------
 709  * prism2mgmt_readpda
 710  *
 711  * Collect the PDA data and put it in the message.
 712  *
 713  * Arguments:
 714  *      wlandev         wlan device structure
 715  *      msgp            ptr to msg buffer
 716  *
 717  * Returns:
 718  *      0       success and done
 719  *      <0      success, but we're waiting for something to finish.
 720  *      >0      an error occurred while handling the message.
 721  * Side effects:
 722  *
 723  * Call context:
 724  *      process thread  (usually)
 725  *----------------------------------------------------------------
 726  */
 727 int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp)
 728 {
 729         struct hfa384x *hw = wlandev->priv;
 730         struct p80211msg_p2req_readpda *msg = msgp;
 731         int result;
 732 
 733         /* We only support collecting the PDA when in the FWLOAD
 734          * state.
 735          */
 736         if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
 737                 netdev_err(wlandev->netdev,
 738                            "PDA may only be read in the fwload state.\n");
 739                 msg->resultcode.data =
 740                     P80211ENUM_resultcode_implementation_failure;
 741                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 742         } else {
 743                 /*  Call drvr_readpda(), it handles the auxport enable
 744                  *  and validating the returned PDA.
 745                  */
 746                 result = hfa384x_drvr_readpda(hw,
 747                                               msg->pda.data,
 748                                               HFA384x_PDA_LEN_MAX);
 749                 if (result) {
 750                         netdev_err(wlandev->netdev,
 751                                    "hfa384x_drvr_readpda() failed, result=%d\n",
 752                                    result);
 753 
 754                         msg->resultcode.data =
 755                             P80211ENUM_resultcode_implementation_failure;
 756                         msg->resultcode.status =
 757                             P80211ENUM_msgitem_status_data_ok;
 758                         return 0;
 759                 }
 760                 msg->pda.status = P80211ENUM_msgitem_status_data_ok;
 761                 msg->resultcode.data = P80211ENUM_resultcode_success;
 762                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 763         }
 764 
 765         return 0;
 766 }
 767 
 768 /*----------------------------------------------------------------
 769  * prism2mgmt_ramdl_state
 770  *
 771  * Establishes the beginning/end of a card RAM download session.
 772  *
 773  * It is expected that the ramdl_write() function will be called
 774  * one or more times between the 'enable' and 'disable' calls to
 775  * this function.
 776  *
 777  * Note: This function should not be called when a mac comm port
 778  *       is active.
 779  *
 780  * Arguments:
 781  *      wlandev         wlan device structure
 782  *      msgp            ptr to msg buffer
 783  *
 784  * Returns:
 785  *      0       success and done
 786  *      <0      success, but we're waiting for something to finish.
 787  *      >0      an error occurred while handling the message.
 788  * Side effects:
 789  *
 790  * Call context:
 791  *      process thread  (usually)
 792  *----------------------------------------------------------------
 793  */
 794 int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp)
 795 {
 796         struct hfa384x *hw = wlandev->priv;
 797         struct p80211msg_p2req_ramdl_state *msg = msgp;
 798 
 799         if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
 800                 netdev_err(wlandev->netdev,
 801                            "ramdl_state(): may only be called in the fwload state.\n");
 802                 msg->resultcode.data =
 803                     P80211ENUM_resultcode_implementation_failure;
 804                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 805                 return 0;
 806         }
 807 
 808         /*
 809          ** Note: Interrupts are locked out if this is an AP and are NOT
 810          ** locked out if this is a station.
 811          */
 812 
 813         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 814         if (msg->enable.data == P80211ENUM_truth_true) {
 815                 if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) {
 816                         msg->resultcode.data =
 817                             P80211ENUM_resultcode_implementation_failure;
 818                 } else {
 819                         msg->resultcode.data = P80211ENUM_resultcode_success;
 820                 }
 821         } else {
 822                 hfa384x_drvr_ramdl_disable(hw);
 823                 msg->resultcode.data = P80211ENUM_resultcode_success;
 824         }
 825 
 826         return 0;
 827 }
 828 
 829 /*----------------------------------------------------------------
 830  * prism2mgmt_ramdl_write
 831  *
 832  * Writes a buffer to the card RAM using the download state.  This
 833  * is for writing code to card RAM.  To just read or write raw data
 834  * use the aux functions.
 835  *
 836  * Arguments:
 837  *      wlandev         wlan device structure
 838  *      msgp            ptr to msg buffer
 839  *
 840  * Returns:
 841  *      0       success and done
 842  *      <0      success, but we're waiting for something to finish.
 843  *      >0      an error occurred while handling the message.
 844  * Side effects:
 845  *
 846  * Call context:
 847  *      process thread  (usually)
 848  *----------------------------------------------------------------
 849  */
 850 int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp)
 851 {
 852         struct hfa384x *hw = wlandev->priv;
 853         struct p80211msg_p2req_ramdl_write *msg = msgp;
 854         u32 addr;
 855         u32 len;
 856         u8 *buf;
 857 
 858         if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
 859                 netdev_err(wlandev->netdev,
 860                            "ramdl_write(): may only be called in the fwload state.\n");
 861                 msg->resultcode.data =
 862                     P80211ENUM_resultcode_implementation_failure;
 863                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 864                 return 0;
 865         }
 866 
 867         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 868         /* first validate the length */
 869         if (msg->len.data > sizeof(msg->data.data)) {
 870                 msg->resultcode.status =
 871                     P80211ENUM_resultcode_invalid_parameters;
 872                 return 0;
 873         }
 874         /* call the hfa384x function to do the write */
 875         addr = msg->addr.data;
 876         len = msg->len.data;
 877         buf = msg->data.data;
 878         if (hfa384x_drvr_ramdl_write(hw, addr, buf, len))
 879                 msg->resultcode.data = P80211ENUM_resultcode_refused;
 880 
 881         msg->resultcode.data = P80211ENUM_resultcode_success;
 882 
 883         return 0;
 884 }
 885 
 886 /*----------------------------------------------------------------
 887  * prism2mgmt_flashdl_state
 888  *
 889  * Establishes the beginning/end of a card Flash download session.
 890  *
 891  * It is expected that the flashdl_write() function will be called
 892  * one or more times between the 'enable' and 'disable' calls to
 893  * this function.
 894  *
 895  * Note: This function should not be called when a mac comm port
 896  *       is active.
 897  *
 898  * Arguments:
 899  *      wlandev         wlan device structure
 900  *      msgp            ptr to msg buffer
 901  *
 902  * Returns:
 903  *      0       success and done
 904  *      <0      success, but we're waiting for something to finish.
 905  *      >0      an error occurred while handling the message.
 906  * Side effects:
 907  *
 908  * Call context:
 909  *      process thread  (usually)
 910  *----------------------------------------------------------------
 911  */
 912 int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
 913 {
 914         int result = 0;
 915         struct hfa384x *hw = wlandev->priv;
 916         struct p80211msg_p2req_flashdl_state *msg = msgp;
 917 
 918         if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
 919                 netdev_err(wlandev->netdev,
 920                            "flashdl_state(): may only be called in the fwload state.\n");
 921                 msg->resultcode.data =
 922                     P80211ENUM_resultcode_implementation_failure;
 923                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 924                 return 0;
 925         }
 926 
 927         /*
 928          ** Note: Interrupts are locked out if this is an AP and are NOT
 929          ** locked out if this is a station.
 930          */
 931 
 932         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 933         if (msg->enable.data == P80211ENUM_truth_true) {
 934                 if (hfa384x_drvr_flashdl_enable(hw)) {
 935                         msg->resultcode.data =
 936                             P80211ENUM_resultcode_implementation_failure;
 937                 } else {
 938                         msg->resultcode.data = P80211ENUM_resultcode_success;
 939                 }
 940         } else {
 941                 hfa384x_drvr_flashdl_disable(hw);
 942                 msg->resultcode.data = P80211ENUM_resultcode_success;
 943                 /* NOTE: At this point, the MAC is in the post-reset
 944                  * state and the driver is in the fwload state.
 945                  * We need to get the MAC back into the fwload
 946                  * state.  To do this, we set the nsdstate to HWPRESENT
 947                  * and then call the ifstate function to redo everything
 948                  * that got us into the fwload state.
 949                  */
 950                 wlandev->msdstate = WLAN_MSD_HWPRESENT;
 951                 result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
 952                 if (result != P80211ENUM_resultcode_success) {
 953                         netdev_err(wlandev->netdev,
 954                                    "prism2sta_ifstate(fwload) failed, P80211ENUM_resultcode=%d\n",
 955                                    result);
 956                         msg->resultcode.data =
 957                             P80211ENUM_resultcode_implementation_failure;
 958                         result = -1;
 959                 }
 960         }
 961 
 962         return result;
 963 }
 964 
 965 /*----------------------------------------------------------------
 966  * prism2mgmt_flashdl_write
 967  *
 968  *
 969  *
 970  * Arguments:
 971  *      wlandev         wlan device structure
 972  *      msgp            ptr to msg buffer
 973  *
 974  * Returns:
 975  *      0       success and done
 976  *      <0      success, but we're waiting for something to finish.
 977  *      >0      an error occurred while handling the message.
 978  * Side effects:
 979  *
 980  * Call context:
 981  *      process thread  (usually)
 982  *----------------------------------------------------------------
 983  */
 984 int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp)
 985 {
 986         struct hfa384x *hw = wlandev->priv;
 987         struct p80211msg_p2req_flashdl_write *msg = msgp;
 988         u32 addr;
 989         u32 len;
 990         u8 *buf;
 991 
 992         if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
 993                 netdev_err(wlandev->netdev,
 994                            "flashdl_write(): may only be called in the fwload state.\n");
 995                 msg->resultcode.data =
 996                     P80211ENUM_resultcode_implementation_failure;
 997                 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 998                 return 0;
 999         }
1000 
1001         /*
1002          ** Note: Interrupts are locked out if this is an AP and are NOT
1003          ** locked out if this is a station.
1004          */
1005 
1006         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1007         /* first validate the length */
1008         if (msg->len.data > sizeof(msg->data.data)) {
1009                 msg->resultcode.status =
1010                     P80211ENUM_resultcode_invalid_parameters;
1011                 return 0;
1012         }
1013         /* call the hfa384x function to do the write */
1014         addr = msg->addr.data;
1015         len = msg->len.data;
1016         buf = msg->data.data;
1017         if (hfa384x_drvr_flashdl_write(hw, addr, buf, len))
1018                 msg->resultcode.data = P80211ENUM_resultcode_refused;
1019 
1020         msg->resultcode.data = P80211ENUM_resultcode_success;
1021 
1022         return 0;
1023 }
1024 
1025 /*----------------------------------------------------------------
1026  * prism2mgmt_autojoin
1027  *
1028  * Associate with an ESS.
1029  *
1030  * Arguments:
1031  *      wlandev         wlan device structure
1032  *      msgp            ptr to msg buffer
1033  *
1034  * Returns:
1035  *      0       success and done
1036  *      <0      success, but we're waiting for something to finish.
1037  *      >0      an error occurred while handling the message.
1038  * Side effects:
1039  *
1040  * Call context:
1041  *      process thread  (usually)
1042  *      interrupt
1043  *----------------------------------------------------------------
1044  */
1045 int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp)
1046 {
1047         struct hfa384x *hw = wlandev->priv;
1048         int result = 0;
1049         u16 reg;
1050         u16 port_type;
1051         struct p80211msg_lnxreq_autojoin *msg = msgp;
1052         struct p80211pstrd *pstr;
1053         u8 bytebuf[256];
1054         struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
1055 
1056         wlandev->macmode = WLAN_MACMODE_NONE;
1057 
1058         /* Set the SSID */
1059         memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
1060 
1061         /* Disable the Port */
1062         hfa384x_drvr_disable(hw, 0);
1063 
1064         /*** STATION ***/
1065         /* Set the TxRates */
1066         hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
1067 
1068         /* Set the auth type */
1069         if (msg->authtype.data == P80211ENUM_authalg_sharedkey)
1070                 reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
1071         else
1072                 reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
1073 
1074         hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
1075 
1076         /* Set the ssid */
1077         memset(bytebuf, 0, 256);
1078         pstr = (struct p80211pstrd *)&msg->ssid.data;
1079         prism2mgmt_pstr2bytestr(p2bytestr, pstr);
1080         result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
1081                                         bytebuf,
1082                                         HFA384x_RID_CNFDESIREDSSID_LEN);
1083         port_type = HFA384x_PORTTYPE_BSS;
1084         /* Set the PortType */
1085         hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
1086 
1087         /* Enable the Port */
1088         hfa384x_drvr_enable(hw, 0);
1089 
1090         /* Set the resultcode */
1091         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1092         msg->resultcode.data = P80211ENUM_resultcode_success;
1093 
1094         return result;
1095 }
1096 
1097 /*----------------------------------------------------------------
1098  * prism2mgmt_wlansniff
1099  *
1100  * Start or stop sniffing.
1101  *
1102  * Arguments:
1103  *      wlandev         wlan device structure
1104  *      msgp            ptr to msg buffer
1105  *
1106  * Returns:
1107  *      0       success and done
1108  *      <0      success, but we're waiting for something to finish.
1109  *      >0      an error occurred while handling the message.
1110  * Side effects:
1111  *
1112  * Call context:
1113  *      process thread  (usually)
1114  *      interrupt
1115  *----------------------------------------------------------------
1116  */
1117 int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp)
1118 {
1119         int result = 0;
1120         struct p80211msg_lnxreq_wlansniff *msg = msgp;
1121 
1122         struct hfa384x *hw = wlandev->priv;
1123         u16 word;
1124 
1125         msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1126         switch (msg->enable.data) {
1127         case P80211ENUM_truth_false:
1128                 /* Confirm that we're in monitor mode */
1129                 if (wlandev->netdev->type == ARPHRD_ETHER) {
1130                         msg->resultcode.data =
1131                             P80211ENUM_resultcode_invalid_parameters;
1132                         return 0;
1133                 }
1134                 /* Disable monitor mode */
1135                 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
1136                 if (result) {
1137                         netdev_dbg(wlandev->netdev,
1138                                    "failed to disable monitor mode, result=%d\n",
1139                                    result);
1140                         goto failed;
1141                 }
1142                 /* Disable port 0 */
1143                 result = hfa384x_drvr_disable(hw, 0);
1144                 if (result) {
1145                         netdev_dbg
1146                         (wlandev->netdev,
1147                              "failed to disable port 0 after sniffing, result=%d\n",
1148                              result);
1149                         goto failed;
1150                 }
1151                 /* Clear the driver state */
1152                 wlandev->netdev->type = ARPHRD_ETHER;
1153 
1154                 /* Restore the wepflags */
1155                 result = hfa384x_drvr_setconfig16(hw,
1156                                                   HFA384x_RID_CNFWEPFLAGS,
1157                                                   hw->presniff_wepflags);
1158                 if (result) {
1159                         netdev_dbg
1160                             (wlandev->netdev,
1161                              "failed to restore wepflags=0x%04x, result=%d\n",
1162                              hw->presniff_wepflags, result);
1163                         goto failed;
1164                 }
1165 
1166                 /* Set the port to its prior type and enable (if necessary) */
1167                 if (hw->presniff_port_type != 0) {
1168                         word = hw->presniff_port_type;
1169                         result = hfa384x_drvr_setconfig16(hw,
1170                                                   HFA384x_RID_CNFPORTTYPE,
1171                                                   word);
1172                         if (result) {
1173                                 netdev_dbg
1174                                     (wlandev->netdev,
1175                                      "failed to restore porttype, result=%d\n",
1176                                      result);
1177                                 goto failed;
1178                         }
1179 
1180                         /* Enable the port */
1181                         result = hfa384x_drvr_enable(hw, 0);
1182                         if (result) {
1183                                 netdev_dbg(wlandev->netdev,
1184                                            "failed to enable port to presniff setting, result=%d\n",
1185                                            result);
1186                                 goto failed;
1187                         }
1188                 } else {
1189                         result = hfa384x_drvr_disable(hw, 0);
1190                 }
1191 
1192                 netdev_info(wlandev->netdev, "monitor mode disabled\n");
1193                 msg->resultcode.data = P80211ENUM_resultcode_success;
1194                 return 0;
1195         case P80211ENUM_truth_true:
1196                 /* Disable the port (if enabled), only check Port 0 */
1197                 if (hw->port_enabled[0]) {
1198                         if (wlandev->netdev->type == ARPHRD_ETHER) {
1199                                 /* Save macport 0 state */
1200                                 result = hfa384x_drvr_getconfig16(hw,
1201                                                   HFA384x_RID_CNFPORTTYPE,
1202                                                   &hw->presniff_port_type);
1203                                 if (result) {
1204                                         netdev_dbg
1205                                         (wlandev->netdev,
1206                                              "failed to read porttype, result=%d\n",
1207                                              result);
1208                                         goto failed;
1209                                 }
1210                                 /* Save the wepflags state */
1211                                 result = hfa384x_drvr_getconfig16(hw,
1212                                                   HFA384x_RID_CNFWEPFLAGS,
1213                                                   &hw->presniff_wepflags);
1214                                 if (result) {
1215                                         netdev_dbg
1216                                         (wlandev->netdev,
1217                                              "failed to read wepflags, result=%d\n",
1218                                              result);
1219                                         goto failed;
1220                                 }
1221                                 hfa384x_drvr_stop(hw);
1222                                 result = hfa384x_drvr_start(hw);
1223                                 if (result) {
1224                                         netdev_dbg(wlandev->netdev,
1225                                                    "failed to restart the card for sniffing, result=%d\n",
1226                                                    result);
1227                                         goto failed;
1228                                 }
1229                         } else {
1230                                 /* Disable the port */
1231                                 result = hfa384x_drvr_disable(hw, 0);
1232                                 if (result) {
1233                                         netdev_dbg(wlandev->netdev,
1234                                                    "failed to enable port for sniffing, result=%d\n",
1235                                                    result);
1236                                         goto failed;
1237                                 }
1238                         }
1239                 } else {
1240                         hw->presniff_port_type = 0;
1241                 }
1242 
1243                 /* Set the channel we wish to sniff  */
1244                 word = msg->channel.data;
1245                 result = hfa384x_drvr_setconfig16(hw,
1246                                                   HFA384x_RID_CNFOWNCHANNEL,
1247                                                   word);
1248                 hw->sniff_channel = word;
1249 
1250                 if (result) {
1251                         netdev_dbg(wlandev->netdev,
1252                                    "failed to set channel %d, result=%d\n",
1253                                    word, result);
1254                         goto failed;
1255                 }
1256 
1257                 /* Now if we're already sniffing, we can skip the rest */
1258                 if (wlandev->netdev->type != ARPHRD_ETHER) {
1259                         /* Set the port type to pIbss */
1260                         word = HFA384x_PORTTYPE_PSUEDOIBSS;
1261                         result = hfa384x_drvr_setconfig16(hw,
1262                                                   HFA384x_RID_CNFPORTTYPE,
1263                                                   word);
1264                         if (result) {
1265                                 netdev_dbg
1266                                     (wlandev->netdev,
1267                                      "failed to set porttype %d, result=%d\n",
1268                                      word, result);
1269                                 goto failed;
1270                         }
1271                         if ((msg->keepwepflags.status ==
1272                              P80211ENUM_msgitem_status_data_ok) &&
1273                             (msg->keepwepflags.data != P80211ENUM_truth_true)) {
1274                                 /* Set the wepflags for no decryption */
1275                                 word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
1276                                     HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
1277                                 result =
1278                                     hfa384x_drvr_setconfig16(hw,
1279                                                      HFA384x_RID_CNFWEPFLAGS,
1280                                                      word);
1281                         }
1282 
1283                         if (result) {
1284                                 netdev_dbg
1285                                   (wlandev->netdev,
1286                                    "failed to set wepflags=0x%04x, result=%d\n",
1287                                    word, result);
1288                                 goto failed;
1289                         }
1290                 }
1291 
1292                 /* Do we want to strip the FCS in monitor mode? */
1293                 if ((msg->stripfcs.status ==
1294                      P80211ENUM_msgitem_status_data_ok) &&
1295                     (msg->stripfcs.data == P80211ENUM_truth_true)) {
1296                         hw->sniff_fcs = 0;
1297                 } else {
1298                         hw->sniff_fcs = 1;
1299                 }
1300 
1301                 /* Do we want to truncate the packets? */
1302                 if (msg->packet_trunc.status ==
1303                     P80211ENUM_msgitem_status_data_ok) {
1304                         hw->sniff_truncate = msg->packet_trunc.data;
1305                 } else {
1306                         hw->sniff_truncate = 0;
1307                 }
1308 
1309                 /* Enable the port */
1310                 result = hfa384x_drvr_enable(hw, 0);
1311                 if (result) {
1312                         netdev_dbg
1313                             (wlandev->netdev,
1314                              "failed to enable port for sniffing, result=%d\n",
1315                              result);
1316                         goto failed;
1317                 }
1318                 /* Enable monitor mode */
1319                 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
1320                 if (result) {
1321                         netdev_dbg(wlandev->netdev,
1322                                    "failed to enable monitor mode, result=%d\n",
1323                                    result);
1324                         goto failed;
1325                 }
1326 
1327                 if (wlandev->netdev->type == ARPHRD_ETHER)
1328                         netdev_info(wlandev->netdev, "monitor mode enabled\n");
1329 
1330                 /* Set the driver state */
1331                 /* Do we want the prism2 header? */
1332                 if ((msg->prismheader.status ==
1333                      P80211ENUM_msgitem_status_data_ok) &&
1334                     (msg->prismheader.data == P80211ENUM_truth_true)) {
1335                         hw->sniffhdr = 0;
1336                         wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1337                 } else if ((msg->wlanheader.status ==
1338                             P80211ENUM_msgitem_status_data_ok) &&
1339                            (msg->wlanheader.data == P80211ENUM_truth_true)) {
1340                         hw->sniffhdr = 1;
1341                         wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1342                 } else {
1343                         wlandev->netdev->type = ARPHRD_IEEE80211;
1344                 }
1345 
1346                 msg->resultcode.data = P80211ENUM_resultcode_success;
1347                 return 0;
1348         default:
1349                 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
1350                 return 0;
1351         }
1352 
1353 failed:
1354         msg->resultcode.data = P80211ENUM_resultcode_refused;
1355         return 0;
1356 }

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