📄 zd1205.c
字号:
/* src/zd1205.c
*
*
*
* Copyright (C) 2004 ZyDAS Inc. All Rights Reserved.
* --------------------------------------------------------------------
*
*
*
* 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.
*
* -------------------------------------------------------------------- */
#define __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <net/checksum.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include "zd1205.h"
#include "zdinlinef.h"
#include "zddebug.h"
#include "zddebug2.h"
#include "menu_drv_macro.h"
#include "zdhw.h"
#include "zdsorts.h"
#include "zdglobal.h"
#include "zdutils.h"
#include "zdmisc.h"
#include "zdhci.h"
#ifdef HOST_IF_USB
#include "zd1211.h"
#endif
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
#endif
#if ZDCONF_LP_SUPPORT == 1
#include "zdlpmgt.h"
#include "zdturbo_burst.h"
#endif
#if ZDPRODUCTIOCTL
#include "zdreq.h"
#endif
extern U16 mTmRetryConnect;
extern BOOLEAN mProbeWithSsid;
extern u8 mMacMode;
extern U8 mBssType;
extern Element mSsid;
extern Element dot11DesiredSsid;
int errno;
extern u8 mCurrConnUser;
extern U8 mNumBOnlySta;
extern u8 mBssNum;
extern U8 mKeyFormat; //Init value: WEP64_USED(1)
extern BOOLEAN mPrivacyInvoked; // Init value: FALSE
extern U8 mKeyVector[4][16]; // Store WEP key
extern U8 mWepKeyLen;
extern U8 mKeyId; // Init value: 0
extern U16 mCap; // Init value: CAP_ESS(1);
extern u16 CurrScanCH;
extern MacAddr_t dot11MacAddress;
extern BOOLEAN zd_CmdProbeReq(U8 bWithSSID);
extern Hash_t *HashSearch(MacAddr_t *pMac);
extern void re_initFdescBuf(void);
/******************************************************************************
* C O N S T A N T S
*******************************************************************************
*/
static u8 ZD_SNAP_HEADER[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
static u8 ZD_SNAP_BRIDGE_TUNNEL[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
static u8 zd_Snap_Apple_Type[] = {0xAA,0xAA,0x03,0x08,0x00,0x07,0x80,0x9b};
//Slow Pairwise key install issue is casued by a too fast response 1/2
//group key update before PTK is installed. The gorup update is discarded
//caused key update fails.
//<Slow Pairwise Key Install Fix>
static u8 ZD_SNAP_EAPOL[] = {0xAA,0xAA,0xAA,0x03, 0x00,0x00,0x00, 0x88,0x8E};
//</Slow Pairwise Key Install Fix>
static u16 IPX=0x8137;
//static u16 NOVELL=0xe0e0;
static u16 APPLE_TALK=0x80f3;
static u16 EAPOL=0x888e;
#define MAX_MULTICAST_ADDRS 32
#define NUM_WEPKEYS 4
#define bGroup(pWlanHdr) (pWlanHdr->Address1[0] & BIT_0)
#define getSeq(pWlanHdr) (((u16)pWlanHdr->SeqCtrl[1] << 4) + (u16)((pWlanHdr->SeqCtrl[0] & 0xF0) >> 4))
#define getFrag(pWlanHdr) (pWlanHdr->SeqCtrl[0] & 0x0F)
#define getTA(pWlanHdr) (&pWlanHdr->Address2[0])
#define isWDS(pWlanHdr) (((pWlanHdr->FrameCtrl[1] & TO_DS_FROM_DS) == TO_DS_FROM_DS) ? 1 : 0)
#define bRetryBit(pWlanHdr) (pWlanHdr->FrameCtrl[1] & RETRY_BIT)
#define bWepBit(pWlanHdr) (pWlanHdr->FrameCtrl[1] & ENCRY_BIT)
#define bMoreFrag(pWlanHdr) (pWlanHdr->FrameCtrl[1] & MORE_FRAG)
#define bMoreData(pWlanHdr) (pWlanHdr->FrameCtrl[1] & MORE_DATA)
#define BaseFrameType(pWlanHdr) (pWlanHdr->FrameCtrl[0] & 0x0C)
#define SubFrameType(pWlanHdr) (pWlanHdr->FrameCtrl[0])
#define bDataMgtFrame(pWlanHdr) (((pWlanHdr->FrameCtrl[0] & 0x04) == 0))
#ifndef HOST_IF_USB
#define nowT() (zd_readl(TSF_LowPart)) //us unit
#else
#define nowT() (jiffies) //tick (10ms) unit
#endif
/******************************************************************************
* F U N C T I O N D E C L A R A T I O N S
*******************************************************************************
*/
#ifdef CONFIG_PROC_FS
extern int zd1205_create_proc_subdir(struct zd1205_private *);
extern void zd1205_remove_proc_subdir(struct zd1205_private *);
#else
#define zd1205_create_proc_subdir(X) 0
#define zd1205_remove_proc_subdir(X) do {} while(0)
#endif
static u32 channel_11A_to_Freq(const u32 channel);
//static u32 Freq_11A_to_channel(const u32 freq);
static unsigned char zd1205_alloc_space(struct zd1205_private *);
unsigned char zd1205_init(struct zd1205_private *);
static void zd1205_setup_tcb_pool(struct zd1205_private *macp);
static void zd1205_config(struct zd1205_private *macp);
static void zd1205_rd_eaddr(struct zd1205_private *);
int zd1205_open(struct net_device *);
int zd1205_close(struct net_device *);
int zd1205_change_mtu(struct net_device *, int);
int zd1205_set_mac(struct net_device *, void *);
void zd1205_set_multi(struct net_device *);
struct net_device_stats *zd1205_get_stats(struct net_device *);
static int zd1205_alloc_tcb_pool(struct zd1205_private *);
static void zd1205_free_tcb_pool(struct zd1205_private *);
static int zd1205_alloc_rfd_pool(struct zd1205_private *);
static void zd1205_free_rfd_pool(struct zd1205_private *);
static void zd1205_clear_pools(struct zd1205_private *macp);
zd1205_SwTcb_t * zd1205_first_txq(struct zd1205_private *macp, zd1205_SwTcbQ_t *Q);
void zd1205_qlast_txq(struct zd1205_private *macp, zd1205_SwTcbQ_t *Q, zd1205_SwTcb_t *signal);
static void zd1205_init_txq(struct zd1205_private *macp, zd1205_SwTcbQ_t *Q);
#ifndef HOST_IF_USB
static u8 zd1205_pci_setup(struct pci_dev *, struct zd1205_private *);
static void zd1205_intr(int, void *, struct pt_regs *);
static void zd1205_retry_failed(struct zd1205_private *);
static void zd1205_dtim_notify(struct zd1205_private *);
void zd1205_start_ru(struct zd1205_private *);
u8 zd1205_RateAdaption(u16 aid, u8 CurrentRate, u8 gear);
#else
struct rx_list_elem *zd1205_start_ru(struct zd1205_private *);
#endif
u32 zd1205_rx_isr(struct zd1205_private *macp);
void zd1205_tx_isr(struct zd1205_private *);
static void zd1205_transmit_cleanup(struct zd1205_private *, zd1205_SwTcb_t *sw_tcb);
static int zd1205_validate_frame(struct zd1205_private *macp, zd1205_RFD_t *rfd);
int zd1205_xmit_frame(struct sk_buff *, struct net_device *);
static void zd1205_dealloc_space(struct zd1205_private *macp);
void zd1205_disable_int(void);
void zd1205_enable_int(void);
void zd1205_config_wep_keys(struct zd1205_private *macp);
void HKeepingCB(struct net_device *dev);
void zd1205_mgt_mon_cb(struct net_device *dev);
void zd1205_lp_poll_cb(struct net_device *dev);
void zd1205_process_wakeup(struct zd1205_private *macp);
void zd1205_device_reset(struct zd1205_private *macp);
int zd1205_DestPowerSave(struct zd1205_private *macp, u8 *pDestAddr);
void zd1205_recycle_rx(struct zd1205_private *macp);
//for 1211
u8 CalculateStrength(struct zd1205_private *macp, zd1205_RFD_t *rfd);
u8 CalculateQuality(struct zd1205_private *macp, zd1205_RFD_t *rfd, u8 *pQualityIndB);
void zd1205_initCAM(struct zd1205_private *macp);
int zd1205_CheckOverlapBss(struct zd1205_private *macp, plcp_wla_Header_t *pWlanHdr, u8 *pMacBody, u32 bodyLen);
void zd1205_HandleQosRequest(struct zd1205_private *macp);
void zd1205_SetRatesInfo(struct zd1205_private *macp);
u8 X_To_dB(u32 X, u8 rate);
u16 ZDLog10multiply100(int data);
void zd1205_connect_mon(struct zd1205_private *macp);
//wireless extension helper functions
void zd1205_lock(struct zd1205_private *macp);
void zd1205_unlock(struct zd1205_private *macp);
static int zd1205_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq, char* key);
static int zd1205_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq, char* key);
static int zd1205_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
static int zd1205_ioctl_setbssid(struct net_device *dev, struct iwreq *wrq);
static int zd1205_ioctl_getessid(struct net_device *dev, struct iw_point *erq);
static int zd1205_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq);
//static int zd1205_ioctl_setsens(struct net_device *dev, struct iw_param *srq);
static int zd1205_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
static int zd1205_ioctl_setfrag(struct net_device *dev, struct iw_param *frq);
static int zd1205_ioctl_getfrag(struct net_device *dev, struct iw_param *frq);
static int zd1205_ioctl_setrate(struct net_device *dev, struct iw_param *frq);
static int zd1205_ioctl_getrate(struct net_device *dev, struct iw_param *frq);
//static int zd1205_ioctl_settxpower(struct net_device *dev, struct iw_param *prq);
//static int zd1205_ioctl_gettxpower(struct net_device *dev, struct iw_param *prq);
static int zd1205_ioctl_setpower(struct net_device *dev, struct iw_param *prq);
static int zd1205_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
static int zd1205_ioctl_setmode(struct net_device *dev, __u32 *mode);
/* Wireless Extension Handler functions */
static int zd1205wext_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra);
static int zd1205wext_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra);
static int zd1205wext_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra);
static int zd1205wext_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra);
static int zd1205wext_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra);
static int zd1205wext_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *frag, char *extra);
//static int zd1205wext_giwtxpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra);
//static int zd1205wext_siwtxpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra);
static int zd1205wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra);
#if WIRELESS_EXT > 13
static int zd1205wext_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra);
static int zd1205wext_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra);
#endif
/* functions to support 802.11 protocol stack */
void zdcb_rx_ind(U8 *pData, U32 length, void *buf, U32 LP_MAP);
void zdcb_release_buffer(void *buf);
void zdcb_tx_completed(void);
void zdcb_start_timer(U32 timeout, U32 event);
void zdcb_stop_timer(U32 TimerId);
void zd1205_set_zd_cbs(zd_80211Obj_t *pObj);
void zdcb_set_reg(void *reg, U32 offset, U32 value);
void chal_tout_cb(unsigned long ptr);
U32 zdcb_dis_intr(void);
void zdcb_set_intr_mask(U32 flags);
BOOLEAN zdcb_check_tcb_avail(U8 num_of_frag);
BOOLEAN zdcb_setup_next_send(fragInfo_t *frag_info);
//void zd_CmdScanReq(u16 channel);
//void zd_ScanBegin();
//void zd_ScanEnd();
U16 zdcb_status_notify(U16 status, U8 *StaAddr);
U32 zdcb_vir_to_phy_addr(U32 virtAddr);
U32 zdcb_get_reg(void *reg, U32 offset);
void zdcb_delay_us(U32 ustime);
int zdcb_Rand(U32 seed);
/* For WPA supported functions */
void zd1205_notify_join_event(struct zd1205_private *macp);
void zd1205_notify_disjoin_event(struct zd1205_private *macp);
void zd1205_notify_scan_done(struct zd1205_private *macp);
BOOLEAN zd_CmdProbeReq(U8 ProbeWithSsid);
BssInfo_t *zd1212_bssid_to_BssInfo(U8 *bssid);
void zd_RateAdaption(void);
/******************************************************************************
* P U B L I C D A T A
*******************************************************************************
*/
/* Global Data structures and variables */
#ifndef HOST_IF_USB
char zd1205_copyright[] __devinitdata = "Copyright (c) 2002 Zydas Corporation";
char zd1205_driver_version[]="0.0.1";
const char *zd1205_full_driver_name = "Zydas ZD1205 Network Driver";
char zd1205_short_driver_name[] = "zd1205";
#endif
const char config_filename[] = "/etc/zd1211.conf";
static BOOLEAN CustomMACSet = FALSE;
static u8 CustomMAC[ETH_ALEN];
static BOOLEAN AsocTimerStat = FALSE; //If the Asoc Timer is enabled
extern Hash_t *sstByAid[MAX_RECORD];
zd1205_SwTcbQ_t free_txq_buf, active_txq_buf;
struct net_device *g_dev;
u8 *mTxOFDMType;
zd_80211Obj_t dot11Obj = {0};
#if ZDCONF_LP_SUPPORT == 1
fragInfo_t PollFragInfo;
#endif
#define RX_COPY_BREAK 0//1518 //we do bridge, don't care IP header alignment
#define BEFORE_BEACON 25
/* Definition of Wireless Extension */
/*
* Structures to export the Wireless Handlers
*/
typedef enum _ZD_REGION
{
ZD_REGION_Default = 0x00,//All channel
ZD_REGION_USA = 0x10,//G channel->ch1-11;
ZD_REGION_Canada = 0x20,//G channel->ch1-11;
ZD_REGION_Argentina = 0x21,//G channel->ch1-11;
ZD_REGION_Brazil = 0x22,//G channel->ch1-11;
ZD_REGION_Europe = 0x30,//G channel->ETSI ch1-13;
ZD_REGION_Spain = 0x31,//G channel->ETSI ch1-13;
ZD_REGION_France = 0x32,//G channel->ch10-13;
ZD_REGION_Ukraine = 0x33,//G channel->ch1-11;
ZD_REGION_AustriaBelgium = 0x34,//Austria and Belgium G channel->ch1-13;;
ZD_REGION_Switzerland = 0x35,//G channel->ch1-13;
ZD_REGION_Japan = 0x40,//G channel->ch1-14;
ZD_REGION_Australia = 0x42,//G channel->ch1-13;
ZD_REGION_China = 0x43,//G channel->ch1-11;
ZD_REGION_HongKong = 0x44,//G channel->ch1-11;
ZD_REGION_Korea = 0x45,//G channel->ch1-11;
ZD_REGION_NewZealand = 0x46,//G channel->ch1-11;
ZD_REGION_Singapore = 0x47,//G channel->ch10-13;
ZD_REGION_Taiwan = 0x48,//G channel->ch1-13;
ZD_REGION_Israel = 0x50,//G channel->ch3-9;
ZD_REGION_Mexico = 0x51 //G channel->ch10,11;
} ZD_REGION;
struct iw_priv_args zd1205_private_args[] = {
{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "list_bss" },
{ SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
{ SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_auth" }, /* 0 - open, 1 - shared key */
{ SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_CHAR | 12, "get_auth" },
{ SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble" }, /* 0 - long, 1 - short */
{ SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_CHAR | 6, "get_preamble" },
{ SIOCIWFIRSTPRIV + 0x6, 0, 0, "cnt" },
{ SIOCIWFIRSTPRIV + 0x7, 0, 0, "regs" },
{ SIOCIWFIRSTPRIV + 0x8, 0, 0, "probe" },
// { SIOCIWFIRSTPRIV + 0x9, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dbg_flag" },
{ SIOCIWFIRSTPRIV + 0xA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "connect" },
#if ZDCONF_LP_SUPPORT == 1
{ SIOCIWFIRSTPRIV + 0xF , IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "lp_mode" },
#endif
{ SIOCIWFIRSTPRIV + 0xB, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_mac_mode" },
{ SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" },
// { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" },
// { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" },
// { SIOCIWFIRSTPRIV + 0xF, 0, IW_PRIV_TYPE_CHAR | 14, "get_Region" },
{ SIOCIWFIRSTPRIV + 0x9,IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_Region" },
};
#if WIRELESS_EXT > 12
static iw_handler zd1205wext_handler[] = {
(iw_handler) NULL, /* SIOCSIWCOMMIT */
(iw_handler) NULL, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) NULL, /* SIOCSIWFREQ */
(iw_handler) zd1205wext_giwfreq, /* SIOCGIWFREQ */
(iw_handler) NULL, /* SIOCSIWMODE */
(iw_handler) zd1205wext_giwmode, /* SIOCGIWMODE */
(iw_handler) NULL, /* SIOCSIWSENS */
(iw_handler) NULL, /* SIOCGIWSENS */
(iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */
(iw_handler) zd1205wext_giwrange, /* SIOCGIWRANGE */
(iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */
(iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */
(iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */
(iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */
(iw_handler) NULL, /* SIOCSIWSPY */
(iw_handler) NULL, /* SIOCGIWSPY */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWAP */
(iw_handler) NULL, /* SIOCGIWAP */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCGIWAPLIST */
#if WIRELESS_EXT > 13
(iw_handler) zd1205wext_siwscan, /* SIOCSIWSCAN */
(iw_handler) zd1205wext_giwscan, /* SIOCGIWSCAN */
#else /* WIRELESS_EXT > 13 */
(iw_handler) NULL, /* null */ /* SIOCSIWSCAN */
(iw_handler) NULL, /* null */ /* SIOCGIWSCAN */
#endif /* WIRELESS_EXT > 13 */
(iw_handler) NULL, /* SIOCSIWESSID */
(iw_handler) NULL, /* SIOCGIWESSID */
(iw_handler) NULL, /* SIOCSIWNICKN */
(iw_handler) NULL, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWRATE */
(iw_handler) zd1205wext_giwrate, /* SIOCGIWRATE */
(iw_handler) NULL, /* SIOCSIWRTS */
(iw_handler) zd1205wext_giwrts, /* SIOCGIWRTS */
(iw_handler) NULL, /* SIOCSIWFRAG */
(iw_handler) zd1205wext_giwfrag, /* SIOCGIWFRAG */
(iw_handler) NULL, /* SIOCSIWTXPOW */
(iw_handler) NULL, /* SIOCGIWTXPOW */
(iw_handler) NULL, /* SIOCSIWRETRY */
(iw_handler) NULL, /* SIOCGIWRETRY */
(iw_handler) NULL, /* SIOCSIWENCODE */
(iw_handler) NULL, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
};
static const iw_handler zd1205_private_handler[] =
{
NULL, /* SIOCIWFIRSTPRIV */
};
struct iw_handler_def p80211wext_handler_def = {
num_standard: sizeof(zd1205wext_handler) / sizeof(iw_handler),
num_private: sizeof(zd1205_private_handler)/sizeof(iw_handler),
num_private_args: sizeof(zd1205_private_args)/sizeof(struct iw_priv_args),
standard: zd1205wext_handler,
private: (iw_handler *) zd1205_private_handler,
private_args: (struct iw_priv_args *) zd1205_private_args,
#if WIRELESS_EXT > 18
get_wireless_stats: (struct iw_statistics * )zd1205_iw_getstats
#endif
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -