📄 prism2mgmt.c
字号:
/* src/prism2/driver/prism2mgmt.c** Management request handler functions.** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.* --------------------------------------------------------------------** linux-wlan** The contents of this file are subject to the Mozilla Public* License Version 1.1 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.mozilla.org/MPL/** Software distributed under the License is distributed on an "AS* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** Alternatively, the contents of this file may be used under the* terms of the GNU Public License version 2 (the "GPL"), in which* case the provisions of the GPL are applicable instead of the* above. If you wish to allow the use of your version of this file* only under the terms of the GPL and not to allow others to use* your version of this file under the MPL, indicate your decision* by deleting the provisions above and replace them with the notice* and other provisions required by the GPL. If you do not delete* the provisions above, a recipient may use your version of this* file under either the MPL or the GPL.** --------------------------------------------------------------------** Inquiries regarding the linux-wlan Open Source project can be* made directly to:** AbsoluteValue Systems Inc.* info@linux-wlan.com* http://www.linux-wlan.com** --------------------------------------------------------------------** Portions of the development of this software were funded by * Intersil Corporation as part of PRISM(R) chipset product development.** --------------------------------------------------------------------** The functions in this file handle management requests sent from* user mode.** Most of these functions have two separate blocks of code that are* conditional on whether this is a station or an AP. This is used* to separate out the STA and AP responses to these management primitives.* It's a choice (good, bad, indifferent?) to have the code in the same * place so it's clear that the same primitive is implemented in both * cases but has different behavior.** --------------------------------------------------------------------*//*================================================================*//* System Includes */#define WLAN_DBVAR prism2_debug#include <wlan/version.h>#include <linux/config.h>#include <linux/version.h>#include <linux/if_arp.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/wait.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/slab.h>#include <linux/wireless.h>#include <linux/netdevice.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/byteorder.h>#include <linux/random.h>#if (WLAN_HOSTIF == WLAN_USB)#include <linux/usb.h>#endif#if (WLAN_HOSTIF == WLAN_PCMCIA)#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#include <pcmcia/cisreg.h>#endif#include <wlan/wlan_compat.h>/*================================================================*//* Project Includes */#include <wlan/p80211types.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/p80211conv.h>#include <wlan/p80211msg.h>#include <wlan/p80211netdev.h>#include <wlan/p80211metadef.h>#include <wlan/p80211metastruct.h>#include <prism2/hfa384x.h>#include <prism2/prism2mgmt.h>/*================================================================*//* Local Constants *//*================================================================*//* Local Macros *//* Converts 802.11 format rate specifications to prism2 */#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \ (((n)&~BIT7) == 4) ? BIT1 : \ (((n)&~BIT7) == 11) ? BIT2 : \ (((n)&~BIT7) == 22) ? BIT3 : 0)/*================================================================*//* Local Types *//*================================================================*//* Local Static Definitions *//*================================================================*//* Local Function Declarations *//*================================================================*//* Function Definitions *//*----------------------------------------------------------------* prism2mgmt_powermgmt** Set the power management state of this station's MAC.** Arguments:* wlandev wlan device structure* msgp ptr to msg buffer** Returns: * 0 success and done* <0 success, but we're waiting for something to finish.* >0 an error occurred while handling the message.* Side effects:** Call context:* process thread (usually)* interrupt----------------------------------------------------------------*/int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp){ int result = 0; hfa384x_t *hw = wlandev->priv; p80211msg_dot11req_powermgmt_t *msg = msgp; DBFENTER; if (!hw->ap) { /*** STATION ***/ /* * Set CNFPMENABLED (on or off) * Set CNFMULTICASTRX (if PM on, otherwise clear) * Spout a notice stating that SleepDuration and * HoldoverDuration and PMEPS also have an impact. */ /* Powermgmt is currently unsupported for STA */ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; msg->resultcode.data = P80211ENUM_resultcode_not_supported; } else { /*** ACCESS POINT ***/ /* Powermgmt is never supported for AP */ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; msg->resultcode.data = P80211ENUM_resultcode_not_supported; } DBFEXIT; return result;}/*----------------------------------------------------------------* prism2mgmt_scan** Initiate a scan for BSSs.** This function corresponds to MLME-scan.request and part of * MLME-scan.confirm. As far as I can tell in the standard, there* are no restrictions on when a scan.request may be issued. We have* to handle in whatever state the driver/MAC happen to be.** Arguments:* wlandev wlan device structure* msgp ptr to msg buffer** Returns: * 0 success and done* <0 success, but we're waiting for something to finish.* >0 an error occurred while handling the message.* Side effects:** Call context:* process thread (usually)* interrupt----------------------------------------------------------------*/int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp){ int result = 0; hfa384x_t *hw = wlandev->priv; p80211msg_dot11req_scan_t *msg = msgp; UINT16 roamingmode, word; int i, timeout; int istmpenable = 0; hfa384x_HostScanRequest_data_t scanreq; DBFENTER; if (hw->ap) { WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n"); result = 1; msg->resultcode.data = P80211ENUM_resultcode_not_supported; goto exit; } /* gatekeeper check */ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, hw->ident_sta_fw.minor, hw->ident_sta_fw.variant) < HFA384x_FIRMWARE_VERSION(1,3,2)) { WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n"); result = 1; msg->resultcode.data = P80211ENUM_resultcode_not_supported; goto exit; } memset(&scanreq, 0, sizeof(scanreq)); /* save current roaming mode */ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFROAMINGMODE, &roamingmode); if ( result ) { WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* drop into mode 3 for the scan */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if ( result ) { WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* active or passive? */ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, hw->ident_sta_fw.minor, hw->ident_sta_fw.variant) > HFA384x_FIRMWARE_VERSION(1,5,0)) { if (msg->scantype.data != P80211ENUM_scantype_active) { word = host2hfa384x_16(msg->maxchanneltime.data); } else { word = 0; } result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word); if ( result ) { WLAN_LOG_WARNING("Passive scan not supported with " "current firmware. (<1.5.1)\n"); } } /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ word = HFA384x_RATEBIT_2; scanreq.txRate = host2hfa384x_16(word); /* set up the channel list */ word = 0; for (i = 0; i < msg->channellist.data.len; i++) { UINT8 channel = msg->channellist.data.data[i]; if (channel > 14) continue; /* channel 1 is BIT0 ... channel 14 is BIT13 */ word |= (1 << (channel-1)); } scanreq.channelList = host2hfa384x_16(word); /* set up the ssid, if present. */ scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len); memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); /* Enable the MAC port if it's not already enabled */ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); if ( result ) { WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. " "result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } if (word == HFA384x_PORTSTATUS_DISABLED) { UINT16 wordbuf[17]; result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if ( result ) { WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* Construct a bogus SSID and assign it to OwnSSID and * DesiredSSID */ wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN); get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, wordbuf, HFA384x_RID_CNFOWNSSID_LEN); if ( result ) { WLAN_LOG_ERROR("Failed to set OwnSSID.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID, wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN); if ( result ) { WLAN_LOG_ERROR("Failed to set DesiredSSID.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* bsstype */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, HFA384x_PORTTYPE_IBSS); if ( result ) { WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* ibss options */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, HFA384x_CREATEIBSS_JOINCREATEIBSS); if ( result ) { WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = hfa384x_drvr_enable(hw, 0); if ( result ) { WLAN_LOG_ERROR("drvr_enable(0) failed. " "result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } istmpenable = 1; } /* Figure out our timeout first Kus, then HZ */ timeout = msg->channellist.data.len * msg->maxchanneltime.data; timeout = (timeout * HZ)/1000; /* Issue the scan request */ hw->scanflag = 0; WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq)); result = hfa384x_drvr_setconfig( hw, HFA384x_RID_HOSTSCAN, &scanreq, sizeof(hfa384x_HostScanRequest_data_t)); if ( result ) { WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* sleep until info frame arrives */ wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); msg->numbss.status = P80211ENUM_msgitem_status_data_ok; if (hw->scanflag == -1) hw->scanflag = 0; msg->numbss.data = hw->scanflag; hw->scanflag = 0; /* Disable port if we temporarily enabled it. */ if (istmpenable) { result = hfa384x_drvr_disable(hw, 0); if ( result ) { WLAN_LOG_ERROR("drvr_disable(0) failed. " "result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } } /* restore original roaming mode */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, roamingmode); if ( result ) { WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = 0; msg->resultcode.data = P80211ENUM_resultcode_success; exit: msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; DBFEXIT; return result;}/*----------------------------------------------------------------* prism2mgmt_scan_results** Retrieve the BSS description for one of the BSSs identified in* a scan.** Arguments:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -