?? ar6000_drv.c
字號:
/* * Copyright (c) 2004-2006 Atheros Communications Inc. * * Wireless Network driver for Atheros AR6001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * 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. * * *//* * This driver is a pseudo ethernet driver to access the Atheros AR6000 * WLAN Device */static const char athId[] __attribute__ ((unused)) = "$Id: //depot/sw/releases/etnaGPL1.1/host/os/linux/ar6000_drv.c#2 $";#include <linux/module.h>#include <linux/config.h>#include <linux/version.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/spinlock.h>#include <linux/skbuff.h>#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <net/iw_handler.h>#include <linux/if_arp.h>#include <linux/ip.h>#include <linux/rtnetlink.h>#include <linux/netdevice.h>#include <asm/semaphore.h>#include <linux/wireless.h>#include "../include/athdefs.h"#include "../include/athtypes.h"#include "../include/osapi.h"#include "../include/htc.h"#include "../include/wmi.h"#include "../include/athdrv.h"#include "ar6000_drv.h"#include "../include/bmi.h"#include "../include/ieee80211.h"#include "../include/ieee80211_ioctl.h"#include "../include/wlan_api.h"#include "../include/wmi_api.h"#include "../include/dset_api.h"#include "../include/app/dset.h"#include "../include/gpio_api.h"#include "../include/AR6000_gpio.h"#include "../include/host_version.h"#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)#include <asm/uaccess.h>#include <linux/rtnetlink.h>#endif#include "../include/hw/mbox_host_reg.h"#include "../include/hw/mc_reg.h"#include "../include/hw/mbox_reg.h"#include "../include/hw/rtc_reg.h"MODULE_LICENSE("Dual BSD/GPL");#if defined (SPI)#define CONTROL_PADCONF_AA12 0x00E8unsigned int awake_gpio = 17;unsigned int awake_gpio_pad_conf_offset = CONTROL_PADCONF_AA12;unsigned int awake_gpio_pad_conf_byte = 1;unsigned int awake_gpio_pad_mode_value = 0x3;#endifint bmienable = 0;unsigned int bypasswmi = 0;unsigned int debuglevel = 0;int tspecCompliance = CCX_V4_COMPLIANCE;unsigned int busspeedlow = 0;unsigned int onebitmode = 0;unsigned int skipflash = 0;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)module_param(bmienable, int, 0644);module_param(bypasswmi, int, 0644);module_param(debuglevel, int, 0644);module_param(tspecCompliance, int, 0644);module_param(onebitmode, int, 0644);module_param(busspeedlow, int, 0644);module_param(skipflash, int, 0644);#else#define __user/* for linux 2.4 and lower */MODULE_PARM(bmienable,"i");MODULE_PARM(bypasswmi,"i");MODULE_PARM(debuglevel, "i");MODULE_PARM(onebitmode,"i");MODULE_PARM(busspeedlow, "i");MODULE_PARM(skipflash, "i");#if defined SPIMODULE_PARM(awake_gpio, "i");MODULE_PARM_DESC(awake_gpio, "Awake GPIO pin");MODULE_PARM(awake_gpio_pad_conf_offset, "i");MODULE_PARM_DESC(awake_gpio_pad_conf_offset, "Awake GPIO pin pad config offset");MODULE_PARM(awake_gpio_pad_conf_byte, "i");MODULE_PARM_DESC(awake_gpio_pad_conf_byte, "Awake GPIO pin pad byte number");MODULE_PARM(awake_gpio_pad_mode_value, "i");MODULE_PARM_DESC(awake_gpio_pad_mode_value, "Awake GPIO pin mode value");#endif#endif#define MAX_ALLOWED_TXQ_DEPTH (HTC_DATA_REQUEST_RING_BUFFER_SIZE - 2)static int txFlowCtrlThresh[HTC_MAILBOX_NUM_MAX] = {0 * (MAX_ALLOWED_TXQ_DEPTH - 1), 1 * (MAX_ALLOWED_TXQ_DEPTH - 1), 2 * (MAX_ALLOWED_TXQ_DEPTH - 1), 3 * (MAX_ALLOWED_TXQ_DEPTH - 1)};#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)/* in 2.6.10 and later this is now a pointer to a uint */unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;#define mboxnum &_mboxnum#elseunsigned int mboxnum = HTC_MAILBOX_NUM_MAX;#endif#ifdef DEBUGint debugdriver = 1;unsigned int debughtc = 128;unsigned int debugbmi = 1;unsigned int debughif = 1;unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)module_param(debugdriver, int, 0644);module_param(debughtc, int, 0644);module_param(debugbmi, int, 0644);module_param(debughif, int, 0644);module_param_array(txcreditsavailable, int, mboxnum, 0644);module_param_array(txcreditsconsumed, int, mboxnum, 0644);module_param_array(txcreditintrenable, int, mboxnum, 0644);module_param_array(txcreditintrenableaggregate, int, mboxnum, 0644);#else/* linux 2.4 and lower */MODULE_PARM(debugdriver, "i");MODULE_PARM(debughtc, "i");MODULE_PARM(debugbmi, "i");MODULE_PARM(debughif, "i");MODULE_PARM(txcreditsavailable, "0-3i");MODULE_PARM(txcreditsconsumed, "0-3i");MODULE_PARM(txcreditintrenable, "0-3i");MODULE_PARM(txcreditintrenableaggregate, "0-3i");#endif#endif /* DEBUG */unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)module_param_array(tx_attempt, int, mboxnum, 0644);module_param_array(tx_post, int, mboxnum, 0644);module_param_array(tx_complete, int, mboxnum, 0644);#elseMODULE_PARM(tx_attempt, "0-3i");MODULE_PARM(tx_post, "0-3i");MODULE_PARM(tx_complete, "0-3i");#endif#ifdef BLOCK_TX_PATH_FLAGint blocktx = 0;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)module_param(blocktx, int, 0644);#elseMODULE_PARM(blocktx, "i");#endif#endif /* BLOCK_TX_PATH_FLAG */#ifdef DEBUG#define AR_DEBUG_PRINTF(args...) if (debugdriver) printk(args);#define AR_DEBUG2_PRINTF(args...) if (debugdriver >= 2) printk(args);#else#define AR_DEBUG_PRINTF(args...)#define AR_DEBUG2_PRINTF(args...)#endif/* Function declarations */static int ar6000_init_module(void);static void ar6000_cleanup_module(void);static int ar6000_init(struct net_device *dev);static int ar6000_open(struct net_device *dev);static int ar6000_close(struct net_device *dev);static void ar6000_init_control_info(AR_SOFTC_T *ar);static void ar6000_init_profile_info(AR_SOFTC_T *ar);static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);static int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static void ar6000_destroy(struct net_device *dev);static struct net_device_stats *ar6000_get_stats(struct net_device *dev);static struct iw_statistics * ar6000_get_iwstats(struct net_device *dev);static void ar6000_ioctl_iwsetup(struct iw_handler_def *def);static int ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_link_threshold(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq);static int ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata);static int ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata);static int ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata);static int ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata);static int ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq);#ifdef HTC_RAW_INTERFACEstatic void ar6000_htc_raw_read_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_htc_raw_unread_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_htc_raw_write_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg);static int ar6000_htc_raw_open(HTC_TARGET *htcTarget);static int ar6000_htc_raw_close(HTC_TARGET *htcTarget);static ssize_t ar6000_htc_raw_read(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, char __user *buffer, size_t count);static ssize_t ar6000_htc_raw_write(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, char __user *buffer, size_t count);#endif /* HTC_RAW_INTERFACE */static void ar6000_install_static_wep_keys(AR_SOFTC_T *ar);static int ar6000_ioctl_addpmkid(struct net_device *dev, struct iw_request_info *info, void *w, char *extra);#if CONFIG_HOST_DSET_SUPPORTstatic void ar6000_dset_init(void);static int ar6000_ioctl_wait_dset_req(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_dset_open_reply(struct net_device *dev, struct ifreq *rq);static int ar6000_ioctl_dset_data_reply(struct net_device *dev, struct ifreq *rq);#endif /* CONFIG_HOST_DSET_SUPPORT */#if CONFIG_HOST_GPIO_SUPPORTstatic void ar6000_gpio_init(void);A_STATUS ar6000_gpio_output_set(struct net_device *dev, A_UINT32 set_mask, A_UINT32 clear_mask, A_UINT32 enable_mask, A_UINT32 disable_mask);static A_STATUS ar6000_gpio_input_get(struct net_device *dev);static A_STATUS ar6000_gpio_register_set(struct net_device *dev, A_UINT32 gpioreg_id, A_UINT32 value);static A_STATUS ar6000_gpio_register_get(struct net_device *dev, A_UINT32 gpioreg_id);static A_STATUS ar6000_gpio_intr_ack(struct net_device *dev, A_UINT32 ack_mask);#endif /* CONFIG_HOST_GPIO_SUPPORT *//* * HTC event handlers */static void ar6000_avail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_unavail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_rx(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_rx_refill(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);static void ar6000_tx_complete(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);/* * Static variables */static struct net_device *ar6000_devices[MAX_AR6000];static struct iw_handler_def ath_iw_handler_def;static DECLARE_WAIT_QUEUE_HEAD(arEvent);static A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};static A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};#if CONFIG_HOST_GPIO_SUPPORTstruct ar6000_gpio_intr_wait_cmd_s gpio_intr_results;/* gpio_reg_results and gpio_data_available are protected by arSem */static struct ar6000_gpio_register_cmd_s gpio_reg_results;static A_BOOL gpio_data_available; /* Requested GPIO data available */static A_BOOL gpio_intr_available; /* GPIO interrupt info available */static A_BOOL gpio_ack_received; /* GPIO ack was received */#endif /* CONFIG_HOST_GPIO_SUPPORT *//* * adhoc PS support */static void ar6000_cookie_init(AR_SOFTC_T *ar);static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];static int __initar6000_init_module(void){ static int probed = 0; A_STATUS status; if (probed) { return -ENODEV; } probed++;#if CONFIG_HOST_DSET_SUPPORT ar6000_dset_init();#endif /* CONFIG_HOST_DSET_SUPPORT */#if CONFIG_HOST_GPIO_SUPPORT ar6000_gpio_init();#endif /* CONFIG_HOST_GPIO_SUPPORT */ status = HTCInit(); if(status != A_OK) return -ENODEV; HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE, ar6000_avail_ev, NULL); HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_UNAVAILABLE, ar6000_unavail_ev, NULL); return 0;}static void __exitar6000_cleanup_module(void){ int i = 0; struct net_device *ar6000_netdev; for (i=0; i < MAX_AR6000; i++) { if (ar6000_devices[i] != NULL) { ar6000_netdev = ar6000_devices[i]; ar6000_devices[i] = NULL; ar6000_destroy(ar6000_netdev); } } /* This will unregister with the SDIO bus driver */ HTCShutDown(NULL); AR_DEBUG_PRINTF("ar6000_cleanup: success\n");}/* * Write to the AR6000 through its diagnostic window. * No cooperation from the Target is required for this. */A_STATUSar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data){ HIF_REQUEST request; A_STATUS status; HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -