📄 prism2sta.c
字号:
/* src/prism2/driver/prism2sta.c** Implements the station functionality for prism2** 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.** --------------------------------------------------------------------** This file implements the module and linux pcmcia routines for the* prism2 driver.** --------------------------------------------------------------------*//*================================================================*//* System Includes */#define WLAN_DBVAR prism2_debug#include <wlan/version.h>#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/wireless.h>#include <linux/netdevice.h>#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))#include <linux/tqueue.h>#else#include <linux/workqueue.h>#endif#include <asm/io.h>#include <linux/delay.h>#include <asm/byteorder.h>#include <linux/if_arp.h>#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>#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))#include <linux/ioport.h>#include <linux/pci.h>#endif/*================================================================*//* 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/p80211req.h>#include <wlan/p80211metadef.h>#include <wlan/p80211metastruct.h>#include <prism2/hfa384x.h>#include <prism2/prism2mgmt.h>/*================================================================*//* Local Constants *//*================================================================*//* Local Macros *//*================================================================*//* Local Types *//*================================================================*//* Local Static Definitions */#if (WLAN_HOSTIF == WLAN_PCMCIA)#define DRIVER_SUFFIX "_cs"#elif (WLAN_HOSTIF == WLAN_PLX)#define DRIVER_SUFFIX "_plx"typedef char* dev_info_t;#elif (WLAN_HOSTIF == WLAN_PCI)#define DRIVER_SUFFIX "_pci"typedef char* dev_info_t;#elif (WLAN_HOSTIF == WLAN_USB)#define DRIVER_SUFFIX "_usb"typedef char* dev_info_t;#else#error "HOSTIF unsupported or undefined!"#endifstatic char *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE;static dev_info_t dev_info = "prism2" DRIVER_SUFFIX;/*-----------------------------------------------------------------*/ #if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))/* NOTE: The pci code in this driver is written to the * 2.4.x (or some 2.3.x and newer) pci support. The declarations * inside this #if block are to provide backward compatibility to 2.2.x. * NOTE2: If you want to modify the pci support, please make sure you do * it in a 2.4.x compliant way. */struct pci_driver_mapping { struct pci_dev *dev; struct pci_driver *drv; void *driver_data;};struct pci_device_id{ unsigned int vendor, device; unsigned int subvendor, subdevice; unsigned int class, class_mask; unsigned long driver_data;};struct pci_driver{ struct {int a;} dummy; char *name; const struct pci_device_id *id_table; /* NULL if wants all devices */ int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); void (*remove) (struct pci_dev *dev); int (*save_state) (struct pci_dev *dev, u32 state); int (*suspend)(struct pci_dev *dev, u32 state); int (*resume) (struct pci_dev *dev); int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);};#define PCI_MAX_MAPPINGS 16static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };#define PCI_ANY_ID 0xffffstatic int pci_register_driver(struct pci_driver *drv);static void pci_unregister_driver(struct pci_driver *drv);static int pci_populate_drvmap (struct pci_dev *dev, struct pci_driver *drv);static void *pci_get_drvdata (struct pci_dev *dev);static void pci_set_drvdata (struct pci_dev *dev, void *driver_data);/* no-ops */#define pci_enable_device(a) 0#define pci_disable_device(a) 0#define request_mem_region(x,y,z) (1)#define release_mem_region(x,y) do {} while (0)#ifndef pci_resource_startstatic unsigned long pci_resource_len (struct pci_dev *dev, int n_base){ u32 l, sz; int reg = PCI_BASE_ADDRESS_0 + (n_base << 2); /* XXX temporarily disable I/O and memory decoding for this device? */ pci_read_config_dword (dev, reg, &l); if (l == 0xffffffff) return 0; pci_write_config_dword (dev, reg, ~0); pci_read_config_dword (dev, reg, &sz); pci_write_config_dword (dev, reg, l); if (!sz || sz == 0xffffffff) return 0; if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { sz = ~(sz & PCI_BASE_ADDRESS_MEM_MASK); } else { sz = ~(sz & PCI_BASE_ADDRESS_IO_MASK) & 0xffff; } return sz + 1;}#define pci_resource_start(dev, i) \ (((dev)->base_address[i] & PCI_BASE_ADDRESS_SPACE) ? \ ((dev)->base_address[i] & PCI_BASE_ADDRESS_IO_MASK) : \ ((dev)->base_address[i] & PCI_BASE_ADDRESS_MEM_MASK))#define pci_resource_end(dev,bar) \ (pci_resource_len((dev),(bar)) == 0 ? \ pci_resource_start(dev,bar) : \ (pci_resource_start(dev,bar) + pci_resource_len((dev),(bar)) - 1)#define pci_resource_flags(dev, i) \ (dev->base_address[i] & IORESOURCE_IO)#endif#endif /* (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI) */#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) *//*-----------------------------------------------------------------*/ #if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)#ifdef CONFIG_PMstatic int prism2sta_suspend_pci(struct pci_dev *pdev, u32 state);static int prism2sta_resume_pci(struct pci_dev *pdev);#endif#endif#if (WLAN_HOSTIF == WLAN_PCI)#endif /* WLAN_PCI */static wlandevice_t *create_wlan(void);/*----------------------------------------------------------------*//* --Module Parameters */int prism2_reset_holdtime=30; /* Reset hold time in ms */int prism2_reset_settletime=100; /* Reset settle time in ms */#if (WLAN_HOSTIF == WLAN_USB)static int prism2_doreset=0; /* Do a reset at init? */#elsestatic int prism2_doreset=1; /* Do a reset at init? */int prism2_bap_timeout=1000; /* BAP timeout */int prism2_irq_evread_max=20; /* Maximum number of * ev_reads (loops) * in irq handler */#endif#ifdef WLAN_INCLUDE_DEBUGint prism2_debug=0; /* Debug output level, */MODULE_PARM( prism2_debug, "i");MODULE_PARM_DESC(prism2_debug, "prism2 debugging"); #endifMODULE_PARM( prism2_doreset, "i");MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization?");MODULE_PARM( prism2_reset_holdtime, "i");MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");MODULE_PARM( prism2_reset_settletime, "i");MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");#if (WLAN_HOSTIF != WLAN_USB)MODULE_PARM( prism2_bap_timeout, "i");MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us");MODULE_PARM( prism2_irq_evread_max, "i");MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler");#endif#ifdef MODULE_LICENSEMODULE_LICENSE("Dual MPL/GPL");#endif/*================================================================*//* Local Function Declarations */static int prism2sta_open(wlandevice_t *wlandev);static int prism2sta_close(wlandevice_t *wlandev);static void prism2sta_reset(wlandevice_t *wlandev );static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);static int prism2sta_getcardinfo(wlandevice_t *wlandev);static int prism2sta_globalsetup(wlandevice_t *wlandev);static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);static void prism2sta_inf_handover( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_tallies( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_hostscanresults( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_scanresults( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_chinforesults( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_linkstatus( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_assocstatus( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_authreq( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_authreq_defer( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);static void prism2sta_inf_psusercnt( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);#ifdef CONFIG_PROC_FSstatic intprism2sta_proc_read( char *page, char **start, off_t offset, int count, int *eof, void *data);#endif/*================================================================*//* Function Definitions *//*----------------------------------------------------------------* dmpmem** Debug utility function to dump memory to the kernel debug log.** Arguments:* buf ptr data we want dumped* len length of data** Returns: * nothing* Side effects:** Call context:* process thread* interrupt----------------------------------------------------------------*/inline void dmpmem(void *buf, int n){ int c; for ( c= 0; c < n; c++) { if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c); printk("%02x ", ((UINT8*)buf)[c]); if ( (c % 16) == 15 ) printk("\n"); } if ( (c % 16) != 0 ) printk("\n");}/*-----------------------------------------------------------------*/ #if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))/* NOTE: See the note above about 2.4.x and pci support *//*----------------------------------------------------------------* pci_register_driver* pci_unregister_driver** 2.4.x PCI support function emulation for 2.2.x kernels.** Arguments:* drv 2.4.x type driver description block** Returns: * 0 success* ~0 error** Side effects:** Call context:* process thread----------------------------------------------------------------*/static int pci_register_driver(struct pci_driver *drv){ int nfound = 0; struct pci_dev *pdev; const struct pci_device_id *id_tbl=drv->id_table; DBFENTER; /* Scan the bus for matching devices */ if (pcibios_present()) { static int pci_index = 0; UINT8 pci_bus; UINT8 pci_device_fn; for(;pci_index < 0xff; pci_index++) { u16 vendor; u16 device; int idx; if (pcibios_find_class(PCI_CLASS_NETWORK_OTHER<<8,pci_index, &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL) break; pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor); pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device); for( idx = 0; id_tbl[idx].vendor; idx++) { if ( id_tbl[idx].vendor == vendor && id_tbl[idx].device == device ) break; /* found one! */ } if (id_tbl[idx].vendor == 0) continue; nfound++; /* Probably an invalid assumption...but we'll assume the * card is alive for now. TODO: need to add power management * stuff here. */ /* Collect the pci_device structure */ pdev = pci_find_slot(pci_bus, pci_device_fn); /* Set the driver for this device in the drvmap */ if (pci_populate_drvmap(pdev, drv) == 0) { /* Call the driver probe function */ (*(drv->probe))(pdev, &(id_tbl[idx])); } } } DBFEXIT; return nfound;}static int pci_populate_drvmap (struct pci_dev *dev, struct pci_driver *drv){ int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -